-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
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
[Merged by Bors] - add ReflectAsset
and ReflectHandle
#5923
Conversation
@@ -111,6 +112,8 @@ pub struct StandardMaterial { | |||
pub double_sided: bool, | |||
/// Whether to cull the "front", "back" or neither side of a mesh | |||
/// defaults to `Face::Back` | |||
// TODO: include this in reflection somehow (maybe via remote types like serde https://serde.rs/remote-derive.html) |
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.
Can we use a blanket impl for Option in bevy_reflect? Or do we not own the Face type either :(
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.
Face
is the problem, because it is defined in wgpu-types
, not in bevy.
We can
- add a feature to
bevy_reflect
to implementReflect
forwgpu-types
- add a feature to
wgpu-types
to implementReflect
(if the maintainers agree that this is worth it) - solve this similar to what serde does, and what @MrGVSV experimented with in https://discordapp.com/channels/691052431525675048/1002362493634629796/1016608961224511538
I'm in favor of this! Just some small comments around ergonomics and docs. |
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.
Looking really good! Just some comments/questions/suggestions.
/// and adds [`ReflectAsset`] type data to `T` and [`ReflectHandle`] type data to `Handle<T>` in the type registry. | ||
/// | ||
/// This enables reflection code to access assets. For detailed information, see the docs on [`ReflectAsset`] and [`ReflectHandle`]. | ||
fn register_asset_reflect<T>(&mut self) -> &mut Self |
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 wonder if this should also perform the add_asset
call internally. Then users only need to write one or the other, not both. In that case, I might also recommend bikeshedding this to add_reflectable_asset
or something similar.
Any thoughts on this?
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.
Hm. I think my preference is to have these two methods separately, because then you can search for add_asset
globally and easily find all asset registration. Registering reflect also feels like something that is done "additionally", not like a completely different way of adding an 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.
Ah, true. I guess it also means you can quickly comment out the line if you need to test it without the reflection. Save on those keystrokes haha
I think I lean more towards keeping it as is now, but if anyone else has any thoughts, I'd love to hear it!
One question I just thought of is if we want to represent owned values in these kinds of APIs as |
Big 👍 to this! This is exactly what I was needing for asset management in scripts. |
My instinct is that I should have a To work around not having |
@jakobhellermann I think this PR needs to be rebased |
Co-authored-by: Gino Valente <49806985+MrGVSV@users.noreply.github.com>
99f6daa
to
48eb298
Compare
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.
Great work! Definitely in line with the patterns we've already established. A bit unfortunate that we need to revert to reflect_value
and reflect(ignore)
in some cases, but thats not your fault and the solutions are pretty clear at this point (and we can punt that until later).
bors r+ |
# Objective ![image](https://user-images.githubusercontent.com/22177966/189350194-639a0211-e984-4f73-ae62-0ede44891eb9.png) ^ enable this Concretely, I need to - list all handle ids for an asset type - fetch the asset as `dyn Reflect`, given a `HandleUntyped` - when encountering a `Handle<T>`, find out what asset type that handle refers to (`T`'s type id) and turn the handle into a `HandleUntyped` ## Solution - add `ReflectAsset` type containing function pointers for working with assets ```rust pub struct ReflectAsset { type_uuid: Uuid, assets_resource_type_id: TypeId, // TypeId of the `Assets<T>` resource get: fn(&World, HandleUntyped) -> Option<&dyn Reflect>, get_mut: fn(&mut World, HandleUntyped) -> Option<&mut dyn Reflect>, get_unchecked_mut: unsafe fn(&World, HandleUntyped) -> Option<&mut dyn Reflect>, add: fn(&mut World, &dyn Reflect) -> HandleUntyped, set: fn(&mut World, HandleUntyped, &dyn Reflect) -> HandleUntyped, len: fn(&World) -> usize, ids: for<'w> fn(&'w World) -> Box<dyn Iterator<Item = HandleId> + 'w>, remove: fn(&mut World, HandleUntyped) -> Option<Box<dyn Reflect>>, } ``` - add `ReflectHandle` type relating the handle back to the asset type and providing a way to create a `HandleUntyped` ```rust pub struct ReflectHandle { type_uuid: Uuid, asset_type_id: TypeId, downcast_handle_untyped: fn(&dyn Any) -> Option<HandleUntyped>, } ``` - add the corresponding `FromType` impls - add a function `app.register_asset_reflect` which is supposed to be called after `.add_asset` and registers `ReflectAsset` and `ReflectHandle` in the type registry --- ## Changelog - add `ReflectAsset` and `ReflectHandle` types, which allow code to use reflection to manipulate arbitrary assets without knowing their types at compile time
ReflectAsset
and ReflectHandle
ReflectAsset
and ReflectHandle
# Objective ![image](https://user-images.githubusercontent.com/22177966/189350194-639a0211-e984-4f73-ae62-0ede44891eb9.png) ^ enable this Concretely, I need to - list all handle ids for an asset type - fetch the asset as `dyn Reflect`, given a `HandleUntyped` - when encountering a `Handle<T>`, find out what asset type that handle refers to (`T`'s type id) and turn the handle into a `HandleUntyped` ## Solution - add `ReflectAsset` type containing function pointers for working with assets ```rust pub struct ReflectAsset { type_uuid: Uuid, assets_resource_type_id: TypeId, // TypeId of the `Assets<T>` resource get: fn(&World, HandleUntyped) -> Option<&dyn Reflect>, get_mut: fn(&mut World, HandleUntyped) -> Option<&mut dyn Reflect>, get_unchecked_mut: unsafe fn(&World, HandleUntyped) -> Option<&mut dyn Reflect>, add: fn(&mut World, &dyn Reflect) -> HandleUntyped, set: fn(&mut World, HandleUntyped, &dyn Reflect) -> HandleUntyped, len: fn(&World) -> usize, ids: for<'w> fn(&'w World) -> Box<dyn Iterator<Item = HandleId> + 'w>, remove: fn(&mut World, HandleUntyped) -> Option<Box<dyn Reflect>>, } ``` - add `ReflectHandle` type relating the handle back to the asset type and providing a way to create a `HandleUntyped` ```rust pub struct ReflectHandle { type_uuid: Uuid, asset_type_id: TypeId, downcast_handle_untyped: fn(&dyn Any) -> Option<HandleUntyped>, } ``` - add the corresponding `FromType` impls - add a function `app.register_asset_reflect` which is supposed to be called after `.add_asset` and registers `ReflectAsset` and `ReflectHandle` in the type registry --- ## Changelog - add `ReflectAsset` and `ReflectHandle` types, which allow code to use reflection to manipulate arbitrary assets without knowing their types at compile time
Objective
^ enable this
Concretely, I need to
dyn Reflect
, given aHandleUntyped
Handle<T>
, find out what asset type that handle refers to (T
's type id) and turn the handle into aHandleUntyped
Solution
ReflectAsset
type containing function pointers for working with assetsReflectHandle
type relating the handle back to the asset type and providing a way to create aHandleUntyped
FromType
implsapp.register_asset_reflect
which is supposed to be called after.add_asset
and registersReflectAsset
andReflectHandle
in the type registryChangelog
ReflectAsset
andReflectHandle
types, which allow code to use reflection to manipulate arbitrary assets without knowing their types at compile time