-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support multiple different AssetLoaders with the same extension #367
Comments
skairunner
changed the title
Supporting multiple different AssetLoaders with the same extension
Support multiple different AssetLoaders with the same extension
Aug 27, 2020
karroffel
added
A-Assets
Load files from disk to use for things like images, models, and sounds
C-Feature
A new feature, making something new possible
labels
Aug 27, 2020
What about allowing multiple loaders, where additional loaders for the extension could use impl AssetLoader for FontLoader {
fn load<'a>(
&'a self,
bytes: &'a [u8],
load_context: &'a mut LoadContext,
) -> BoxedFuture<'a, Result<()>> {
Box::pin(async move {
load_context.set_labeled_asset("mesh", LoadedAsset::new(...));
Ok(())
})
}
fn extensions(&self) -> &[&str] {
&["ttf"]
}
} Although, then the user needs to know the label when loading let asset = asset_server.load("fonts/FiraMono-Medium.ttf#mesh"); |
github-merge-queue bot
pushed a commit
that referenced
this issue
Jan 31, 2024
# Objective - Addresses **Support processing and loading files without extensions** from #9714 - Addresses **More runtime loading configuration** from #9714 - Fixes #367 - Fixes #10703 ## Solution `AssetServer::load::<A>` and `AssetServer::load_with_settings::<A>` can now use the `Asset` type parameter `A` to select a registered `AssetLoader` without inspecting the provided `AssetPath`. This change cascades onto `LoadContext::load` and `LoadContext::load_with_settings`. This allows the loading of assets which have incorrect or ambiguous file extensions. ```rust // Allow the type to be inferred by context let handle = asset_server.load("data/asset_no_extension"); // Hint the type through the handle let handle: Handle<CustomAsset> = asset_server.load("data/asset_no_extension"); // Explicit through turbofish let handle = asset_server.load::<CustomAsset>("data/asset_no_extension"); ``` Since a single `AssetPath` no longer maps 1:1 with an `Asset`, I've also modified how assets are loaded to permit multiple asset types to be loaded from a single path. This allows for two different `AssetLoaders` (which return different types of assets) to both load a single path (if requested). ```rust // Uses GltfLoader let model = asset_server.load::<Gltf>("cube.gltf"); // Hypothetical Blob loader for data transmission (for example) let blob = asset_server.load::<Blob>("cube.gltf"); ``` As these changes are reflected in the `LoadContext` as well as the `AssetServer`, custom `AssetLoaders` can also take advantage of this behaviour to create more complex assets. --- ## Change Log - Updated `custom_asset` example to demonstrate extension-less assets. - Added `AssetServer::get_handles_untyped` and Added `AssetServer::get_path_ids` ## Notes As a part of that refactor, I chose to store `AssetLoader`s (within `AssetLoaders`) using a `HashMap<TypeId, ...>` instead of a `Vec<...>`. My reasoning for this was I needed to add a relationship between `Asset` `TypeId`s and the `AssetLoader`, so instead of having a `Vec` and a `HashMap`, I combined the two, removing the `usize` index from the adjacent maps. --------- Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
tjamaan
pushed a commit
to tjamaan/bevy
that referenced
this issue
Feb 6, 2024
# Objective - Addresses **Support processing and loading files without extensions** from bevyengine#9714 - Addresses **More runtime loading configuration** from bevyengine#9714 - Fixes bevyengine#367 - Fixes bevyengine#10703 ## Solution `AssetServer::load::<A>` and `AssetServer::load_with_settings::<A>` can now use the `Asset` type parameter `A` to select a registered `AssetLoader` without inspecting the provided `AssetPath`. This change cascades onto `LoadContext::load` and `LoadContext::load_with_settings`. This allows the loading of assets which have incorrect or ambiguous file extensions. ```rust // Allow the type to be inferred by context let handle = asset_server.load("data/asset_no_extension"); // Hint the type through the handle let handle: Handle<CustomAsset> = asset_server.load("data/asset_no_extension"); // Explicit through turbofish let handle = asset_server.load::<CustomAsset>("data/asset_no_extension"); ``` Since a single `AssetPath` no longer maps 1:1 with an `Asset`, I've also modified how assets are loaded to permit multiple asset types to be loaded from a single path. This allows for two different `AssetLoaders` (which return different types of assets) to both load a single path (if requested). ```rust // Uses GltfLoader let model = asset_server.load::<Gltf>("cube.gltf"); // Hypothetical Blob loader for data transmission (for example) let blob = asset_server.load::<Blob>("cube.gltf"); ``` As these changes are reflected in the `LoadContext` as well as the `AssetServer`, custom `AssetLoaders` can also take advantage of this behaviour to create more complex assets. --- ## Change Log - Updated `custom_asset` example to demonstrate extension-less assets. - Added `AssetServer::get_handles_untyped` and Added `AssetServer::get_path_ids` ## Notes As a part of that refactor, I chose to store `AssetLoader`s (within `AssetLoaders`) using a `HashMap<TypeId, ...>` instead of a `Vec<...>`. My reasoning for this was I needed to add a relationship between `Asset` `TypeId`s and the `AssetLoader`, so instead of having a `Vec` and a `HashMap`, I combined the two, removing the `usize` index from the adjacent maps. --------- Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Currently, the AssetServer stores its references to handlers as a dictionary of string to box. But the file extension to asset type relationship is not one-to-one -- with GLTF, the file can contain anything from Meshes and Materials to Textures to Skins (aka bones).
In a language with reflection, it would be possible to select handlers depending on the type. While Rust doesn't have true reflection, it does have TypeId which would allow us to match on both AssetLoader type and file extension. This might be a good solution that would also let us preserve the existing API. This could also solve the TODO in the asset server file that mentions that load() needs to be strongly typed.
Another solution that is slightly less ergonomic is to create a
load_a
method that takes a String specifying the type of the asset we want to load as well as the path.If we can determine a good path to take, I may be able to implement it, since I am working on something that directly requires this support. (No extra credit for guessing that it's GLTF :D )
The text was updated successfully, but these errors were encountered: