diff options
author | 2020-05-03 00:57:15 +0200 | |
---|---|---|
committer | 2020-05-03 00:57:15 +0200 | |
commit | c3c5161386cb527bf6d0fe34e5f4103392733599 (patch) | |
tree | 18b42d48b885ebd2e6b5f6d0701156eb963c85e5 /examples/game_of_life | |
parent | a43fb42428cbcef3d80e0ec21ec92c6db506353d (diff) | |
download | iced-c3c5161386cb527bf6d0fe34e5f4103392733599.tar.gz iced-c3c5161386cb527bf6d0fe34e5f4103392733599.tar.bz2 iced-c3c5161386cb527bf6d0fe34e5f4103392733599.zip |
Draw grid in `game_of_life`
Diffstat (limited to 'examples/game_of_life')
-rw-r--r-- | examples/game_of_life/src/main.rs | 91 |
1 files changed, 73 insertions, 18 deletions
diff --git a/examples/game_of_life/src/main.rs b/examples/game_of_life/src/main.rs index 0e66c237..52b04696 100644 --- a/examples/game_of_life/src/main.rs +++ b/examples/game_of_life/src/main.rs @@ -13,7 +13,10 @@ use iced::{ use std::time::{Duration, Instant}; pub fn main() { - GameOfLife::run(Settings::default()) + GameOfLife::run(Settings { + antialiasing: true, + ..Settings::default() + }) } #[derive(Default)] @@ -132,12 +135,14 @@ mod grid { }; use rustc_hash::{FxHashMap, FxHashSet}; use std::future::Future; + use std::ops::RangeInclusive; use std::time::{Duration, Instant}; pub struct Grid { state: State, interaction: Interaction, - cache: Cache, + life_cache: Cache, + grid_cache: Cache, translation: Vector, scaling: f32, version: usize, @@ -163,7 +168,8 @@ mod grid { Self { state: State::default(), interaction: Interaction::None, - cache: Cache::default(), + life_cache: Cache::default(), + grid_cache: Cache::default(), translation: Vector::default(), scaling: 1.0, version: 0, @@ -203,14 +209,14 @@ mod grid { self.state = State::default(); self.version += 1; - self.cache.clear(); + self.life_cache.clear(); } pub fn update(&mut self, message: Message) -> Option<Duration> { match message { Message::Populate(cell) => { self.state.populate(cell); - self.cache.clear(); + self.life_cache.clear(); None } @@ -220,7 +226,7 @@ mod grid { tick_duration, } if version == self.version => { self.state.update(life); - self.cache.clear(); + self.life_cache.clear(); Some(tick_duration) } @@ -310,7 +316,8 @@ mod grid { + (cursor_position - start) * (1.0 / self.scaling); - self.cache.clear(); + self.life_cache.clear(); + self.grid_cache.clear(); None } @@ -344,7 +351,8 @@ mod grid { ); } - self.cache.clear(); + self.life_cache.clear(); + self.grid_cache.clear(); } None @@ -358,7 +366,7 @@ mod grid { fn draw(&self, bounds: Rectangle, cursor: Cursor) -> Vec<Geometry> { let center = Vector::new(bounds.width / 2.0, bounds.height / 2.0); - let life = self.cache.draw(bounds.size(), |frame| { + let life = self.life_cache.draw(bounds.size(), |frame| { let background = Path::rectangle(Point::ORIGIN, frame.size()); frame.fill(&background, Color::from_rgb8(0x40, 0x44, 0x4B)); @@ -370,7 +378,7 @@ mod grid { let region = self.visible_region(frame.size()); - for cell in region.view(self.state.cells()) { + for cell in region.cull(self.state.cells()) { frame.fill_rectangle( Point::new(cell.j as f32, cell.i as f32), Size::UNIT, @@ -405,7 +413,44 @@ mod grid { frame.into_geometry() }; - vec![life, hovered_cell] + if self.scaling < 0.2 { + vec![life, hovered_cell] + } else { + let grid = self.grid_cache.draw(bounds.size(), |frame| { + frame.translate(center); + frame.scale(self.scaling); + frame.translate(self.translation); + frame.scale(Cell::SIZE as f32); + + let region = self.visible_region(frame.size()); + let rows = region.rows(); + let columns = region.columns(); + let (total_rows, total_columns) = + (rows.clone().count(), columns.clone().count()); + let width = 2.0 / Cell::SIZE as f32; + let color = Color::from_rgb8(70, 74, 83); + + frame.translate(Vector::new(-width / 2.0, -width / 2.0)); + + for row in region.rows() { + frame.fill_rectangle( + Point::new(*columns.start() as f32, row as f32), + Size::new(total_columns as f32, width), + color, + ); + } + + for column in region.columns() { + frame.fill_rectangle( + Point::new(column as f32, *rows.start() as f32), + Size::new(width, total_rows as f32), + color, + ); + } + }); + + vec![life, grid, hovered_cell] + } } fn mouse_interaction( @@ -583,20 +628,30 @@ mod grid { } impl Region { - fn view<'a>( - &self, - cells: impl Iterator<Item = &'a Cell>, - ) -> impl Iterator<Item = &'a Cell> { + fn rows(&self) -> RangeInclusive<isize> { let first_row = (self.y / Cell::SIZE as f32).floor() as isize; - let first_column = (self.x / Cell::SIZE as f32).floor() as isize; let visible_rows = (self.height / Cell::SIZE as f32).ceil() as isize; + + first_row..=first_row + visible_rows + } + + fn columns(&self) -> RangeInclusive<isize> { + let first_column = (self.x / Cell::SIZE as f32).floor() as isize; + let visible_columns = (self.width / Cell::SIZE as f32).ceil() as isize; - let rows = first_row..=first_row + visible_rows; - let columns = first_column..=first_column + visible_columns; + first_column..=first_column + visible_columns + } + + fn cull<'a>( + &self, + cells: impl Iterator<Item = &'a Cell>, + ) -> impl Iterator<Item = &'a Cell> { + let rows = self.rows(); + let columns = self.columns(); cells.filter(move |cell| { rows.contains(&cell.i) && columns.contains(&cell.j) |