[Merged by Bors] - Redo State architecture#1424
[Merged by Bors] - Redo State architecture#1424TheRawMeatball wants to merge 26 commits intobevyengine:mainfrom
Conversation
091f5a8 to
a9d4f55
Compare
|
Suggested changes from Discord earlier: Speaking of I'm not sure I like the admittedly clever hack with |
|
Hmm, I agree with most of your points but I'd argue keeping state_cleaner a hidden implementation detail is the better choice: I feel like adding a state should automatically add all necessary parts, including the driver. As an improvement I might make soon, this impl can probably be improved by automatically adding in relations between the driver system and all systems in the driven sets to remove the need for the hard sync point. If the state driver was to be manual, this burden would be on the user, and I don't think thats very elegant. |
|
I am insinuating that this approach relies on its own abstraction, rather than integrating well with existing ones. How will this interoperate with plain system sets (i.e. what if something uses the provided run criteria without going through That said, the improvement you're planning will, in my opinion, make this a very good direct replacement to As for epithets, "elegant" is when things work out beautifully and with perfect clarity; this idea strikes me as "sneaky" at best - which doesn't mean it's bad. |
|
Alright, I cleaned up the API and made it more aligned with the rest of the ECS. I'll update the example when #1428 is merged. |
|
Ok, the PR is ready except for the examples, which I'll fix after #1453 |
|
|
||
| /// Creates a driver set for the State. | ||
| /// | ||
| /// Important note: this set must be inserted **before** all other state-dependant sets to work properly! |
There was a problem hiding this comment.
This is unfortunate, but I don't think this can be avoided until #1375 or some stop-gap measure that lets us order run criteria evaluation.
Co-authored-by: bjorn3 <bjorn3@users.noreply.github.com>
alice-i-cecile
left a comment
There was a problem hiding this comment.
This seems like a very solid improvement to StateStages: the way it's decoupled makes much more sense and the general API seems sensible. Are there any good patterns for working with compound states with this API? If so, they likely deserve their own example.
| }) | ||
| pub fn add_state<T: Component + Clone + Eq>(&mut self, initial: T) -> &mut Self { | ||
| self.insert_resource(State::new(initial)) | ||
| .add_system_set(State::<T>::make_driver()) |
There was a problem hiding this comment.
Is it possible to add these system sets (and hence states) to stages other than Update?
There was a problem hiding this comment.
add_state_to_stage is the solution for this.
examples/game/alien_cake_addict.rs
Outdated
| scoreboard_system.system(), | ||
| .add_system_set(State::on_enter_set(GameState::Playing).with_system(setup.system())) | ||
| .add_system_set( | ||
| State::on_update_set(GameState::Playing) |
There was a problem hiding this comment.
on_enter_set and friends is a bit of a confusing name in English: "set" could either be a verb (to set a property on update...) or a "noun" (a collection of systems). I think it's the latter here from context.
IMO State::on_enter (etc.) would be clearer in typical usage, since you're seeing the system set call just above it already.
There was a problem hiding this comment.
Ah I see, those names are reserved for the transition functions...
What about on_enter_systems?
There was a problem hiding this comment.
I don't feel strongly either way, so sure.
There was a problem hiding this comment.
I think I like this:
.add_system_set(SystemSet::on_enter(GameState::Playing).with_system(setup.system()))more than this:
.add_system_set(State::on_enter_set(GameState::Playing).with_system(setup.system()))Normally I would prefer the current impl as it's a clean "layer" on top of system sets, but SystemSet::on_enter reads better and is clearer about the type. The fact that they are in the same module also makes me feel better about it.
| let stages = self.state_stages(state); | ||
| stages.enter = Box::new(stage); | ||
| self | ||
| pub fn on_inactive_update(s: T) -> impl System<In = (), Out = ShouldRun> { |
There was a problem hiding this comment.
Could we have a doc string describing this function? It's not clear from either the name or a quick look at the code.
There was a problem hiding this comment.
Hmm, documentation on the various on_*_set methods is a good idea, though I'd probably put the actual docs on on_* and link.
examples/game/alien_cake_addict.rs
Outdated
| scoreboard_system.system(), | ||
| .add_system_set(State::on_enter_set(GameState::Playing).with_system(setup.system())) | ||
| .add_system_set( | ||
| State::on_update_set(GameState::Playing) |
There was a problem hiding this comment.
I think I like this:
.add_system_set(SystemSet::on_enter(GameState::Playing).with_system(setup.system()))more than this:
.add_system_set(State::on_enter_set(GameState::Playing).with_system(setup.system()))Normally I would prefer the current impl as it's a clean "layer" on top of system sets, but SystemSet::on_enter reads better and is clearer about the type. The fact that they are in the same module also makes me feel better about it.
|
bors r+ |
An alternative to StateStages that uses SystemSets. Also includes pop and push operations since this was originally developed for my personal project which needed them.
|
Pull request successfully merged into main. Build succeeded: |
|
Thank you for this @TheRawMeatball !! Me and my brother were literally just talking about how we felt like state could be simpler and then a couple hours later this is merged. It's great! |
An alternative to StateStages that uses SystemSets. Also includes pop and push operations since this was originally developed for my personal project which needed them.