send Unused event when asset is actually unused (#12459)
# 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.~~
This commit is contained in:
		
							parent
							
								
									4a4d73ef55
								
							
						
					
					
						commit
						36cfb2170f
					
				| @ -549,24 +549,25 @@ 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 }); |  | ||||||
| 
 |  | ||||||
|             let mut remove_asset = true; |  | ||||||
| 
 |  | ||||||
|             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 let LoadState::Loading | LoadState::NotLoaded = info.load_state { |                     if let LoadState::Loading | LoadState::NotLoaded = info.load_state { | ||||||
|                         not_ready.push(drop_event); |                         not_ready.push(drop_event); | ||||||
|                         continue; |                         continue; | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|                 remove_asset = infos.process_handle_drop(untyped_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; | ||||||
|                 } |                 } | ||||||
|             if remove_asset { |             } | ||||||
|  | 
 | ||||||
|  |             assets.queued_events.push(AssetEvent::Unused { id }); | ||||||
|             assets.remove_dropped(id); |             assets.remove_dropped(id); | ||||||
|         } |         } | ||||||
|         } |  | ||||||
| 
 | 
 | ||||||
|         // TODO: this is _extremely_ inefficient find a better fix
 |         // TODO: this is _extremely_ inefficient find a better fix
 | ||||||
|         // This will also loop failed assets indefinitely. Is that ok?
 |         // This will also loop failed assets indefinitely. Is that ok?
 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 robtfm
						robtfm