-
-
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
The documentation for ReflectComponent
is inconsistent with how Reflect
is implemented for lists
#7129
Comments
this is not actually blocked on #7061 since we can use |
I’m working on adding diff support to bevy_reflect (currently partially blocked by #6971). Diffing would allow insert/remove operations to be performed on |
This still means we would have no way to fully set a component except remove followed by insert. Is there a compelling reason for |
|
We would need a new And as mentioned earlier it wouldn't work with borrowed data Edit: Sorry, I misread your comment |
|
I have been tripped up by this when using hot reloading of scenes. If a component in the file contains a Vec, only changes that grows the Vec or keeps it at the same length has the expected outcome. My suggestion for a fix would simply be to remove the excess elems from the list like so:
Is there any reason why this wasn't already implemented? |
I've also run into this now. While the current list behavior is consistent with structs/tuples/etc, there is definitely a need for a |
Yeah I hope so. I'm going to try to find time for it this month. Ideally, I could at least get it up in draft PR form for initial thoughts |
Bevy version
v0.9.1
What you did
The documentation for
ReflectComponent
currently reads:/// Uses reflection to set the value of this [`Component`] type in the entity to the given value.
However, internally, the implementation of
apply
for lists:This means
List[1, 2, 3].apply(List[4, 5]) == List[4, 5, 3]
.So the result of calling
ReflectComponent::apply()
on a component with a list in it would not actually result in the components being equal afterwards.In particular, this was causing problems in
bevy_ggrs
, where theChildren
component is being rolled back. We usedReflectComponent::apply
since that sounded like the right thing to do, but sincelist_apply
didn't remove elements ifself.len()
>value.len()
, we were getting leftover children that shouldn't be there.To work around this, we used
ReflectComponent::remove
followed byReflectComponent::insert
. However, by doing this it is causing unnecessary copies of the entire children hierarchy on every snapshot restore, and also needlessly triggeringAdded
queries, causing further performance regressions.What went wrong
I think the least confusing thing for users, would be if
Reflect::apply
for lists actually removed excess elements, soList[1, 2, 3].apply(List[4, 5]) == List[4, 5]
Alternatively, the documentation for
ReflectComponent::apply
should specifically warn about this gotcha, and we need some alternative way of performing in-place updates of components.Additional information
Added
triggering in bevy_ggrsinsert
andremove
methods forList
#7061The text was updated successfully, but these errors were encountered: