More WASM bindgen glue, World::draw()

main
Shad Amethyst 2 years ago
parent fca68918e4
commit 0d3e4f7d15
Signed by: amethyst
GPG Key ID: D970C8DD1D6DEE36

@ -1,8 +1,8 @@
mod utils;
use js_sys::Function;
use serde::{Deserialize, Serialize};
use wasm_bindgen::prelude::*;
use js_sys::Function;
use stackline::pane::Pane as SLPane;
use stackline::signal::Signal as SLSignal;
@ -11,6 +11,7 @@ use stackline::tile::AnyTile;
use stackline::tile::FullTile as SLFullTile;
use stackline::utils::Direction;
use stackline::world::World as SLWorld;
use stackline::text::TextSurface;
// When the `wee_alloc` feature is enabled, use `wee_alloc` as the global
// allocator.
@ -33,9 +34,10 @@ pub fn set_panic() {
#[wasm_bindgen]
pub fn available_tiles() -> Vec<JsValue> {
AnyTile::available().iter().map(|name| {
JsValue::from_str(name)
}).collect()
AnyTile::available()
.iter()
.map(|name| JsValue::from_str(name))
.collect()
}
#[wasm_bindgen]
@ -66,9 +68,11 @@ impl World {
self.0.get((x, y)).map(|tile| FullTile((*tile).clone()))
}
pub fn set(&mut self, x: i32, y: i32, tile: &FullTile) {
pub fn set(&mut self, x: i32, y: i32, tile: FullTile) {
if let Some(tile_ref) = self.0.get_mut((x, y)) {
*tile_ref = tile.0.clone();
*tile_ref = tile.0;
} else if cfg!(debug_assertions) {
err!("Index out of bound: {}:{}", x, y);
}
}
@ -79,6 +83,37 @@ impl World {
pub fn set_pane(&mut self, name: String, pane: Pane) {
self.0.set_pane(name, pane.0);
}
pub fn panes(&self) -> Vec<JsValue> {
self.0.panes().keys().map(|key| {
JsValue::from_str(key)
}).collect()
}
pub fn draw(&self, x: i32, y: i32, width: usize, height: usize) -> Vec<u32> {
let mut surface = TextSurface::new(width, height);
self.0.draw(x, y, &mut surface);
#[derive(Serialize)]
struct Char {
ch: char,
fg: (u8, u8, u8),
bg: Option<(u8, u8, u8)>,
}
fn to_u32(red: u8, green: u8, blue: u8) -> u32 {
0xff000000 | (red as u32).checked_shl(16).unwrap() | (green as u32).checked_shl(8).unwrap() | (blue as u32)
}
surface.iter().map(|ch| {
vec![
ch.ch as u32,
to_u32(ch.fg.red, ch.fg.green, ch.fg.blue),
ch.bg.map(|bg| to_u32(bg.red, bg.green, bg.blue)).unwrap_or(0)
].into_iter()
}).flatten().collect::<Vec<_>>()
}
}
#[wasm_bindgen]
@ -111,6 +146,16 @@ impl Pane {
vec![x, y]
}
#[wasm_bindgen(getter)]
pub fn x(&self) -> i32 {
self.0.position().0
}
#[wasm_bindgen(getter)]
pub fn y(&self) -> i32 {
self.0.position().1
}
#[wasm_bindgen(setter)]
pub fn set_position(&mut self, position: &[i32]) {
if let [x, y] = position[..] {
@ -151,11 +196,17 @@ impl FullTile {
#[wasm_bindgen(getter)]
pub fn tile(&self) -> JsValue {
self.0.get().map(|tile| {
JsValue::from_serde(tile).map_err(|err| {
err!("Error while serializing AnyTile: {}", err);
}).ok()
}).flatten().unwrap_or(JsValue::UNDEFINED)
self.0
.get()
.map(|tile| {
JsValue::from_serde(tile)
.map_err(|err| {
err!("Error while serializing AnyTile: {}", err);
})
.ok()
})
.flatten()
.unwrap_or(JsValue::UNDEFINED)
}
#[wasm_bindgen(setter)]
@ -170,8 +221,36 @@ impl FullTile {
}
}
pub fn schema(&self) -> JsValue {
use serde_json::Value;
use stackline::tile::{Tile, TileSchema};
fn construct_value(schema: TileSchema) -> Value {
match schema {
TileSchema::Tuple(arr) => {
Value::Array(arr.into_iter().map(construct_value).collect())
}
TileSchema::Map(map) => Value::Object(
map.into_iter()
.map(|(key, value)| (key, construct_value(value)))
.collect(),
),
TileSchema::Value(string) => Value::String(string),
}
}
if let Some(tile) = self.0.get() {
JsValue::from_serde(&construct_value(tile.schema()))
.expect("Error while serializing TileSchema")
} else {
JsValue::UNDEFINED
}
}
pub fn map_tile(&mut self, callback: &Function) {
let res = callback.call1(&JsValue::NULL, &self.tile()).expect("Error while calling javascript callback");
let res = callback
.call1(&JsValue::NULL, &self.tile())
.expect("Error while calling javascript callback");
self.set_tile(res);
}
}

Loading…
Cancel
Save