use a more compact memory rep

This commit is contained in:
histausse 2021-05-14 00:13:46 +02:00
parent 40c026f32a
commit 50f94820a5
Signed by: histausse
GPG key ID: 67486F107F62E9E9
3 changed files with 38 additions and 45 deletions

View file

@ -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"

View file

@ -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<Cell>,
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<Cell> = (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")?;

2
www

@ -1 +1 @@
Subproject commit b0799ea316d590cd432fee5f53914287e2a328d6
Subproject commit f6fa2759a6dce5379554d7294f00487bb1565004