Skip to content

Commit 7a4b80b

Browse files
andriyDevtigregalis
authored andcommitted
Send the entire loaded asset instead of decomposing it on the loader task. (bevyengine#21204)
# Objective - The previous state had the loader task send a single `InternalAssetEvent::Loaded` for every root asset **and** each of its subassets. The `handle_internal_asset_events` system reads these events one at a time. This means these two threads are racing. So it's possible to see some of the subassets loaded without the root asset being loaded in a frame, and then have to wait an additional frame to see the remaining subassets and root asset loaded. ## Solution - Instead of recursively sending the subassets inside the loader task, just send the `LoadedAsset` in its entirety. - Do the recursion when processing the loaded asset. Since we're doing this in the system, the entire loaded asset will be processed in a single frame. - This also reduces contention of the channel. ## Testing - None. This is kinda a "fake issue". In order to see it, handling a loaded asset in `handle_internal_asset_events` needs to finish the last received subasset before the loader task sends the root asset. This is probably pretty unlikely, but could in theory cause flaky tests.
1 parent 0047327 commit 7a4b80b

File tree

2 files changed

+10
-11
lines changed

2 files changed

+10
-11
lines changed

crates/bevy_asset/src/server/info.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,12 @@ impl AssetInfos {
384384
world: &mut World,
385385
sender: &Sender<InternalAssetEvent>,
386386
) {
387+
// Process all the labeled assets first so that they don't get skipped due to the "parent"
388+
// not having its handle alive.
389+
for (_, asset) in loaded_asset.labeled_assets {
390+
self.process_asset_load(asset.handle.id(), asset.asset, world, sender);
391+
}
392+
387393
// Check whether the handle has been dropped since the asset was loaded.
388394
if !self.infos.contains_key(&loaded_asset_id) {
389395
return;

crates/bevy_asset/src/server/mod.rs

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -830,7 +830,10 @@ impl AssetServer {
830830
fetched_handle
831831
};
832832

833-
self.send_loaded_asset(base_asset_id, loaded_asset);
833+
self.send_asset_event(InternalAssetEvent::Loaded {
834+
id: base_asset_id,
835+
loaded_asset,
836+
});
834837
Ok(final_handle)
835838
}
836839
Err(err) => {
@@ -844,16 +847,6 @@ impl AssetServer {
844847
}
845848
}
846849

847-
/// Sends a load event for the given `loaded_asset` and does the same recursively for all
848-
/// labeled assets.
849-
fn send_loaded_asset(&self, id: UntypedAssetId, mut loaded_asset: ErasedLoadedAsset) {
850-
for (_, labeled_asset) in loaded_asset.labeled_assets.drain() {
851-
self.send_loaded_asset(labeled_asset.handle.id(), labeled_asset.asset);
852-
}
853-
854-
self.send_asset_event(InternalAssetEvent::Loaded { id, loaded_asset });
855-
}
856-
857850
/// Kicks off a reload of the asset stored at the given path. This will only reload the asset if it currently loaded.
858851
pub fn reload<'a>(&self, path: impl Into<AssetPath<'a>>) {
859852
self.reload_internal(path, false);

0 commit comments

Comments
 (0)