diff --git a/life/src/main.rs b/life/src/main.rs index 0c97aea..723a6ea 100644 --- a/life/src/main.rs +++ b/life/src/main.rs @@ -1,3 +1,4 @@ +use bevy::asset::{AssetPath, HandleTemplate}; use engine::*; const TILE: &str = "tileGrey_01.png"; @@ -72,7 +73,6 @@ fn main() { Update, toggle_state_entities::.run_if(state_changed::), ) - .add_observer(on_add_ui_button) .add_observer(on_add_coordinates) .run(); } @@ -86,7 +86,7 @@ enum AudioPlayback { Play, } -#[derive(Debug, Component, PartialEq, Default, FromTemplate)] +#[derive(Debug, Component, PartialEq, Default)] #[require(Visibility, Transform)] enum UiButton { Power, @@ -117,51 +117,41 @@ impl UiButton { } } -fn on_add_ui_button( - trigger: On, - mut commands: Commands, - query: Query<&UiButton>, - server: Res, -) { - let button = query.get(trigger.entity).unwrap(); - commands - .entity(trigger.entity) - .insert(( - Button, - Hovered::default(), - Outline { - width: Val::Px(5.0), - color: Color::NONE, - ..default() - }, +fn ui_button( + button: UiButton, +) -> impl Scene { + let color: Color = WHITE.with_alpha(0.5).into(); + bsn! { + Button + Hovered + Outline { + width: Val::Px(5.0), + color: Color::NONE, + } + Node { + top: Val::Px(2.5), + left: Val::Px(2.5), + margin: UiRect::all(Val::Px(2.5)), + } + BackgroundColor(GRAY) + ImageNode { + image: HandleTemplate::Path(TILE), + color, + } + Children [ Node { - top: Val::Px(2.5), - left: Val::Px(2.5), - margin: UiRect::all(Val::Px(2.5)), - ..default() - }, - BackgroundColor(GRAY.into()), + align_self: AlignSelf::Center, + justify_self: JustifySelf::Center, + width: Val::Percent(100.0), + height: Val::Percent(100.0), + } ImageNode { - image: server.load(TILE), - color: WHITE.with_alpha(0.5).into(), - ..default() - }, - children![( - Node { - align_self: AlignSelf::Center, - justify_self: JustifySelf::Center, - width: Val::Percent(100.0), - height: Val::Percent(100.0), - ..default() - }, - ImageNode { - image: server.load(button.icon()), - ..default() - }, - )], - )) - .observe(responsive_button_over) - .observe(responsive_button_out); + image: HandleTemplate::Path(AssetPath::parse(button.icon())), + } + ] + on(responsive_button_over) + on(responsive_button_out) + } } fn the_camera() -> impl Scene { @@ -180,27 +170,27 @@ fn the_ui() -> impl Scene { } Transform Children [ - UiButton::Power + ui_button(UiButton::Power) on(|_: On>, mut writer: MessageWriter| { writer.write(AppExit::Success); }), - UiButton::Pause + ui_button(UiButton::Pause) SimulationPlayback::Run on(|_: On>, mut next: ResMut>| { // Set simulation state next.set(SimulationPlayback::Pause); }), - UiButton::Play + ui_button(UiButton::Play) SimulationPlayback::Pause on(|_: On>, mut next: ResMut>| { // Set simulation state next.set(SimulationPlayback::Run); }), - UiButton::Step + ui_button(UiButton::Step) on(|_: On>, mut next: ResMut>| { next.set(SimulationPlayback::Step); }), - UiButton::ZoomOut + ui_button(UiButton::ZoomOut) on(|_: On>, mut projection: Query<&mut Projection>| { projection.iter_mut().for_each(|mut p| match *p { Projection::Orthographic(ref mut o) => { @@ -209,7 +199,7 @@ fn the_ui() -> impl Scene { _ => todo!(), }); }), - UiButton::ZoomIn + ui_button(UiButton::ZoomIn) on(|_: On>, mut projection: Query<&mut Projection>| { projection.iter_mut().for_each(|mut p| match *p { Projection::Orthographic(ref mut o) => { @@ -218,15 +208,15 @@ fn the_ui() -> impl Scene { _ => todo!(), }); }), - UiButton::MuteAudio + ui_button(UiButton::MuteAudio) AudioPlayback::Play on(|_: On>, mut next: ResMut>| { - next.set(AudioPlayback::Play); + next.set(AudioPlayback::Mute); }), - UiButton::PlayAudio + ui_button(UiButton::PlayAudio) AudioPlayback::Mute on(|_: On>, mut next: ResMut>| { - next.set(AudioPlayback::Mute); + next.set(AudioPlayback::Play); }), ] } @@ -235,7 +225,7 @@ fn the_ui() -> impl Scene { #[derive(Default, Debug, Resource)] struct NextCoordinates(Coordinates); -#[derive(Debug, Default, Clone, PartialEq, Hash, Eq, Component)] +#[derive(Debug, Default, Clone, PartialEq, Hash, Eq, Component, FromTemplate)] #[require(Visibility, Transform)] struct Coordinates { x: isize, @@ -383,7 +373,7 @@ fn grid_gizmo(mut gizmos: Gizmos, coordinates: Res) { gizmos.rect_2d(isometry, Vec2::ONE * SCALE, PURPLE) } -#[derive(Component, Debug, PartialEq, Hash, Eq)] +#[derive(Component, Debug, PartialEq, Hash, Eq, FromTemplate)] struct Cell; // When left mouse clicked, spawn a cell at GridPosition @@ -522,12 +512,19 @@ enum Lifecycle { Dead(Entity), } +fn new_cell(Coordinates { x, y }: Coordinates) -> impl Scene { + bsn! { + Coordinates { x, y } + Cell + } +} + fn cell_lifecycle(mut reader: MessageReader, mut commands: Commands) { reader.read().for_each(|msg| match msg { Lifecycle::Alive(c) => { debug!("creating {:?}", c); // TODO: Safeguard: ensure no other cell there? - commands.spawn((c.clone(), Cell)); + commands.spawn_scene(new_cell(c.clone())); } Lifecycle::Dead(e) => { commands.entity(*e).despawn();