Allow erasing cells in game_of_life
This commit is contained in:
parent
4417a34edb
commit
917199197f
@ -156,6 +156,7 @@ mod grid {
|
|||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum Message {
|
pub enum Message {
|
||||||
Populate(Cell),
|
Populate(Cell),
|
||||||
|
Unpopulate(Cell),
|
||||||
Ticked {
|
Ticked {
|
||||||
result: Result<Life, TickError>,
|
result: Result<Life, TickError>,
|
||||||
tick_duration: Duration,
|
tick_duration: Duration,
|
||||||
@ -217,6 +218,10 @@ mod grid {
|
|||||||
self.state.populate(cell);
|
self.state.populate(cell);
|
||||||
self.life_cache.clear();
|
self.life_cache.clear();
|
||||||
}
|
}
|
||||||
|
Message::Unpopulate(cell) => {
|
||||||
|
self.state.unpopulate(&cell);
|
||||||
|
self.life_cache.clear();
|
||||||
|
}
|
||||||
Message::Ticked {
|
Message::Ticked {
|
||||||
result: Ok(life),
|
result: Ok(life),
|
||||||
version,
|
version,
|
||||||
@ -293,20 +298,25 @@ mod grid {
|
|||||||
|
|
||||||
let cursor_position = cursor.position_in(&bounds)?;
|
let cursor_position = cursor.position_in(&bounds)?;
|
||||||
let cell = Cell::at(self.project(cursor_position, bounds.size()));
|
let cell = Cell::at(self.project(cursor_position, bounds.size()));
|
||||||
|
let is_populated = self.state.contains(&cell);
|
||||||
|
|
||||||
let populate = if self.state.contains(&cell) {
|
let (populate, unpopulate) = if is_populated {
|
||||||
None
|
(None, Some(Message::Unpopulate(cell)))
|
||||||
} else {
|
} else {
|
||||||
Some(Message::Populate(cell))
|
(Some(Message::Populate(cell)), None)
|
||||||
};
|
};
|
||||||
|
|
||||||
match event {
|
match event {
|
||||||
Event::Mouse(mouse_event) => match mouse_event {
|
Event::Mouse(mouse_event) => match mouse_event {
|
||||||
mouse::Event::ButtonPressed(button) => match button {
|
mouse::Event::ButtonPressed(button) => match button {
|
||||||
mouse::Button::Left => {
|
mouse::Button::Left => {
|
||||||
self.interaction = Interaction::Drawing;
|
self.interaction = if is_populated {
|
||||||
|
Interaction::Erasing
|
||||||
|
} else {
|
||||||
|
Interaction::Drawing
|
||||||
|
};
|
||||||
|
|
||||||
populate
|
populate.or(unpopulate)
|
||||||
}
|
}
|
||||||
mouse::Button::Right => {
|
mouse::Button::Right => {
|
||||||
self.interaction = Interaction::Panning {
|
self.interaction = Interaction::Panning {
|
||||||
@ -321,6 +331,7 @@ mod grid {
|
|||||||
mouse::Event::CursorMoved { .. } => {
|
mouse::Event::CursorMoved { .. } => {
|
||||||
match self.interaction {
|
match self.interaction {
|
||||||
Interaction::Drawing => populate,
|
Interaction::Drawing => populate,
|
||||||
|
Interaction::Erasing => unpopulate,
|
||||||
Interaction::Panning { translation, start } => {
|
Interaction::Panning { translation, start } => {
|
||||||
self.translation = translation
|
self.translation = translation
|
||||||
+ (cursor_position - start)
|
+ (cursor_position - start)
|
||||||
@ -504,6 +515,7 @@ mod grid {
|
|||||||
) -> mouse::Interaction {
|
) -> mouse::Interaction {
|
||||||
match self.interaction {
|
match self.interaction {
|
||||||
Interaction::Drawing => mouse::Interaction::Crosshair,
|
Interaction::Drawing => mouse::Interaction::Crosshair,
|
||||||
|
Interaction::Erasing => mouse::Interaction::Crosshair,
|
||||||
Interaction::Panning { .. } => mouse::Interaction::Grabbing,
|
Interaction::Panning { .. } => mouse::Interaction::Grabbing,
|
||||||
Interaction::None if cursor.is_over(&bounds) => {
|
Interaction::None if cursor.is_over(&bounds) => {
|
||||||
mouse::Interaction::Crosshair
|
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) {
|
fn update(&mut self, mut life: Life) {
|
||||||
self.births.drain().for_each(|cell| life.populate(cell));
|
self.births.drain().for_each(|cell| life.populate(cell));
|
||||||
|
|
||||||
@ -592,6 +612,10 @@ mod grid {
|
|||||||
self.cells.insert(cell);
|
self.cells.insert(cell);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn unpopulate(&mut self, cell: &Cell) {
|
||||||
|
let _ = self.cells.remove(cell);
|
||||||
|
}
|
||||||
|
|
||||||
fn tick(&mut self) {
|
fn tick(&mut self) {
|
||||||
let mut adjacent_life = FxHashMap::default();
|
let mut adjacent_life = FxHashMap::default();
|
||||||
|
|
||||||
@ -706,6 +730,7 @@ mod grid {
|
|||||||
enum Interaction {
|
enum Interaction {
|
||||||
None,
|
None,
|
||||||
Drawing,
|
Drawing,
|
||||||
|
Erasing,
|
||||||
Panning { translation: Vector, start: Point },
|
Panning { translation: Vector, start: Point },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user