Allow erasing cells in game_of_life

This commit is contained in:
Héctor Ramón Jiménez 2020-05-03 02:43:20 +02:00
parent 4417a34edb
commit 917199197f

View File

@ -156,6 +156,7 @@ mod grid {
#[derive(Debug, Clone)]
pub enum Message {
Populate(Cell),
Unpopulate(Cell),
Ticked {
result: Result<Life, TickError>,
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 },
}
}