Mark render assets as modified when removed from the asset server (#18814)

# Objective

Fixes #18808

## Solution

When an asset emits a removed event, mark it as modified in the render
world to ensure any appropriate bookkeeping runs as necessary.
This commit is contained in:
charlotte 2025-04-11 16:18:26 -07:00 committed by GitHub
parent e9a0ef49f9
commit a9b0b4e7f7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -246,10 +246,6 @@ pub(crate) fn extract_render_asset<A: RenderAsset>(
let mut modified = <HashSet<_>>::default();
for event in events.read() {
#[expect(
clippy::match_same_arms,
reason = "LoadedWithDependencies is marked as a TODO, so it's likely this will no longer lint soon."
)]
match event {
AssetEvent::Added { id } => {
needs_extracting.insert(*id);
@ -258,9 +254,20 @@ pub(crate) fn extract_render_asset<A: RenderAsset>(
needs_extracting.insert(*id);
modified.insert(*id);
}
AssetEvent::Removed { .. } => {
// We don't care that the asset was removed from Assets<T> in the main world.
// An asset is only removed from RenderAssets<T> when its last handle is dropped (AssetEvent::Unused).
AssetEvent::Removed { id, .. } => {
// Normally, we consider an asset removed from the render world only
// when it's final handle is dropped triggering an `AssetEvent::Unused`
// event. However, removal without unused can happen when the asset
// is explicitly removed from the asset server and re-added by the user.
// We mark the asset as modified in this case to ensure that
// any necessary render world bookkeeping still runs.
// TODO: consider removing this check and just emitting Unused after
// Removed to ensure that the asset is always "really" removed from the
// render world when the last strong handle is dropped.
if !removed.contains(id) {
modified.insert(*id);
}
}
AssetEvent::Unused { id } => {
needs_extracting.remove(id);