-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Add DeferredMut, and supporting methods on WorldQuery to apply deferred mutations
#19602
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
base: main
Are you sure you want to change the base?
Conversation
copied directly from `SystemParam` lol
|
The |
|
Hmm, why not have these functions on just |
Mostly it just seemed nicer to put methods taking |
|
derive macros should be fixed |
alice-i-cecile
left a comment
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.
Hmm. I think we should make a call on the use of this for deferred mutations for the immutable components pattern now, and probably merge that as one PR. This is currently very simple, which means I'm comfortable adding the first use case in one PR.
|
sounds good, will try in the morning :) |
|
It looks like your PR has been selected for a highlight in the next release blog post, but you didn't provide a release note. Please review the instructions for writing release notes, then expand or revise the content in the release notes directory to showcase your changes. |
|
turns out this is super cursed actually, I ran into a bunch of roadblocks trying to get any kind of state from |
|
Well, it works ™️ now, but it feels extremely jank to clone an Is this dead in the water/how should this proceed? |
chescock
left a comment
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.
Oh, wow, I was worried this would be complex, but it's very readable!
The IS_DENSE thing is unsound and should be fixed before merging, and you probably want to delegate the new methods for Option so that Option<DeferredMut<T>> doesn't compile but ignore all changes, but none of the rest of my comments should be blocking.
Co-authored-by: Chris Russell <8494645+chescock@users.noreply.github.com>
|
Needs a release note still :) |
WorldQuery to apply deferred mutationsDeferredMut, adn supporting methods on WorldQuery to apply deferred mutations
|
Oh, I just thought of a missing piece: We need to call |
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.
As a bevy user I love this, I also wanted to have something like this in an Entry-like query data.
But I am not so happy with the Parallel approach, the possibly surprising limitations such as "you won't see the new value on the second iteration" or "will not work with manual QueryState".
It really shows queries are not built to support this and this implementation here only works roughly. But I leave it to others to decide if that is okay. Personally I think a proper way to do this comes with a larger refactoring.
What this PR is missing is tests which is why I did not yet approve it here.
In hindsight, me neither lol. Since But I guess we could just make it not readonly?? Seems like storing a bunch of The one downside there is we'd need to also add a read-only version, which should be |
Wouldn't that require a separate cell for each entity? At that point, you might as well store it in the ECS like But I think an approach like that requires always iterating every entity in order to apply the updates. The current approach keeps a dense list of updated entities, which is going to perform better when updates are rare. I don't see how to do better than |
DeferredMut, adn supporting methods on WorldQuery to apply deferred mutationsDeferredMut, and supporting methods on WorldQuery to apply deferred mutations
alice-i-cecile
left a comment
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 like this, and the implementation looks solid. Before we merge this though, it needs:
a) to update the example where we demonstrate the immutable components pattern
b) needs a robust set of tests, including one where we validate that automatic sync points are inferred correctly
Removing from the 0.17 milestone as this is not a release blocker and is not currently ready to merge.
See discord convo: https://discord.com/channels/691052431525675048/749335865876021248/1373035857522725079
Added
applyandqueuemethods toWorldQueryto mirrorSystemParam, and piped the calls throughQueryas needed.While manually passing
&mut Commandsaround is probably sufficient for most cases, sometimes customQueryDataimplementations would benefit from being able to directly wrap (and queue/apply) some form of deferred state. A hypothetical example would be anEntry<T>QueryData, but anything that needs to update external state while accessing component data would fit the bill.I'm not sure if this is controversial or not. Maybe it'd be good to enforce a strong separation between directly accessing components through queries and applying deferred mutations with commands, but IMO this opens the door to some pretty nice ergonomics.
Possible Followups:
fetch.rsinto a bunch of smaller modules to make thecfg::parallelguard cleanerStorageSwitchbut for component mutability, and only do the clone/deferred mutations whenTis actually immutable?QueryStateto allow users to manually flush state. Currently usingDeferredMutoutside of a system is a footgun.