Behind Coleus

大学生なのに特別大学で楽しいことが一 つもない。虐待と男子校病のせいにしてみる。→日本脱出しました 今ジャカルタにいます。→ジャカルタから帰ってきました。→6月19日から小笠原沖で、インドネシア人とメカジキ漁

youtu.be今回の目的は、システムの実行順をコントロールする方法として、.before, .after, .chain, systemsetを実践することです。

 

今回は、動画のコードは分かりにくいので、system a system b system cという関数を作り、それの実行結果について考察を行う。
まずは以下の様なコードをビルドして、順番を確かめた。

use bevy::prelude::*;
fn main() {
    App::new()
    .add_plugins(MinimalPlugins)
    .add_systems(Startup, (system_a, system_b, system_c))
    .run();
}
fn system_a() {
    println!("System A is running");
}

fn system_b() {
    println!("System B is running");
}

fn system_c() {
    println!("System C is running");
}

この実行結果の場合、ビルドする度に、Systemの実行順が変わっていることが分かる。

つまり、bevyは並列処理をするため、五月雨に実行していて順番が変わるのである。

use bevy::prelude::*;
fn main() {
    App::new()
        .add_plugins(MinimalPlugins)
        .add_systems(Startup, system_c.before(system_a))
        .add_systems(Startup, system_a.after(system_b))
        .add_systems(Startup, system_b.after(system_c))
        .run();
}
fn system_a() {
    println!("System A is running");
}

fn system_b() {
    println!("System B is running");
}

fn system_c() {
    println!("System C is running");
}

上の3つのシステムの順番は3回実行しても変わらなかった。

今回は、3つの条件を与えて、順番を統制した。はじめは、二つしか条件を与えていなかったので、完全に忘れていた。

次に、

use bevy::prelude::*;
fn main() {
    App::new()
        .add_plugins(MinimalPlugins)
        .add_systems(Startup, (system_a, system_b, system_c).chain())
        .run();
}
fn system_a() {
    println!("System A is running");
}

fn system_b() {
    println!("System B is running");
}

fn system_c() {
    println!("System C is running");
}

このように、chain()を使うことで、一発で順番を完全に制御できる。

use bevy::prelude::*;

#[derive(SystemSet, Debug, Hash, PartialEq, Eq, Clone)]
pub struct Systemset1;
#[derive(SystemSet, Debug, Hash, PartialEq, Eq, Clone)]
pub struct Systemset2;

fn main() {
    App::new()
        .add_plugins(MinimalPlugins)
        .configure_sets(Startup, Systemset1.before(Systemset2))
        .add_systems(Startup, system_a.in_set(Systemset1))
        .add_systems(Startup, system_b.in_set(Systemset1))
        .add_systems(Startup, system_c.in_set(Systemset2))
        .run();
}
fn system_a() {
    println!("System A is running");
}

fn system_b() {
    println!("System B is running");
}

fn system_c() {
    println!("System C is running");
}

そして、もう一つの方法として、SystemSetも使ってみた。

今回は、

SystemSetは

#[derive(SystemSet, Debug, Hash, PartialEq, Eq, Clone)]
pub struct Systemset1;

このように宣言し、導入するときは、

        .configure_sets(Startup, Systemset1.before(Systemset2))

このように宣言する。
これは、Systemset1を、Systemset2の前に実行するという意味である。
さらに、既存のシステムをSystemSetに入れたいときは、.in_set()を用いる。

これにより、システムをシステムセットに所属させることが出来る。

そして、実行結果は必ずABCの順番になった。つまり、Systemset1にコードの順番通りに記録され、それがSystemset2の前に実行されたという事になる。

fn main() {
    App::new()
        .add_plugins(MinimalPlugins)
        .configure_sets(Startup, Systemset1.before(Systemset2))
        .add_systems(Startup, system_b.in_set(Systemset1))
        .add_systems(Startup, system_a.in_set(Systemset1))
        .add_systems(Startup, system_c.in_set(Systemset2))
        .run();
}

また、このようにsystembの、.in_setを先に宣言すると、

実行結果は必ずBACの順になる。.insetは並列処理はされない。

SystemSetは、enum型でも宣言できる。

use bevy::prelude::*;

// #[derive(SystemSet, Debug, Hash, PartialEq, Eq, Clone)]
// pub struct Systemset1;
// #[derive(SystemSet, Debug, Hash, PartialEq, Eq, Clone)]
// pub struct Systemset2;

#[derive(SystemSet, Debug, Hash, PartialEq, Eq, Clone)]
pub enum SystemSetABC {
    FunctionAB,
    FunctionC,
}

fn main() {
    App::new()
        .add_plugins(MinimalPlugins)
        .configure_sets(
            Startup,
            SystemSetABC::FunctionAB.before(SystemSetABC::FunctionC),
        )
        .add_systems(Startup, system_a.in_set(SystemSetABC::FunctionAB))
        .add_systems(Startup, system_b.in_set(SystemSetABC::FunctionAB))
        .add_systems(Startup, system_c.in_set(SystemSetABC::FunctionC))
        .run();
}
fn system_a() {
    println!("System A is running");
}

fn system_b() {
    println!("System B is running");
}

fn system_c() {
    println!("System C is running");
}

これの実行結果は、必ずABCになる。

 

まとめると、今回は

二つの実行順を制御したい場合は.before(), .after()を使う。

.chain()は順番を完全に制御できる。

大きなプロジェクトで実行順を把握するには、SystemSetを使う。その為には、.configure_set()と.in_set()が必要である。