-
-
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
Add ReflectFromWorld
and replace the FromWorld
requirement on ReflectComponent
and ReflectBundle
with FromReflect
#9623
Add ReflectFromWorld
and replace the FromWorld
requirement on ReflectComponent
and ReflectBundle
with FromReflect
#9623
Conversation
Mhm that didn't happen when I ran Anyway, look like the error occurs because a In the end the error is caused by One way to fix could be to fall back to using |
|
||
use crate::world::{FromWorld, World}; | ||
|
||
/// A struct used to operate on reflected [`FromWorld`] of a type. |
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.
This line isn't clear to me. It feels like we're missing a noun after FromWorld
.
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 blindly copied the documentation for ReflectComponent
and ReflectBundle
. I guess their documentation should also be updated?
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.
Yes please :)
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.
Also FromWorld
already feel kinda a noun, so I'm not so sure what to add after it. Any idea?
I like not requiring |
12b486f
to
a1bed41
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.
I have rebased and fixed the merge conflicts. I'll leave here an auto-review to highlight some changes where some feedback would be welcome.
/// Function pointer implementing [`ReflectComponent::insert()`]. | ||
pub insert: fn(&mut EntityWorldMut, &dyn Reflect), | ||
pub insert: fn(&mut EntityWorldMut, &dyn Reflect, &TypeRegistry), |
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 have added a &TypeRegistry
parameter to ReflectComponent
's functions, mimicking the ones on ReflectBundle
. Now the TypeRegistry
in the World
is no longer implicitly accessed.
// FIXME: once we have unique reflect, use `TypePath`. | ||
std::any::type_name::<T>(), |
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.
Here I kinda copied what it's done in ReflectBundle
. The alternative would be requiring TypePath
in the bounds, but I guess that's probably better done in another PR.
if let Some(reflect_component) = | ||
registry.get_type_data::<ReflectComponent>(TypeId::of::<B>()) | ||
{ | ||
reflect_component.apply(entity, reflected_bundle); | ||
} else { |
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.
While reworking insert_field
I realized it would make sense to check if the Bundle
being inserted is a single Component
, in which case it shouldn't insert each field as if it was itself a bundle/component (which would be wrong). I guess usually ReflectComponent
should be checked before ReflectBundle
, but if someone made a mistake we should catch it. This won't work though if someone only registers ReflectBundle
and not ReflectComponent
. It's also a technically a change in behaviour (though I would argue any case where a change is observable was likely behaving wrongly before).
8438cf3
to
43b8f6e
Compare
Rebased and fixed merge conflicts. |
43b8f6e
to
bd1dc46
Compare
@@ -0,0 +1,84 @@ | |||
//! Definitions for [`FromWorld`] reflection. |
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.
This could use a sentence or two of docs about why this is useful.
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.
Note that this is a private module. I tried to expand the documentation a bit anyway, though I'm not fully convinced. I also expanded a bit the documentation of the bundle
and component
modules to keep the same "structure".
Related: I just noticed that the component
module has some kinda extensive documentation, but unfortunately it is not visible to users due to the module being private.
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 have nits about the documentation, but this change ultimately makes sense to me and seems both correct and necessary.
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 strongly agree with the broad strokes of this change and the implementation is solid too.
i wonder if it would be possible in a followup to automatically register ReflectFromWorld
when we write #[reflect(Default)]
.
It should be possible, though I wonder whether there is a more general way to do this that covers any |
probably not without edit: unless we made this part of the definition of |
…ource` for `State<S>` (#12136) # Objective - In #9623 I forgot to change the `FromWorld` requirement for `ReflectResource`, fix that; - Fix #12129 ## Solution - Use the same approach as in #9623 to try using `FromReflect` and falling back to the `ReflectFromWorld` contained in the `TypeRegistry` provided - Just reflect `Resource` on `State<S>` since now that's possible without introducing new bounds. --- ## Changelog - `ReflectResource`'s `FromType<T>` implementation no longer requires `T: FromWorld`, but instead now requires `FromReflect`. - `ReflectResource::insert`, `ReflectResource::apply_or_insert` and `ReflectResource::copy` now take an extra `&TypeRegistry` parameter. ## Migration Guide - Users of `#[reflect(Resource)]` will need to also implement/derive `FromReflect` (should already be the default). - Users of `#[reflect(Resource)]` may now want to also add `FromWorld` to the list of reflected traits in case their `FromReflect` implementation may fail. - Users of `ReflectResource` will now need to pass a `&TypeRegistry` to its `insert`, `apply_or_insert` and `copy` methods.
Objective
FromType<T>
forReflectComponent
andReflectBundle
currently requireT: FromWorld
for two reasons:from_world
method;T
s usingFromWorld
and thenapply
a&dyn Reflect
to it to simulateFromReflect
.FromWorld
/Default
may be difficult/weird/impractical to implement, whileFromReflect
is easier and also more natural for the job.Solution
from_world
fromReflectComponent
andReflectBundle
into its ownReflectFromWorld
struct.FromWorld
inReflectComponent
andReflectBundle
withFromReflect
Changelog
ReflectComponent
andReflectBundle
no longer offer afrom_world
method.ReflectComponent
andReflectBundle
'sFromType<T>
implementation no longer requiresT: FromWorld
, but now requiresFromReflect
.ReflectComponent::insert
,ReflectComponent::apply_or_insert
andReflectComponent::copy
now take an extra&TypeRegistry
parameter.ReflectFromWorld
struct.Migration Guide
ReflectComponent::from_world
andReflectBundle::from_world
will have to be changed toReflectFromWorld::from_world
.#[reflect(Component)]
and#[reflect(Bundle)]
will need to also implement/deriveFromReflect
.#[reflect(Component)]
and#[reflect(Bundle)]
may now want to also addFromWorld
to the list of reflected traits in case theirFromReflect
implementation may fail.ReflectComponent
will now need to pass a&TypeRegistry
to itsinsert
,apply_or_insert
andcopy
methods.