From 81a94a868bd8650b468087333c5c3da36d2dceaf Mon Sep 17 00:00:00 2001 From: Nicola Papale Date: Sun, 10 Sep 2023 17:26:02 +0200 Subject: [PATCH] Provide getters for fields of ReflectFromPtr The reasoning is similar to #8687. I'm building a dynamic query. Currently, I store the ReflectFromPtr in my dynamic `Fetch` type. However, `ReflectFromPtr` is: - 16 bytes for TypeId - 8 bytes for the non-mutable function pointer - 8 bytes for the mutable function pointer It's a lot, it adds 32 bytes to my base `Fetch` which is only `ComponendId` (8 bytes) for a total of 40 bytes. I only need one function per fetch, reducing the total dynamic fetch size to 16 bytes. Since I'm querying the components by the ComponendId associated with the function pointer I'm using, I don't need the TypeId, it's a redundant check. In fact, I've difficulties coming up with situations where checking the TypeId beforehand is relevant. So to me, if ReflectFromPtr makes sense as a public API, exposing the function pointers also makes sense. --- crates/bevy_reflect/src/type_registry.rs | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/crates/bevy_reflect/src/type_registry.rs b/crates/bevy_reflect/src/type_registry.rs index aeaba79a2f6d53..57c179aa982f58 100644 --- a/crates/bevy_reflect/src/type_registry.rs +++ b/crates/bevy_reflect/src/type_registry.rs @@ -528,8 +528,8 @@ impl Deserialize<'a> + Reflect> FromType for ReflectDeserialize { #[derive(Clone)] pub struct ReflectFromPtr { type_id: TypeId, - to_reflect: for<'a> unsafe fn(Ptr<'a>) -> &'a dyn Reflect, - to_reflect_mut: for<'a> unsafe fn(PtrMut<'a>) -> &'a mut dyn Reflect, + to_reflect: unsafe fn(Ptr) -> &dyn Reflect, + to_reflect_mut: unsafe fn(PtrMut) -> &mut dyn Reflect, } impl ReflectFromPtr { @@ -553,6 +553,26 @@ impl ReflectFromPtr { pub unsafe fn as_reflect_ptr_mut<'a>(&self, val: PtrMut<'a>) -> &'a mut dyn Reflect { (self.to_reflect_mut)(val) } + /// Get a function pointer to turn a `Ptr` into `&dyn Reflect` for + /// the type this was constructed for. + /// + /// # Safety + /// When calling the unsafe function returned by this method you must ensure that: + /// - The input `Ptr` points to the `Reflect` type this [`ReflectFromPtr`] + /// was constructed for. + pub fn get_to_reflect(&self) -> unsafe fn(Ptr) -> &dyn Reflect { + self.to_reflect + } + /// Get a function pointer to turn a `PtrMut` into `&mut dyn Reflect` for + /// the type this was constructed for. + /// + /// # Safety + /// When calling the unsafe function returned by this method you must ensure that: + /// - The input `PtrMut` points to the `Reflect` type this [`ReflectFromPtr`] + /// was constructed for. + pub fn get_to_reflect_mut(&self) -> unsafe fn(PtrMut) -> &mut dyn Reflect { + self.to_reflect_mut + } } impl FromType for ReflectFromPtr {