Skip to content

Commit

Permalink
send Unused event when asset is actually unused (#12459)
Browse files Browse the repository at this point in the history
# Objective

fix #12344

## Solution

use existing machinery in track_assets to determine if the asset is
unused before firing Asset::Unused event

~~most extract functions use `AssetEvent::Removed` to schedule deletion
of render world resources. `RenderAssetPlugin` was using
`AssetEvent::Unused` instead.
`Unused` fires when the last strong handle is dropped, even if a new one
is created. `Removed` only fires when a new one is not created.
as far as i can see, `Unused` is the same as `Removed` except for this
"feature", and that it also fires early if all handles for a loading
asset are dropped (`Removed` fires after the loading completes). note
that in that case, processing based on `Loaded` won't have been done
anyway.
i think we should get rid of `Unused` completely, it is not currently
used anywhere (except here, previously) and i think using it is probably
always a mistake.
i also am not sure why we keep loading assets that have been dropped
while loading, we should probably drop the loader task as well and
remove immediately.~~
  • Loading branch information
robtfm authored Mar 17, 2024
1 parent 4a4d73e commit 36cfb21
Showing 1 changed file with 10 additions and 9 deletions.
19 changes: 10 additions & 9 deletions crates/bevy_asset/src/assets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -549,23 +549,24 @@ impl<A: Asset> Assets<A> {
while let Ok(drop_event) = assets.handle_provider.drop_receiver.try_recv() {
let id = drop_event.id.typed();

assets.queued_events.push(AssetEvent::Unused { id });

let mut remove_asset = true;

if drop_event.asset_server_managed {
let untyped_id = drop_event.id.untyped(TypeId::of::<A>());
let untyped_id = id.untyped();
if let Some(info) = infos.get(untyped_id) {
if let LoadState::Loading | LoadState::NotLoaded = info.load_state {
not_ready.push(drop_event);
continue;
}
}
remove_asset = infos.process_handle_drop(untyped_id);
}
if remove_asset {
assets.remove_dropped(id);

// the process_handle_drop call checks whether new handles have been created since the drop event was fired, before removing the asset
if !infos.process_handle_drop(untyped_id) {
// a new handle has been created, or the asset doesn't exist
continue;
}
}

assets.queued_events.push(AssetEvent::Unused { id });
assets.remove_dropped(id);
}

// TODO: this is _extremely_ inefficient find a better fix
Expand Down

0 comments on commit 36cfb21

Please sign in to comment.