Adopt actions framework
parent
494cdce42e
commit
09e6c66788
@ -0,0 +1,137 @@
|
||||
use super::*;
|
||||
|
||||
pub(crate) struct GameActionsPlugin;
|
||||
|
||||
impl Plugin for GameActionsPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.add_plugins((
|
||||
ActionsPlugin::<SimAction>::new()
|
||||
.bind(SimAction::Toggle, [Binding::Key(KeyCode::Space)])
|
||||
.bind(SimAction::Step, [Binding::Key(KeyCode::KeyN)])
|
||||
.bind(SimAction::Reset, [Binding::Key(KeyCode::KeyR)]),
|
||||
ActionsPlugin::<AudioAction>::new()
|
||||
.bind(AudioAction::Toggle, [Binding::Key(KeyCode::KeyM)]),
|
||||
ActionsPlugin::<Action>::new()
|
||||
.bind(Action::ZoomIn, [Binding::Key(KeyCode::Equal)])
|
||||
.bind(Action::ZoomOut, [Binding::Key(KeyCode::Minus)])
|
||||
.bind(Action::Quit, [Binding::Key(KeyCode::Escape)]),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Eq, PartialEq, Hash, GameAction, Default)]
|
||||
pub(crate) enum SimAction {
|
||||
#[action_handler(SimAction::toggle)]
|
||||
Toggle,
|
||||
#[action_handler(SimAction::step)]
|
||||
Step,
|
||||
#[action_handler(SimAction::reset)]
|
||||
Reset,
|
||||
#[action_handler(SimAction::wipe)]
|
||||
Wipe,
|
||||
#[default]
|
||||
None,
|
||||
}
|
||||
|
||||
impl SimAction {
|
||||
/// When the user toggles between Play/Pause simulation, just update the state
|
||||
fn toggle(
|
||||
curr: Res<State<SimulationPlayback>>,
|
||||
mut next: ResMut<NextState<SimulationPlayback>>,
|
||||
mut last_board_state: ResMut<LastBoardState>,
|
||||
coordinates: Query<&Coordinates, With<Cell>>,
|
||||
) {
|
||||
next.set(match curr.get() {
|
||||
SimulationPlayback::Run | SimulationPlayback::Step => {
|
||||
// Run | Step -> Pause
|
||||
SimulationPlayback::Pause
|
||||
}
|
||||
SimulationPlayback::Pause => {
|
||||
// Capture current state before running
|
||||
last_board_state.coordinates = coordinates.iter().cloned().collect();
|
||||
// Pause -> Run
|
||||
SimulationPlayback::Run
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// When the user wants to step the simulation, just enter the SimulationStep state
|
||||
// TODO: Should switch back to Pause automatically after step if Step is the current state
|
||||
fn step(mut next: ResMut<NextState<SimulationPlayback>>) {
|
||||
next.set(SimulationPlayback::Step);
|
||||
}
|
||||
|
||||
// Reset board to last saved state (before running, or before wiping)
|
||||
fn reset(
|
||||
last_board_state: Res<LastBoardState>,
|
||||
mut lifecycle: MessageWriter<Lifecycle>,
|
||||
cells: Query<Entity, With<Cell>>,
|
||||
mut commands: Commands,
|
||||
) {
|
||||
// TODO: reconcile board instead of despawn/spawning the world
|
||||
cells.iter().for_each(|e| {
|
||||
commands.entity(e).despawn();
|
||||
});
|
||||
last_board_state.coordinates.iter().for_each(|c| {
|
||||
lifecycle.write(Lifecycle::Alive(c.clone()));
|
||||
});
|
||||
}
|
||||
|
||||
// Wipe all cells from the board
|
||||
fn wipe(cells: Query<Entity, With<Cell>>, mut commands: Commands) {
|
||||
cells.iter().for_each(|e| {
|
||||
commands.entity(e).despawn();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Eq, PartialEq, Hash, GameAction, Default)]
|
||||
pub(crate) enum Action {
|
||||
#[action_handler(Action::zoom_in)]
|
||||
ZoomIn,
|
||||
#[action_handler(Action::zoom_out)]
|
||||
ZoomOut,
|
||||
#[action_handler(Action::quit)]
|
||||
Quit,
|
||||
#[default]
|
||||
None,
|
||||
}
|
||||
|
||||
impl Action {
|
||||
fn zoom_in(mut projection: Query<&mut Projection>) {
|
||||
projection.iter_mut().for_each(|mut p| match *p {
|
||||
Projection::Orthographic(ref mut o) => {
|
||||
o.scale *= 0.5;
|
||||
}
|
||||
_ => todo!(),
|
||||
});
|
||||
}
|
||||
fn zoom_out(mut projection: Query<&mut Projection>) {
|
||||
projection.iter_mut().for_each(|mut p| match *p {
|
||||
Projection::Orthographic(ref mut o) => {
|
||||
o.scale /= 0.5;
|
||||
}
|
||||
_ => todo!(),
|
||||
});
|
||||
}
|
||||
fn quit(mut writer: MessageWriter<AppExit>) {
|
||||
writer.write(AppExit::Success);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Eq, PartialEq, Hash, GameAction, Default)]
|
||||
pub(crate) enum AudioAction {
|
||||
#[action_handler(AudioAction::toggle)]
|
||||
Toggle,
|
||||
#[default]
|
||||
None,
|
||||
}
|
||||
|
||||
impl AudioAction {
|
||||
fn toggle(curr: Res<State<AudioPlayback>>, mut next: ResMut<NextState<AudioPlayback>>) {
|
||||
next.set(match curr.get() {
|
||||
AudioPlayback::Play => AudioPlayback::Mute,
|
||||
AudioPlayback::Mute => AudioPlayback::Play,
|
||||
});
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue