Skip to content

Commit

Permalink
Not blocking load_untyped using a wrapper asset
Browse files Browse the repository at this point in the history
  • Loading branch information
NiklasEi committed Oct 22, 2023
1 parent 60773e6 commit f826032
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 4 deletions.
14 changes: 12 additions & 2 deletions crates/bevy_asset/src/assets.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use crate::{Asset, AssetEvent, AssetHandleProvider, AssetId, AssetServer, Handle};
use crate as bevy_asset;
use crate::{Asset, AssetEvent, AssetHandleProvider, AssetId, AssetServer, Handle, UntypedHandle};
use bevy_ecs::{
prelude::EventWriter,
system::{Res, ResMut, Resource},
};
use bevy_reflect::{Reflect, Uuid};
use bevy_reflect::{Reflect, TypePath, Uuid};
use bevy_utils::HashMap;
use crossbeam_channel::{Receiver, Sender};
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -74,6 +75,15 @@ impl AssetIndexAllocator {
}
}

/// A "loaded asset" containing the untyped handle for an asset stored in a given [`AssetPath`].
///
/// [`AssetPath`]: crate::AssetPath
#[derive(Asset, TypePath)]
pub struct LoadedUntypedAsset {
#[dependency]
pub handle: UntypedHandle,
}

// PERF: do we actually need this to be an enum? Can we just use an "invalid" generation instead
#[derive(Default)]
enum Entry<A: Asset> {
Expand Down
1 change: 1 addition & 0 deletions crates/bevy_asset/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ impl Plugin for AssetPlugin {
}
app.insert_resource(embedded)
.init_asset::<LoadedFolder>()
.init_asset::<LoadedUntypedAsset>()
.init_asset::<()>()
.configure_sets(
UpdateAssets,
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_asset/src/processor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -660,7 +660,7 @@ impl AssetProcessor {
source: &AssetSource,
asset_path: &AssetPath<'static>,
) -> Result<ProcessResult, ProcessError> {
// TODO: The extension check was removed now tht AssetPath is the input. is that ok?
// TODO: The extension check was removed now that AssetPath is the input. is that ok?
// TODO: check if already processing to protect against duplicate hot-reload events
debug!("Processing {:?}", asset_path);
let server = &self.server;
Expand Down
31 changes: 30 additions & 1 deletion crates/bevy_asset/src/server/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use crate::{
},
path::AssetPath,
Asset, AssetEvent, AssetHandleProvider, AssetId, Assets, DeserializeMetaError,
ErasedLoadedAsset, Handle, UntypedAssetId, UntypedHandle,
ErasedLoadedAsset, Handle, LoadedUntypedAsset, UntypedAssetId, UntypedHandle,
};
use bevy_ecs::prelude::*;
use bevy_log::{error, info, warn};
Expand Down Expand Up @@ -288,6 +288,35 @@ impl AssetServer {
self.load_internal(None, path, false, None).await
}

#[must_use = "not using the returned strong handle may result in the unexpected release of the assets"]
pub fn load_untyped<'a>(&self, path: impl Into<AssetPath<'a>>) -> Handle<LoadedUntypedAsset> {
let handle = {
let mut infos = self.data.infos.write();
infos.create_loading_handle::<LoadedUntypedAsset>()
};
let id = handle.id().untyped();
let path = path.into().into_owned();

let server = self.clone();
IoTaskPool::get()
.spawn(async move {
match server.load_untyped_async(path).await {
Ok(handle) => server.send_asset_event(InternalAssetEvent::Loaded {
id,
loaded_asset: LoadedAsset::new_with_dependencies(
LoadedUntypedAsset { handle },
None,
)
.into(),
}),
Err(_) => server.send_asset_event(InternalAssetEvent::Failed { id }),
}
})
.detach();

handle
}

/// Performs an async asset load.
///
/// `input_handle` must only be [`Some`] if `should_load` was true when retrieving `input_handle`. This is an optimization to
Expand Down

0 comments on commit f826032

Please sign in to comment.