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

System's executing order based component that the system read and writes #2379

Closed
ghost opened this issue Jun 23, 2021 · 5 comments
Closed

Comments

@ghost
Copy link

ghost commented Jun 23, 2021

Now System's execute order based label, but why not base component that the system read and writes by default?

Like Unity: https://docs.unity3d.com/Packages/com.unity.entities@0.17/manual/ecs_job_dependencies.html

By Example

The following code output is:

> system_2
> system_1

but with the system_2 with SystemParam Res, and system_1 with ResMut;

now may I run system_1 before system_2 runing by default without labeling system?

If the anser is not, and can you tell me that the difficult of implementation, or any other design concideration ?

#[test]
    fn test_system() {
        fn system_1(
            value: ResMut<bool>,
        ) {
            println!("system_1");
        }

        fn system_2(
            value: Res<bool>,
        ) {
            println!("system_2");
        }

        let mut world = World::default();
        world.insert_resource(false);
        
        let mut schedule = Schedule::default();
        let mut update = SystemStage::parallel();
        update.add_system(system_1.system());
        update.add_system(system_2.system());
        
        schedule.add_stage("update", update);
        
        schedule.run(&mut world);
    }

To my untrained eye, can I implement it by adding some derived macro inditate that SystemParameter dependency, which used in the system initialize ?

@ghost ghost added C-Feature A new feature, making something new possible S-Needs-Triage This issue needs to be labelled labels Jun 23, 2021
@james7132
Copy link
Member

Unity's ECS is able to determine ordering because query based jobs explicitly mark inputs and outputs and systems mark explicitly which SystemGroup they're grouped under, which allows them to build a solvable dependency graph. You can sort of achieve the same thing with system chaining: https://bevy-cheatbook.github.io/programming/system-chaining.html, but the values are not written to a World. For world-affecting systems, outside of labels and stages, there's currently nothing to order system execution. because by default Bevy tries to execute as much as possible as wide as possible without violating Rust's borrow checker's rules. Simply declaring that a system input is mutable does not denote when the system should run, and in your example, the ordering is not strictly defined other than that the two systems should not run at the same time.

Right now it's likely easier to just use labels to order your systems, preferably keeping isolated system "families" unordered relative to each other to maximize available parallelism.

@james7132
Copy link
Member

james7132 commented Jun 23, 2021

With that said, establishing strictly sequential system sets, something required for deterministic simulation needed for some networking models, requires a large amount of repetitive labeling (example: https://github.com/HouraiTeahouse/FantasyCresendoBevy/blob/master/src/match/mod.rs#L248). This does not even work with SystemStage::single_threaded(): insertion order does not guarantee execution order. Perhaps a SystemSet::as_sequential utility function would be useful force sequential execution.

One potential solution is to perhaps run one large exclusive system, perhaps with a large derived SystemParam to encompass all of the queries needed for every sequential sub-system, but that can get pretty nasty real fast with suboptimal queries.

@Ratysz
Copy link
Contributor

Ratysz commented Jun 27, 2021

We used to do just that, before changing to the current model. You can skim thruogh #1144 and related discussions to get a picture of why doing that by default is the worse idea.

It is possible to re-implement that on top of the current system, and it should be doable as a third-party addon. There are better ways we could include into Bevy itself to make the current story more ergonomic, like #2381.

@Ratysz Ratysz added core and removed C-Feature A new feature, making something new possible S-Needs-Triage This issue needs to be labelled labels Jun 27, 2021
@ghost
Copy link
Author

ghost commented Jun 29, 2021

3Q very much

@Ratysz
Copy link
Contributor

Ratysz commented Jun 29, 2021

Please close the issue if your question has been answered.

@ghost ghost closed this as completed Jun 30, 2021
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants