Skip to content
Snippets Groups Projects
steps.rs 4.17 KiB
Newer Older
use bevy::{app::AppExit, prelude::*};
use big_brain::{pickers, prelude::*};

#[test]
fn steps() {
    println!("steps test");
    App::new()
        .add_plugins(MinimalPlugins)
        .add_plugin(BigBrainPlugin)
        .init_resource::<GlobalState>()
        .add_startup_system(setup)
        .add_system_to_stage(CoreStage::First, no_failure_score)
        .add_system(action1)
        .add_system(action2)
        .add_system(exit_action)
        .add_system(failure_action)
        .add_system_to_stage(CoreStage::Last, last)
        .run();
    println!("end");
}

fn setup(mut cmds: Commands) {
    cmds.spawn().insert(
        Thinker::build()
            .picker(pickers::FirstToScore::new(0.5))
            .when(NoFailureScore, Steps::build().step(FailureAction))
            .otherwise(Steps::build().step(Action1).step(Action2).step(ExitAction)),
    );
}

#[derive(Clone, Component, Debug, Default)]
struct Action1;
impl ActionBuilder for Action1 {
    fn build(&self, cmd: &mut Commands, action: Entity, _actor: Entity) {
        cmd.entity(action)
            .insert(self.clone())
            .insert(ActionState::Requested);
    }
}

fn action1(mut query: Query<(&Actor, &mut ActionState), With<Action1>>) {
    for (Actor(_actor), mut state) in query.iter_mut() {
        println!("action1 {:?}", state);
        if *state == ActionState::Requested {
            *state = ActionState::Executing;
        }
        if *state == ActionState::Executing {
            *state = ActionState::Success;
        }
    }
}

#[derive(Clone, Component, Debug, Default)]
struct Action2;
impl ActionBuilder for Action2 {
    fn build(&self, cmd: &mut Commands, action: Entity, _actor: Entity) {
        cmd.entity(action)
            .insert(self.clone())
            .insert(ActionState::Requested);
    }
}

fn action2(mut query: Query<(&Actor, &mut ActionState), With<Action2>>) {
    for (Actor(_actor), mut state) in query.iter_mut() {
        println!("action2 {:?}", state);
        if *state == ActionState::Requested {
            *state = ActionState::Executing;
        }
        if *state == ActionState::Executing {
            *state = ActionState::Success;
        }
    }
}

#[derive(Clone, Component, Debug, Default)]
struct ExitAction;
impl ActionBuilder for ExitAction {
    fn build(&self, cmd: &mut Commands, action: Entity, _actor: Entity) {
        cmd.entity(action)
            .insert(self.clone())
            .insert(ActionState::Requested);
    }
}

fn exit_action(
    mut query: Query<(&Actor, &mut ActionState), With<ExitAction>>,
    mut app_exit_events: EventWriter<AppExit>,
) {
    for (Actor(_actor), mut state) in query.iter_mut() {
        println!("exit_action {:?}", state);
        if *state == ActionState::Requested {
            *state = ActionState::Executing;
        }
        if *state == ActionState::Executing {
            app_exit_events.send(AppExit);
        }
    }
}

fn last() {
    println!();
}

#[derive(Clone, Component, Debug, Default)]
struct FailureAction;
impl ActionBuilder for FailureAction {
    fn build(&self, cmd: &mut Commands, action: Entity, _actor: Entity) {
        cmd.entity(action)
            .insert(self.clone())
            .insert(ActionState::Requested);
    }
}

fn failure_action(
    mut query: Query<(&Actor, &mut ActionState), With<FailureAction>>,
    mut global_state: ResMut<GlobalState>,
) {
    for (Actor(_actor), mut state) in query.iter_mut() {
        println!("failure_action {:?}", state);
        if *state == ActionState::Requested {
            *state = ActionState::Executing;
        }
        if *state == ActionState::Executing {
            global_state.failure = true;
            *state = ActionState::Failure;
        }
    }
}

#[derive(Default)]
struct GlobalState {
    failure: bool,
}

#[derive(Clone, Component, Debug)]
struct NoFailureScore;
impl ScorerBuilder for NoFailureScore {
    fn build(&self, cmd: &mut Commands, action: Entity, _actor: Entity) {
        cmd.entity(action).insert(self.clone());
    }
}

fn no_failure_score(
    mut query: Query<(&NoFailureScore, &mut Score)>,
    global_state: Res<GlobalState>,
) {
    for (_, mut score) in query.iter_mut() {
        score.set(if global_state.failure { 0.0 } else { 1.0 });
    }
}