Skip to content
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

Provide getters for fields of ReflectFromPtr #9748

Merged
merged 3 commits into from
Sep 18, 2023

Conversation

nicopap
Copy link
Contributor

@nicopap nicopap commented Sep 10, 2023

Objective

The reasoning is similar to #8687.

I'm building a dynamic query. Currently, I store the ReflectFromPtr in my dynamic Fetch type.

See relevant code

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.

Solution

  • Make the fields public through methods.

Changelog

  • Add from_ptr and from_ptr_mut methods to ReflectFromPtr to access the underlying function pointers
  • ReflectFromPtr::as_reflect_ptr is now ReflectFromPtr::as_reflect
  • ReflectFromPtr::as_reflect_ptr_mut is now ReflectFromPtr::as_reflect_mut

Migration guide

  • ReflectFromPtr::as_reflect_ptr is now ReflectFromPtr::as_reflect
  • ReflectFromPtr::as_reflect_ptr_mut is now ReflectFromPtr::as_reflect_mut

@alice-i-cecile alice-i-cecile added C-Usability A simple quality-of-life change that makes Bevy easier to use A-Reflection Runtime information about types labels Sep 10, 2023
Copy link
Member

@alice-i-cecile alice-i-cecile left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this reasoning makes sense. get_to_reflect is pretty awful as a name, but I don't have any really strong alternatives. get_reflect_conversion and get_reflect_mut_conversion maybe?

I'd really like to either see those safety comments duplicated on the fields themselves, or #[inline] annotations + using these methods internally.

@nicopap
Copy link
Contributor Author

nicopap commented Sep 10, 2023

I agree the name is pretty poor.

I think the field should be renamed to from_ptr[_mut] (which matches the struct name) and the method follow the rust convention of re-using the field name. What do you think? It might be awkward to have a from_ptr method that returns something instead of accepting a Ptr though.

@alice-i-cecile
Copy link
Member

I think I'm happy enough with that rename :) @MrGVSV may have other opinions, but we can paint that bike shed when we get to it.

The reasoning is similar to bevyengine#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.
@nicopap nicopap added the C-Breaking-Change A breaking change to Bevy's public API that needs to be noted in a migration guide label Sep 12, 2023
@github-actions
Copy link
Contributor

It looks like your PR is a breaking change, but you didn't provide a migration guide.

Could you add some context on what users should update when this change get released in a new version of Bevy?
It will be used to help writing the migration guide for the version. Putting it after a ## Migration Guide will help it get automatically picked up by our tooling.

Copy link
Member

@MrGVSV MrGVSV left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree from_ptr[_mut] isn't the best but I think it's pretty good. Especially for an API that's more catered to advanced usages anyways.

@alice-i-cecile alice-i-cecile added the S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it label Sep 12, 2023
auto-merge was automatically disabled September 18, 2023 06:19

Head branch was pushed to by a user without write access

@nicopap
Copy link
Contributor Author

nicopap commented Sep 18, 2023

@alice-i-cecile I forgot to update some doc examples and CI didn't pass. It should be fixed now.

@alice-i-cecile alice-i-cecile added this pull request to the merge queue Sep 18, 2023
Merged via the queue into bevyengine:main with commit 0bd4ea7 Sep 18, 2023
21 checks passed
unsafe { ptr.deref::<T>() as &dyn Reflect }
},
from_ptr_mut: |ptr| {
// SAFE: only called from `as_reflect_mut`, where the `ptr` is guaranteed to be of type `T`,
// and `as_reflect_ptr_mut`, where the caller promises to call it with type `T`
// SAFETY: same as above, but foor `as_reflect_mut`, `from_ptr_mut` and `deref_mut`.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh noes foor, that's what I get for hurried changes.

@nicopap nicopap deleted the public_to_reflect branch September 18, 2023 15:58
rdrpenguin04 pushed a commit to rdrpenguin04/bevy that referenced this pull request Jan 9, 2024
# Objective

The reasoning is similar to bevyengine#8687.

I'm building a dynamic query. Currently, I store the ReflectFromPtr in
my dynamic `Fetch` type.

[See relevant
code](https://github.com/nicopap/bevy_mod_dynamic_query/blob/97ba68ae1e13f15cabfac1dcd58c2483396dfd3f/src/fetches.rs#L14-L17)

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.

## Solution

- Make the fields public through methods.

---

## Changelog

- Add `from_ptr` and `from_ptr_mut` methods to `ReflectFromPtr` to
access the underlying function pointers
- `ReflectFromPtr::as_reflect_ptr` is now `ReflectFromPtr::as_reflect`
- `ReflectFromPtr::as_reflect_ptr_mut` is now
`ReflectFromPtr::as_reflect_mut`

## Migration guide

- `ReflectFromPtr::as_reflect_ptr` is now `ReflectFromPtr::as_reflect`
- `ReflectFromPtr::as_reflect_ptr_mut` is now
`ReflectFromPtr::as_reflect_mut`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Reflection Runtime information about types C-Breaking-Change A breaking change to Bevy's public API that needs to be noted in a migration guide C-Usability A simple quality-of-life change that makes Bevy easier to use S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants