-
-
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
Fix StrongHandle
TypeId
mismatch when using labels
#10465
Fix StrongHandle
TypeId
mismatch when using labels
#10465
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice, thank you for doing this 🙂
I would prefer a more general API instead of focusing on the last word in the label and expecting it to have a number. Can we have the new methods take the asset path or the complete label? Then the loader can decide how to parse it.
crates/bevy_asset/src/loader.rs
Outdated
@@ -39,6 +39,10 @@ pub trait AssetLoader: Send + Sync + 'static { | |||
|
|||
/// Returns a list of extensions supported by this asset loader, without the preceding dot. | |||
fn extensions(&self) -> &[&str]; | |||
/// Returns the type name of the sub-asset type with the given `label`. | |||
fn label_type_name(&self, label_type: &str) -> Option<&'static str>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the new methods should have default implementations returning name/id of Self::Asset
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That should make this change non breaking.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was on the fence yeah. I kinda wanted to make the implementation of AssetLoader
for the user as easy as possible, and parsing a label is kinda annoying, but yeah in doing that I kinda set in stone what a label should look like and we might not want that, also the code of AssetPath
becomes kinda messy yeah.
I would like to hear another opinion on this.
crates/bevy_asset/src/loader.rs
Outdated
fn asset_type_id(&self) -> TypeId { | ||
TypeId::of::<L::Asset>() | ||
} | ||
|
||
fn asset_type_name(&self) -> &'static str { | ||
std::any::type_name::<L::Asset>() | ||
fn label_type_name(&self, label_type: Option<&str>) -> Option<&'static str> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In my opinion this logic should be part of the loader. We could directly call the methods on the loader here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That puts the responsibility of thinking about "if there is no label it's the root Asset type" on the person who implement AssetLoader
. I think the only reason we might want that is if we want to allow an AssetLoader
to only take paths with labels, but even if we do that it would still load an asset with a handle with a path without a label so it doesn't really make sense I think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In most cases an asset loader should not care about the new functions at all. If the default implementations of the functions return the type name/id of the main asset, only the ones requiring their own implementations need to handle "no label" => "main asset type" and is is fine imo. So far I am only aware of the Gltf loader that would need implementations of the new functions.
crates/bevy_asset/src/path.rs
Outdated
/// This is given as a convenience only when parsing an asset path string, | ||
/// but it is not set when a `label` is set directly. | ||
/// Should not be used for comparison. | ||
pub(crate) label_type: Option<CowArc<'a, str>>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can remove this and leave the path parsing to the loader.
The error about the error type is because the new asset loader error is quite big and included in the Gltf loader error. The new error could just contain the path, which might make it small enough. |
I don't really understand how the error is big, I basically copied |
Maybe we should have the new functions return the type names and IDs without |
Hmm I'll need to think on this a bit as something seems off with this approach. |
# Objective Fixes #10436 Alternative to #10465 ## Solution `load_untyped_async` / `load_internal` currently has a bug. In `load_untyped_async`, we pass None into `load_internal` for the `UntypedHandle` of the labeled asset path. This results in a call to `get_or_create_path_handle_untyped` with `loader.asset_type_id()` This is a new code path that wasn't hit prior to the newly added `load_untyped` because `load_untyped_async` was a private method only used in the context of the `load_folder` impl (which doesn't have labels) The fix required some refactoring to catch that case and defer handle retrieval. I have also made `load_untyped_async` public as it is now "ready for public use" and unlocks new scenarios.
Fixed by #10514, closing this. |
# Objective Fixes #10436 Alternative to #10465 ## Solution `load_untyped_async` / `load_internal` currently has a bug. In `load_untyped_async`, we pass None into `load_internal` for the `UntypedHandle` of the labeled asset path. This results in a call to `get_or_create_path_handle_untyped` with `loader.asset_type_id()` This is a new code path that wasn't hit prior to the newly added `load_untyped` because `load_untyped_async` was a private method only used in the context of the `load_folder` impl (which doesn't have labels) The fix required some refactoring to catch that case and defer handle retrieval. I have also made `load_untyped_async` public as it is now "ready for public use" and unlocks new scenarios.
# Objective Fixes bevyengine#10436 Alternative to bevyengine#10465 ## Solution `load_untyped_async` / `load_internal` currently has a bug. In `load_untyped_async`, we pass None into `load_internal` for the `UntypedHandle` of the labeled asset path. This results in a call to `get_or_create_path_handle_untyped` with `loader.asset_type_id()` This is a new code path that wasn't hit prior to the newly added `load_untyped` because `load_untyped_async` was a private method only used in the context of the `load_folder` impl (which doesn't have labels) The fix required some refactoring to catch that case and defer handle retrieval. I have also made `load_untyped_async` public as it is now "ready for public use" and unlocks new scenarios.
Objective
Fix #10436
Note
Solution
label_type_name
andlabel_type_id
methods on theAssetLoader
trait#
and/
characters and before digits, for example forcup.glb#Mesh0/Primitive0
it would bePrimitive
, that's what will be passed to the methods aboveTypeId
to the underlyingStrongHandle
when usingload
orload_untyped
See the conversation here for more information: https://discord.com/channels/691052431525675048/1062754025218510918/1171562681736642622
Migration Guide
If you have a type that implements
AssetLoader
, and thatAssetLoader
should support label, you should implement two methods,label_type_name
andlabel_type_id
. They take alabel
string that you can parse to return the correspondingTypeId
/TypeName
, orNone
if it's an invalid label.