add `ReflectAsset` and `ReflectHandle`
Objective

^ enable this
Concretely, I need to
- list all handle ids for an asset type
- fetch the asset as
dyn Reflect, given aHandleUntyped - when encountering a
Handle<T>, find out what asset type that handle refers to (T's type id) and turn the handle into aHandleUntyped
Solution
- add
ReflectAssettype containing function pointers for working with assets
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
ReflectHandletype relating the handle back to the asset type and providing a way to create aHandleUntyped
pub struct ReflectHandle {
type_uuid: Uuid,
asset_type_id: TypeId,
downcast_handle_untyped: fn(&dyn Any) -> Option<HandleUntyped>,
}
- add the corresponding
FromTypeimpls - add a function
app.register_asset_reflectwhich is supposed to be called after.add_assetand registersReflectAssetandReflectHandlein the type registry
Changelog
- add
ReflectAssetandReflectHandletypes, which allow code to use reflection to manipulate arbitrary assets without knowing their types at compile time
I'm in favor of this! Just some small comments around ergonomics and docs.
One question I just thought of is if we want to represent owned values in these kinds of APIs as &Reflect with the expectation that we will just call FromReflect on it, or as Box<dyn Reflect> which we assume to be containing exactly the wanted type.
If the later, we probably need ReflectFromReflect for people who want to use FromReflect dynamically (part of https://github.com/bevyengine/bevy/pull/6056).
Big :+1: to this! This is exactly what I was needing for asset management in scripts.
One question I just thought of is if we want to represent owned values in these kinds of APIs as &Reflect with the expectation that we will just call FromReflect on it, or as Box<dyn Reflect> which we assume to be containing exactly the wanted type.
My instinct is that I should have a Box<dyn Reflect> for owned values, and ReflectFromReflect was another thing I ran into the need for earlier.
To work around not having ReflectFromReflect I ended up trying to combine ReflectDefault to create the value and Reflect.apply() to patch the value.
@jakobhellermann I think this PR needs to be rebased
bors r+
Pull request successfully merged into main.
Build succeeded:
- build-and-install-on-iOS
- build-android
- build (macos-latest)
- build (ubuntu-latest)
- build-wasm
- build (windows-latest)
- build-without-default-features (bevy)
- build-without-default-features (bevy_ecs)
- build-without-default-features (bevy_reflect)
- check-compiles
- check-doc
- check-missing-examples-in-docs
- ci
- markdownlint
- run-examples
- run-examples-on-wasm
- run-examples-on-windows-dx12