From 917199197f9719bbb3f6f98c63985cb64dfd147c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Sun, 3 May 2020 02:43:20 +0200 Subject: [PATCH] Allow erasing cells in `game_of_life` --- examples/game_of_life/src/main.rs | 35 ++++++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/examples/game_of_life/src/main.rs b/examples/game_of_life/src/main.rs index c2f80dfc..080d55c0 100644 --- a/examples/game_of_life/src/main.rs +++ b/examples/game_of_life/src/main.rs @@ -156,6 +156,7 @@ mod grid { #[derive(Debug, Clone)] pub enum Message { Populate(Cell), + Unpopulate(Cell), Ticked { result: Result, tick_duration: Duration, @@ -217,6 +218,10 @@ mod grid { self.state.populate(cell); self.life_cache.clear(); } + Message::Unpopulate(cell) => { + self.state.unpopulate(&cell); + self.life_cache.clear(); + } Message::Ticked { result: Ok(life), version, @@ -293,20 +298,25 @@ mod grid { let cursor_position = cursor.position_in(&bounds)?; let cell = Cell::at(self.project(cursor_position, bounds.size())); + let is_populated = self.state.contains(&cell); - let populate = if self.state.contains(&cell) { - None + let (populate, unpopulate) = if is_populated { + (None, Some(Message::Unpopulate(cell))) } else { - Some(Message::Populate(cell)) + (Some(Message::Populate(cell)), None) }; match event { Event::Mouse(mouse_event) => match mouse_event { mouse::Event::ButtonPressed(button) => match button { mouse::Button::Left => { - self.interaction = Interaction::Drawing; + self.interaction = if is_populated { + Interaction::Erasing + } else { + Interaction::Drawing + }; - populate + populate.or(unpopulate) } mouse::Button::Right => { self.interaction = Interaction::Panning { @@ -321,6 +331,7 @@ mod grid { mouse::Event::CursorMoved { .. } => { match self.interaction { Interaction::Drawing => populate, + Interaction::Erasing => unpopulate, Interaction::Panning { translation, start } => { self.translation = translation + (cursor_position - start) @@ -504,6 +515,7 @@ mod grid { ) -> mouse::Interaction { match self.interaction { Interaction::Drawing => mouse::Interaction::Crosshair, + Interaction::Erasing => mouse::Interaction::Crosshair, Interaction::Panning { .. } => mouse::Interaction::Grabbing, Interaction::None if cursor.is_over(&bounds) => { mouse::Interaction::Crosshair @@ -541,6 +553,14 @@ mod grid { } } + fn unpopulate(&mut self, cell: &Cell) { + if self.is_ticking { + let _ = self.births.remove(cell); + } else { + self.life.unpopulate(cell); + } + } + fn update(&mut self, mut life: Life) { self.births.drain().for_each(|cell| life.populate(cell)); @@ -592,6 +612,10 @@ mod grid { self.cells.insert(cell); } + fn unpopulate(&mut self, cell: &Cell) { + let _ = self.cells.remove(cell); + } + fn tick(&mut self) { let mut adjacent_life = FxHashMap::default(); @@ -706,6 +730,7 @@ mod grid { enum Interaction { None, Drawing, + Erasing, Panning { translation: Vector, start: Point }, } }