#![recursion_limit="256"]
#![feature(alloc)]
#![feature(drain_filter)]
#![feature(get_mut_unchecked)]
#![allow(warnings)]
extern crate wasm_bindgen;
extern crate hashbrown;
#[macro_use]
extern crate alloc;
extern crate core;
extern crate web_sys;
extern crate mech_core;
extern crate mech_utilities;
extern crate bincode;
#[macro_use]
extern crate lazy_static;
extern crate miniz_oxide;
extern crate base64;
use base64::{encode, decode};
use miniz_oxide::inflate::decompress_to_vec;
use miniz_oxide::deflate::compress_to_vec;
use std::collections::HashMap;
use std::collections::hash_map::Entry;
use std::cell::Cell;
use std::cell::RefCell;
use std::rc::Rc;
use wasm_bindgen::prelude::*;
use wasm_bindgen::JsCast;
use hashbrown::hash_set::HashSet;
use alloc::vec::Vec;
use core::fmt;
use mech_core::*;
use mech_utilities::{SocketMessage, MiniBlock};
use web_sys::{ErrorEvent, MessageEvent, WebSocket, FileReader};
use std::sync::Arc;
pub mod shapes;
pub mod elements;
pub use self::shapes::*;
pub use self::elements::*;
static PI: f64 = 3.14159265358979323846264338327950288;
#[macro_export]
macro_rules! log {
( $( $t:tt )* ) => {
web_sys::console::log_1(&format!( $( $t )* ).into());
}
}
lazy_static! {
pub static ref HTML_APP: u64 = hash_str("html/app");
pub static ref DIV: u64 = hash_str("div");
pub static ref A: u64 = hash_str("a");
pub static ref IMG: u64 = hash_str("img");
pub static ref SRC: u64 = hash_str("src");
pub static ref CONTAINS: u64 = hash_str("contains");
pub static ref ROOT: u64 = hash_str("root");
pub static ref TYPE: u64 = hash_str("type");
pub static ref KIND: u64 = hash_str("kind");
pub static ref HREF: u64 = hash_str("href");
pub static ref BUTTON: u64 = hash_str("button");
pub static ref SLIDER: u64 = hash_str("slider");
pub static ref MIN: u64 = hash_str("min");
pub static ref MAX: u64 = hash_str("max");
pub static ref VALUE: u64 = hash_str("value");
pub static ref CANVAS: u64 = hash_str("canvas");
pub static ref PARAMETERS: u64 = hash_str("parameters");
pub static ref HEIGHT: u64 = hash_str("height");
pub static ref WIDTH: u64 = hash_str("width");
pub static ref SHAPE: u64 = hash_str("shape");
pub static ref CIRCLE: u64 = hash_str("circle");
pub static ref RECTANGLE: u64 = hash_str("rectangle");
pub static ref LINE: u64 = hash_str("line");
pub static ref PATH: u64 = hash_str("path");
pub static ref START__POINT: u64 = hash_str("start-point");
pub static ref LINE__WIDTH: u64 = hash_str("line-width");
pub static ref START__ANGLE: u64 = hash_str("start-angle");
pub static ref END__ANGLE: u64 = hash_str("end-angle");
pub static ref QUADRATIC: u64 = hash_str("quadratic");
pub static ref CONTROL__POINT: u64 = hash_str("control-point");
pub static ref CONTROL__POINTS: u64 = hash_str("control-points");
pub static ref END__POINT: u64 = hash_str("end-point");
pub static ref X1: u64 = hash_str("x1");
pub static ref X2: u64 = hash_str("x2");
pub static ref Y1: u64 = hash_str("y1");
pub static ref Y2: u64 = hash_str("y2");
pub static ref RADIUS: u64 = hash_str("radius");
pub static ref STROKE: u64 = hash_str("stroke");
pub static ref FILL: u64 = hash_str("fill");
pub static ref CENTER__X: u64 = hash_str("center-x");
pub static ref CENTER__Y: u64 = hash_str("center-y");
pub static ref IMAGE: u64 = hash_str("image");
pub static ref X: u64 = hash_str("x");
pub static ref Y: u64 = hash_str("y");
pub static ref ROTATE: u64 = hash_str("rotate");
pub static ref TRANSLATE: u64 = hash_str("translate");
pub static ref SOURCE: u64 = hash_str("source");
pub static ref TIME_TIMER: u64 = hash_str("time/timer");
pub static ref PERIOD: u64 = hash_str("period");
pub static ref TICKS: u64 = hash_str("ticks");
pub static ref HTML_EVENT_POINTER__MOVE: u64 = hash_str("html/event/pointer-move");
pub static ref HTML_EVENT_POINTER__DOWN: u64 = hash_str("html/event/pointer-down");
pub static ref HTML_EVENT_POINTER__UP: u64 = hash_str("html/event/pointer-up");
pub static ref HTML_EVENT_KEY__DOWN: u64 = hash_str("html/event/key-down");
pub static ref HTML_EVENT_KEY__UP: u64 = hash_str("html/event/key-up");
pub static ref TARGET: u64 = hash_str("target");
pub static ref KEY: u64 = hash_str("key");
pub static ref EVENT__ID: u64 = hash_str("event-id");
pub static ref ARC: u64 = hash_str("arc");
pub static ref ELLIPSE: u64 = hash_str("ellipse");
pub static ref MAJOR__AXIS: u64 = hash_str("major-axis");
pub static ref MINOR__AXIS: u64 = hash_str("minor-axis");
pub static ref STARTING__ANGLE: u64 = hash_str("starting-angle");
pub static ref ENDING__ANGLE: u64 = hash_str("ending-angle");
pub static ref TEXT: u64 = hash_str("text");
pub static ref FONT: u64 = hash_str("font");
pub static ref SIZE: u64 = hash_str("size");
pub static ref FACE: u64 = hash_str("face");
pub static ref STYLE: u64 = hash_str("style");
pub static ref WEIGHT: u64 = hash_str("weight");
pub static ref BOLD: u64 = hash_str("bold");
pub static ref NORMAL: u64 = hash_str("normal");
pub static ref ITALIC: u64 = hash_str("italic");
pub static ref FAMILY: u64 = hash_str("family");
pub static ref DIRECTION: u64 = hash_str("direction");
pub static ref ALIGNMENT: u64 = hash_str("alignment");
pub static ref START: u64 = hash_str("start");
pub static ref END: u64 = hash_str("end");
pub static ref LEFT: u64 = hash_str("left");
pub static ref RIGHT: u64 = hash_str("right");
pub static ref CENTER: u64 = hash_str("center");
pub static ref BEZIER: u64 = hash_str("bezier");
pub static ref HTML_LOCATION: u64 = hash_str("html/location");
pub static ref HASH: u64 = hash_str("hash");
pub static ref HOST: u64 = hash_str("host");
pub static ref HOST__NAME: u64 = hash_str("host-name");
pub static ref ORIGIN: u64 = hash_str("origin");
pub static ref PATH__NAME: u64 = hash_str("path-name");
pub static ref PORT: u64 = hash_str("port");
pub static ref PROTOCOL: u64 = hash_str("protocol");
pub static ref SEARCH: u64 = hash_str("search");
pub static ref SCALE: u64 = hash_str("scale");
}
pub fn render_value(value: Value, document: &web_sys::Document, core: &mech_core::Core) -> Result<web_sys::Element, JsValue> {
let mut div = document.create_element("div")?;
match value {
Value::String(chars) => {
let contents_string = chars.to_string();
div.set_inner_html(&contents_string);
},
Value::F32(x) => div.set_inner_html(&format!("{:.2?}", x)),
Value::F64(x) => div.set_inner_html(&format!("{:?}", x)),
Value::U128(x) => div.set_inner_html(&format!("{:?}", x)),
Value::U64(x) => div.set_inner_html(&format!("{:?}", x)),
Value::U32(x) => div.set_inner_html(&format!("{:?}", x)),
Value::U16(x) => div.set_inner_html(&format!("{:?}", x)),
Value::U8(x) => div.set_inner_html(&format!("{:?}", x)),
Value::I128(x) => div.set_inner_html(&format!("{:?}", x)),
Value::I64(x) => div.set_inner_html(&format!("{:?}", x)),
Value::I32(x) => div.set_inner_html(&format!("{:?}", x)),
Value::I16(x) => div.set_inner_html(&format!("{:?}", x)),
Value::I8(x) => div.set_inner_html(&format!("{:?}", x)),
Value::Reference(TableId::Global(table_id)) => {
let table = core.get_table_by_id(table_id).unwrap();
let rendered_ref = make_element(&table.borrow(), document, core)?;
div.append_child(&rendered_ref)?;
}
x => log!("4745 {:?}",x),
}
Ok(div)
}
pub fn draw_canvas(canvas: &web_sys::HtmlCanvasElement, core: &mech_core::Core) -> Result<(), JsValue> {
let context = canvas
.get_context("2d")
.unwrap()
.unwrap()
.dyn_into::<web_sys::CanvasRenderingContext2d>()
.unwrap();
let elements_table_id_string = canvas.get_attribute("elements").unwrap();
let elements_table_id: u64 = elements_table_id_string.parse::<u64>().unwrap();
let elements_table = core.get_table_by_id(elements_table_id).unwrap();
let elements_table_brrw = elements_table.borrow();
let context = Rc::new(context);
context.clear_rect(0.0, 0.0, canvas.width().into(), canvas.height().into());
for row in 1..=elements_table_brrw.rows as usize {
match (elements_table_brrw.get(&TableIndex::Index(row), &TableIndex::Alias(*SHAPE)),
elements_table_brrw.get(&TableIndex::Index(row), &TableIndex::Alias(*PARAMETERS))) {
(Ok(Value::String(shape)), Ok(Value::Reference(parameters_table_id))) => {
let shape = shape.hash();
let parameters_table = core.get_table_by_id(*parameters_table_id.unwrap()).unwrap();
if shape == *CIRCLE { render_circle(parameters_table,&context)?; }
else if shape == *ELLIPSE { render_ellipse(parameters_table,&context)?; }
else if shape == *ARC { render_arc(parameters_table,&context)?; }
else if shape == *RECTANGLE { render_rectangle(parameters_table,&context)?; }
else if shape == *TEXT { render_text(parameters_table,&context,core)?; }
else if shape == *PATH { render_path(parameters_table,&context,core)?; }
else if shape == *IMAGE { render_image(parameters_table,&context,core)?; }
else {
log!("5869");
}
},
x => {log!("5870 {:?}", x);},
}
}
Ok(())
}
pub fn make_element(table: &Table, document: &web_sys::Document, core: &mech_core::Core) -> Result<web_sys::Element, JsValue> {
let mut container: web_sys::Element = document.create_element("div")?;
let element_id = hash_str(&format!("div-{:?}", table.id));
container.set_id(&format!("{:?}",element_id));
container.set_attribute("table-id", &format!("{}", table.id))?;
match table.col_map.get_index(&*KIND) {
Ok(_) => {
for row in 1..=table.rows {
match table.get(&TableIndex::Index(row), &TableIndex::Alias(*KIND)) {
Ok(Value::String(kind)) => {
let raw_kind = kind.hash();
if raw_kind == *DIV { render_div(table,&mut container, document, core)?; }
else if raw_kind == *A { render_link(table,&mut container, document, core)?; }
else if raw_kind == *IMG { render_img(table,&mut container,document, core)?; }
else if raw_kind == *BUTTON { render_button(table, &mut container, document, core)?; }
else if raw_kind == *SLIDER { render_slider(table, &mut container, document, core)?; }
else if raw_kind == *CANVAS { render_canvas(table, &mut container, document, core)?; }
else {
log!("4744 {:?}", raw_kind);
}
}
x => log!("4745 {:?}",x),
Err(x) => log!("4746 {:?}",x),
}
}
}
Err(_) => {
for row in 1..=table.rows {
let mut row_div = document.create_element("div")?;
let element_id = hash_str(&format!("div-{:?}-{:?}", table.id, row));
row_div.set_id(&format!("{:?}",element_id));
for column in 1..=table.cols {
match table.get(&TableIndex::Index(row), &TableIndex::Index(column)) {
Ok(contents) => {
let mut cell_div = document.create_element("div")?;
let element_id = hash_str(&format!("div-{:?}-{:?}-{:?}", table.id, row, column));
let rendered = render_value(contents, document, core)?;
rendered.set_id(&format!("{:?}",element_id));
row_div.append_child(&rendered)?;
}
x => log!("4747 {:?}",x),
}
}
container.append_child(&row_div)?;
}
}
}
Ok(container)
}