From 50f94820a5c97f0a1125ea18a88d63cafb414575 Mon Sep 17 00:00:00 2001 From: Jean-Marie Mineau Date: Fri, 14 May 2021 00:13:46 +0200 Subject: [PATCH] use a more compact memory rep --- Cargo.toml | 1 + src/lib.rs | 80 ++++++++++++++++++++++++------------------------------ www | 2 +- 3 files changed, 38 insertions(+), 45 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 706d514..945821a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,7 @@ crate-type = ["cdylib", "rlib"] default = ["console_error_panic_hook"] [dependencies] +fixedbitset = "0.4.0" js-sys = "0.3" wasm-bindgen = "0.2.63" diff --git a/src/lib.rs b/src/lib.rs index 74f0a2c..79ba38b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,9 +1,12 @@ mod utils; +extern crate js_sys; +extern crate fixedbitset; + use std::fmt; use wasm_bindgen::prelude::*; +use fixedbitset::FixedBitSet; -extern crate js_sys; // When the `wee_alloc` feature is enabled, use `wee_alloc` as the global // allocator. @@ -21,19 +24,11 @@ pub fn greet(name: &str) { alert(&format!("Hello, {name}!", name=name)) } -#[wasm_bindgen] -#[repr(u8)] -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub enum Cell { - Dead = 0, - Alive = 1, -} - #[wasm_bindgen] pub struct Universe { width: u32, height: u32, - cells: Vec, + cells: FixedBitSet, } impl Universe{ @@ -69,14 +64,13 @@ impl Universe { let i = self.get_index(row, col); let cell = self.cells[i]; let live_neighbor = self.live_neighbor_count(row, col); - let next_cell = match (cell, live_neighbor){ - (Cell::Alive, x) if x < 2 => Cell::Dead, - (Cell::Alive, 2) | (Cell::Alive, 3) => Cell::Alive, - (Cell::Alive, x) if x > 3 => Cell::Dead, - (Cell::Dead, 3) => Cell::Alive, + next.set(i, match (cell, live_neighbor){ + (true, x) if x < 2 => false, + (true, 2) | (true, 3) => true, + (true, x) if x > 3 => false, + (false, 3) => true, (other, _) => other, - }; - next[i] = next_cell; + }); } } self.cells = next; @@ -85,16 +79,13 @@ impl Universe { pub fn new() -> Universe { let width = 64; let height = 64; + let size = (width * height) as usize; - let cells = (0..width * height) - .map(|i| { - if i % 2 == 0 || i % 7 == 0 { - Cell::Alive - } else { - Cell::Dead - } - }) - .collect(); + let mut cells = FixedBitSet::with_capacity(size); + + for i in 0..size { + cells.set(i, i % 2 == 0 || i % 7 == 0); + } Universe { width, @@ -106,16 +97,13 @@ impl Universe { pub fn new_random() -> Universe { let width = 64; let height = 64; + let size = (width * height) as usize; - let cells = (0..width * height) - .map(|_i| { - if js_sys::Math::random() < 0.5 { - Cell::Alive - } else { - Cell::Dead - } - }) - .collect(); + let mut cells = FixedBitSet::with_capacity(size); + + for i in 0..size { + cells.set(i, js_sys::Math::random() < 0.5); + } Universe { width, @@ -127,16 +115,19 @@ impl Universe { pub fn new_space_ship() -> Universe { let width : u32 = 64; let height : u32 = 64; + let size = (width * height) as usize; - let mut cells : Vec = (0..width * height) - .map(|_i| { Cell::Dead }) - .collect(); + let mut cells = FixedBitSet::with_capacity(size); + + for i in 0..size { + cells.set(i, false); + } let x0 = 32; let y0 = 32; for (x, y) in [(0, 2), (1, 0), (1, 2), (2, 1), (2, 2)].iter().cloned() { let i = ((y0 + y) * width + x0 + x) as usize; - cells[i] = Cell::Alive; + cells.set(i, true); } Universe { @@ -158,16 +149,17 @@ impl Universe { self.height } - pub fn cells(&self) -> *const Cell { - self.cells.as_ptr() + pub fn cells(&self) -> *const u32 { + self.cells.as_slice().as_ptr() } } impl fmt::Display for Universe { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - for line in self.cells.as_slice().chunks(self.width as usize) { - for &cell in line { - let symbole = if cell == Cell::Dead { '◻' } else { '◼' }; + for row in 0..self.height { + for col in 0..self.width { + let i = self.get_index(row, col); + let symbole = if self.cells[i] { '◻' } else { '◼' }; write!(f, "{}", symbole)?; } write!(f, "\n")?; diff --git a/www b/www index b0799ea..f6fa275 160000 --- a/www +++ b/www @@ -1 +1 @@ -Subproject commit b0799ea316d590cd432fee5f53914287e2a328d6 +Subproject commit f6fa2759a6dce5379554d7294f00487bb1565004