use a more compact memory rep
This commit is contained in:
parent
40c026f32a
commit
50f94820a5
3 changed files with 38 additions and 45 deletions
|
@ -11,6 +11,7 @@ crate-type = ["cdylib", "rlib"]
|
||||||
default = ["console_error_panic_hook"]
|
default = ["console_error_panic_hook"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
fixedbitset = "0.4.0"
|
||||||
js-sys = "0.3"
|
js-sys = "0.3"
|
||||||
wasm-bindgen = "0.2.63"
|
wasm-bindgen = "0.2.63"
|
||||||
|
|
||||||
|
|
76
src/lib.rs
76
src/lib.rs
|
@ -1,9 +1,12 @@
|
||||||
mod utils;
|
mod utils;
|
||||||
|
|
||||||
|
extern crate js_sys;
|
||||||
|
extern crate fixedbitset;
|
||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use wasm_bindgen::prelude::*;
|
use wasm_bindgen::prelude::*;
|
||||||
|
use fixedbitset::FixedBitSet;
|
||||||
|
|
||||||
extern crate js_sys;
|
|
||||||
|
|
||||||
// When the `wee_alloc` feature is enabled, use `wee_alloc` as the global
|
// When the `wee_alloc` feature is enabled, use `wee_alloc` as the global
|
||||||
// allocator.
|
// allocator.
|
||||||
|
@ -21,19 +24,11 @@ pub fn greet(name: &str) {
|
||||||
alert(&format!("Hello, {name}!", name=name))
|
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]
|
#[wasm_bindgen]
|
||||||
pub struct Universe {
|
pub struct Universe {
|
||||||
width: u32,
|
width: u32,
|
||||||
height: u32,
|
height: u32,
|
||||||
cells: Vec<Cell>,
|
cells: FixedBitSet,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Universe{
|
impl Universe{
|
||||||
|
@ -69,14 +64,13 @@ impl Universe {
|
||||||
let i = self.get_index(row, col);
|
let i = self.get_index(row, col);
|
||||||
let cell = self.cells[i];
|
let cell = self.cells[i];
|
||||||
let live_neighbor = self.live_neighbor_count(row, col);
|
let live_neighbor = self.live_neighbor_count(row, col);
|
||||||
let next_cell = match (cell, live_neighbor){
|
next.set(i, match (cell, live_neighbor){
|
||||||
(Cell::Alive, x) if x < 2 => Cell::Dead,
|
(true, x) if x < 2 => false,
|
||||||
(Cell::Alive, 2) | (Cell::Alive, 3) => Cell::Alive,
|
(true, 2) | (true, 3) => true,
|
||||||
(Cell::Alive, x) if x > 3 => Cell::Dead,
|
(true, x) if x > 3 => false,
|
||||||
(Cell::Dead, 3) => Cell::Alive,
|
(false, 3) => true,
|
||||||
(other, _) => other,
|
(other, _) => other,
|
||||||
};
|
});
|
||||||
next[i] = next_cell;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.cells = next;
|
self.cells = next;
|
||||||
|
@ -85,16 +79,13 @@ impl Universe {
|
||||||
pub fn new() -> Universe {
|
pub fn new() -> Universe {
|
||||||
let width = 64;
|
let width = 64;
|
||||||
let height = 64;
|
let height = 64;
|
||||||
|
let size = (width * height) as usize;
|
||||||
|
|
||||||
let cells = (0..width * height)
|
let mut cells = FixedBitSet::with_capacity(size);
|
||||||
.map(|i| {
|
|
||||||
if i % 2 == 0 || i % 7 == 0 {
|
for i in 0..size {
|
||||||
Cell::Alive
|
cells.set(i, i % 2 == 0 || i % 7 == 0);
|
||||||
} else {
|
|
||||||
Cell::Dead
|
|
||||||
}
|
}
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
Universe {
|
Universe {
|
||||||
width,
|
width,
|
||||||
|
@ -106,16 +97,13 @@ impl Universe {
|
||||||
pub fn new_random() -> Universe {
|
pub fn new_random() -> Universe {
|
||||||
let width = 64;
|
let width = 64;
|
||||||
let height = 64;
|
let height = 64;
|
||||||
|
let size = (width * height) as usize;
|
||||||
|
|
||||||
let cells = (0..width * height)
|
let mut cells = FixedBitSet::with_capacity(size);
|
||||||
.map(|_i| {
|
|
||||||
if js_sys::Math::random() < 0.5 {
|
for i in 0..size {
|
||||||
Cell::Alive
|
cells.set(i, js_sys::Math::random() < 0.5);
|
||||||
} else {
|
|
||||||
Cell::Dead
|
|
||||||
}
|
}
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
Universe {
|
Universe {
|
||||||
width,
|
width,
|
||||||
|
@ -127,16 +115,19 @@ impl Universe {
|
||||||
pub fn new_space_ship() -> Universe {
|
pub fn new_space_ship() -> Universe {
|
||||||
let width : u32 = 64;
|
let width : u32 = 64;
|
||||||
let height : u32 = 64;
|
let height : u32 = 64;
|
||||||
|
let size = (width * height) as usize;
|
||||||
|
|
||||||
let mut cells : Vec<Cell> = (0..width * height)
|
let mut cells = FixedBitSet::with_capacity(size);
|
||||||
.map(|_i| { Cell::Dead })
|
|
||||||
.collect();
|
for i in 0..size {
|
||||||
|
cells.set(i, false);
|
||||||
|
}
|
||||||
|
|
||||||
let x0 = 32;
|
let x0 = 32;
|
||||||
let y0 = 32;
|
let y0 = 32;
|
||||||
for (x, y) in [(0, 2), (1, 0), (1, 2), (2, 1), (2, 2)].iter().cloned() {
|
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;
|
let i = ((y0 + y) * width + x0 + x) as usize;
|
||||||
cells[i] = Cell::Alive;
|
cells.set(i, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
Universe {
|
Universe {
|
||||||
|
@ -158,16 +149,17 @@ impl Universe {
|
||||||
self.height
|
self.height
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cells(&self) -> *const Cell {
|
pub fn cells(&self) -> *const u32 {
|
||||||
self.cells.as_ptr()
|
self.cells.as_slice().as_ptr()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for Universe {
|
impl fmt::Display for Universe {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
for line in self.cells.as_slice().chunks(self.width as usize) {
|
for row in 0..self.height {
|
||||||
for &cell in line {
|
for col in 0..self.width {
|
||||||
let symbole = if cell == Cell::Dead { '◻' } else { '◼' };
|
let i = self.get_index(row, col);
|
||||||
|
let symbole = if self.cells[i] { '◻' } else { '◼' };
|
||||||
write!(f, "{}", symbole)?;
|
write!(f, "{}", symbole)?;
|
||||||
}
|
}
|
||||||
write!(f, "\n")?;
|
write!(f, "\n")?;
|
||||||
|
|
2
www
2
www
|
@ -1 +1 @@
|
||||||
Subproject commit b0799ea316d590cd432fee5f53914287e2a328d6
|
Subproject commit f6fa2759a6dce5379554d7294f00487bb1565004
|
Loading…
Reference in a new issue