-
Hi, I build Asset from code and add them using Assets.add(). However, I would like to search for possible duplicate and get a handle to the duplicate, if it exists, before doing the add. let new_asset = MyAssetType {
data: 1,
};
// TODO: Do not call following code if asset is a duplicate of an existing one
// set the handle to the pre-existing asset
let asset_handle = my_assets.add(new_asset); I spent a lot of time reading the doc and trying some code. I can find duplicates with: my_asserts.iter().find(|(id, a)| **a == new_asset) But I do not manage to get a strong handle to the existing asset. Am I doing something wrong? Is there way to do what I want? |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 3 replies
-
After experimenting and looking more in the doc, I found something that works. After searching the assets to find an equality and get the ID of the matching asset, I can use AssetServer::get_id_handle to get a strong handle to the corresponding asset. |
Beta Was this translation helpful? Give feedback.
-
No luck. I tried to use what I found but it crashes when unwrapping the Option returned by AssetServer::get_id_handle(). I can avoid the crash by adding the asset to the AssetServer instead of to the Assets but, in this case, the lookup for already existing assets does not work until the next frame. pub fn get_existing_or_add_asset<A, P>(
asset: A,
assets: &mut Assets<A>,
asset_server: &AssetServer,
predicate: P,
) -> Handle<A>
where
A: Asset,
P: Fn(&A, &A) -> bool,
{
let existing_asset = assets.iter().find(|(_id, a)| predicate(*a, &asset));
let handle = match existing_asset {
Some((id, _a)) => {
println!("Asset found");
// FIXME: Crash into unwrap
asset_server.get_id_handle(id).unwrap()
}
None => {
assets.add(asset)
// asset_server.add(asset)
}
};
assert!(handle.is_strong());
handle
} I suppose the only solution (I think of) is to use another Resource (of type HashMap::<AssetID, Handle>) that maps the AssetId to a weak Handle. And if the weak Handle points to a Asset that is still alive return a Strong clone of this handle, if the Asset is not still alive than adding it to the Assets and returning the resulting Handle (and storing a weak clone into the map). Any help is welcome. I do not know if the solution I think about would work and I think there must be a way (unknown to me) to get an Handle from an AssetId that do not involve the AssetServer (just the Assets) but I cannot find any (after spending days looking in the doc and the code). Thanks for the engine anyways, still a great library even if some basic things like this makes it a bit hard for a newcomer to rust and this engine. |
Beta Was this translation helpful? Give feedback.
Just a tip, in the rust doc, you can search for "function that accept type
X
and return typeY
" with the->
. As follow: https://docs.rs/bevy/latest/bevy/asset/enum.AssetId.html?search=AssetId%20-%3E%20Handle%3CA%3E.I did investigate the
get_id_handle
implementation and it looks like a bug to me. I'll open an issue.