send Unused event when asset is actually unused (#12459)

fix #12344

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.~~
This commit is contained in:
robtfm 2024-03-17 21:37:34 +00:00 committed by François
parent d2e794f112
commit a66bdd074f
No known key found for this signature in database

View file

@ -503,10 +503,8 @@ impl<A: Asset> Assets<A> {
while let Ok(drop_event) = assets.handle_provider.drop_receiver.try_recv() { while let Ok(drop_event) = assets.handle_provider.drop_receiver.try_recv() {
let id = drop_event.id.typed(); let id = drop_event.id.typed();
assets.queued_events.push(AssetEvent::Unused { id });
if drop_event.asset_server_managed { 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 Some(info) = infos.get(untyped_id) {
if info.load_state == LoadState::Loading if info.load_state == LoadState::Loading
|| info.load_state == LoadState::NotLoaded || info.load_state == LoadState::NotLoaded
@ -515,12 +513,16 @@ impl<A: Asset> Assets<A> {
continue; continue;
} }
} }
if infos.process_handle_drop(untyped_id) {
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;
} }
} else {
assets.remove_dropped(id);
} }
assets.queued_events.push(AssetEvent::Unused { id });
assets.remove_dropped(id);
} }
// TODO: this is _extremely_ inefficient find a better fix // TODO: this is _extremely_ inefficient find a better fix