From a66bdd074f04908cb8757ae10670a7205dfb974a Mon Sep 17 00:00:00 2001 From: robtfm <50659922+robtfm@users.noreply.github.com> Date: Sun, 17 Mar 2024 21:37:34 +0000 Subject: [PATCH] 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.~~ --- crates/bevy_asset/src/assets.rs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/crates/bevy_asset/src/assets.rs b/crates/bevy_asset/src/assets.rs index 0a4fe716fb61c..83b45fbda7a74 100644 --- a/crates/bevy_asset/src/assets.rs +++ b/crates/bevy_asset/src/assets.rs @@ -503,10 +503,8 @@ impl Assets { 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 }); - if drop_event.asset_server_managed { - let untyped_id = drop_event.id.untyped(TypeId::of::()); + let untyped_id = id.untyped(); if let Some(info) = infos.get(untyped_id) { if info.load_state == LoadState::Loading || info.load_state == LoadState::NotLoaded @@ -515,12 +513,16 @@ impl Assets { 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