Browse Source

Split example app from emigui_wasm

pull/1/head
Emil Ernerfeldt 6 years ago
parent
commit
1beed16053
  1. 13
      Cargo.lock
  2. 1
      Cargo.toml
  3. 2
      build.sh
  4. BIN
      docs/emigui_wasm_bg.wasm
  5. 121
      docs/example.js
  6. BIN
      docs/example_bg.wasm
  7. 22
      docs/index.html
  8. 74
      emigui_wasm/src/lib.rs
  9. 33
      example/Cargo.toml
  10. 2
      example/src/app.rs
  11. 79
      example/src/lib.rs

13
Cargo.lock

@ -107,6 +107,19 @@ dependencies = [
"termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "example"
version = "0.1.0"
dependencies = [
"emigui 0.1.0",
"emigui_wasm 0.1.0",
"js-sys 0.3.10 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.87 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)",
"wasm-bindgen 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
"web-sys 0.3.10 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "failure"
version = "0.1.5"

1
Cargo.toml

@ -2,6 +2,7 @@
members = [
"emigui",
"emigui_wasm",
"example",
]
# Optimize for small code size:

2
build.sh

@ -22,7 +22,7 @@ function build_rust
echo "Generate JS bindings for wasm:"
FOLDER_NAME=${PWD##*/}
TARGET_NAME="emigui_wasm.wasm"
TARGET_NAME="example.wasm"
wasm-bindgen "target/wasm32-unknown-unknown/$BUILD/$TARGET_NAME" \
--out-dir docs --no-modules --no-typescript
# --no-modules-global hoboho

BIN
docs/emigui_wasm_bg.wasm

Binary file not shown.

121
docs/emigui_wasm.js → docs/example.js

@ -331,20 +331,20 @@ __exports.__widl_f_performance_Window = function(arg0) {
};
__exports.__wbg_new_12b9ae8fdb332911 = function(arg0) {
__exports.__wbg_new_f49b071a6847bcff = function(arg0) {
return addHeapObject(new Float32Array(getObject(arg0)));
};
__exports.__wbg_subarray_1c02edccacdc6b96 = function(arg0, arg1, arg2) {
__exports.__wbg_subarray_f8934b42fec7ca7c = function(arg0, arg1, arg2) {
return addHeapObject(getObject(arg0).subarray(arg1, arg2));
};
__exports.__wbg_newnoargs_970ffcd96c15d34e = function(arg0, arg1) {
__exports.__wbg_newnoargs_43c5f57b77232284 = function(arg0, arg1) {
let varg0 = getStringFromWasm(arg0, arg1);
return addHeapObject(new Function(varg0));
};
__exports.__wbg_call_6ecd167e59b01396 = function(arg0, arg1, exnptr) {
__exports.__wbg_call_7ac13208e630ddeb = function(arg0, arg1, exnptr) {
try {
return addHeapObject(getObject(arg0).call(getObject(arg1)));
} catch (e) {
@ -355,35 +355,35 @@ __exports.__wbg_call_6ecd167e59b01396 = function(arg0, arg1, exnptr) {
}
};
__exports.__wbg_new_24372bdd16e7ac17 = function(arg0) {
__exports.__wbg_new_efed94c530925533 = function(arg0) {
return addHeapObject(new Int16Array(getObject(arg0)));
};
__exports.__wbg_subarray_333aec38f24ecc8c = function(arg0, arg1, arg2) {
__exports.__wbg_subarray_b6e319a511351c70 = function(arg0, arg1, arg2) {
return addHeapObject(getObject(arg0).subarray(arg1, arg2));
};
__exports.__wbg_new_4e991c7c717b13c1 = function(arg0) {
__exports.__wbg_new_a999fd72f5304154 = function(arg0) {
return addHeapObject(new Uint8Array(getObject(arg0)));
};
__exports.__wbg_subarray_0de502469162fe71 = function(arg0, arg1, arg2) {
__exports.__wbg_subarray_1cd21da1682e7d1e = function(arg0, arg1, arg2) {
return addHeapObject(getObject(arg0).subarray(arg1, arg2));
};
__exports.__wbg_new_ebb3136fdb1b1152 = function(arg0) {
__exports.__wbg_new_12076896685e5e56 = function(arg0) {
return addHeapObject(new Uint16Array(getObject(arg0)));
};
__exports.__wbg_subarray_acb28098200224ff = function(arg0, arg1, arg2) {
__exports.__wbg_subarray_a860cdd7b04efc31 = function(arg0, arg1, arg2) {
return addHeapObject(getObject(arg0).subarray(arg1, arg2));
};
__exports.__wbg_instanceof_Memory_48643a8591466d1a = function(idx) {
__exports.__wbg_instanceof_Memory_ed5a1f7b9a0e05a3 = function(idx) {
return getObject(idx) instanceof WebAssembly.Memory ? 1 : 0;
};
__exports.__wbg_buffer_74e21c76ddf2eb17 = function(arg0) {
__exports.__wbg_buffer_efdca35786c3eb75 = function(arg0) {
return addHeapObject(getObject(arg0).buffer);
};
@ -403,21 +403,6 @@ __exports.__wbindgen_string_new = function(p, l) {
return addHeapObject(getStringFromWasm(p, l));
};
__exports.__wbindgen_number_get = function(n, invalid) {
let obj = getObject(n);
if (typeof(obj) === 'number') return obj;
getUint8Memory()[invalid] = 1;
return 0;
};
__exports.__wbindgen_is_null = function(idx) {
return getObject(idx) === null ? 1 : 0;
};
__exports.__wbindgen_is_undefined = function(idx) {
return getObject(idx) === undefined ? 1 : 0;
};
__exports.__wbindgen_boolean_get = function(i) {
let v = getObject(i);
if (typeof(v) === 'boolean') {
@ -427,16 +412,78 @@ __exports.__wbindgen_boolean_get = function(i) {
}
};
__exports.__wbindgen_is_symbol = function(i) {
return typeof(getObject(i)) === 'symbol' ? 1 : 0;
__exports.__wbindgen_debug_string = function(i, len_ptr) {
const toString = Object.prototype.toString;
const debug_str = val => {
// primitive types
const type = typeof val;
if (type == 'number' || type == 'boolean' || val == null) {
return `${val}`;
}
if (type == 'string') {
return `"${val}"`;
}
if (type == 'symbol') {
const description = val.description;
if (description == null) {
return 'Symbol';
} else {
return `Symbol(${description})`;
}
}
if (type == 'function') {
const name = val.name;
if (typeof name == 'string' && name.length > 0) {
return `Function(${name})`;
} else {
return 'Function';
}
}
// objects
if (Array.isArray(val)) {
const length = val.length;
let debug = '[';
if (length > 0) {
debug += debug_str(val[0]);
}
for(let i = 1; i < length; i++) {
debug += ', ' + debug_str(val[i]);
}
debug += ']';
return debug;
}
// Test for built-in
const builtInMatches = /\[object ([^\]]+)\]/.exec(toString.call(val));
let className;
if (builtInMatches.length > 1) {
className = builtInMatches[1];
} else {
// Failed to match the standard '[object ClassName]'
return toString.call(val);
}
if (className == 'Object') {
// we're a user defined class or Object
// JSON.stringify avoids problems with cycles, and is generally much
// easier than looping through ownProperties of `val`.
try {
return 'Object(' + JSON.stringify(val) + ')';
} catch (_) {
return 'Object';
}
}
// errors
if (val instanceof Error) {
return `${val.name}: ${val.message}
${val.stack}`;
}
// TODO we could test for more things here, like `Set`s and `Map`s.
return className;
};
__exports.__wbindgen_string_get = function(i, len_ptr) {
let obj = getObject(i);
if (typeof(obj) !== 'string') return 0;
const ptr = passStringToWasm(obj);
getUint32Memory()[len_ptr / 4] = WASM_VECTOR_LEN;
return ptr;
const val = getObject(i);
const debug = debug_str(val);
const ptr = passStringToWasm(debug);
getUint32Memory()[len_ptr / 4] = WASM_VECTOR_LEN;
return ptr;
};
__exports.__wbindgen_memory = function() { return addHeapObject(wasm.memory); };
@ -479,7 +526,7 @@ __exports.__wbindgen_throw = function(ptr, len) {
function init(path_or_module) {
let instantiation;
const imports = { './emigui_wasm': __exports };
const imports = { './example': __exports };
if (path_or_module instanceof WebAssembly.Module) {
instantiation = WebAssembly.instantiate(path_or_module, imports)
.then(instance => {

BIN
docs/example_bg.wasm

Binary file not shown.

22
docs/index.html

@ -39,26 +39,24 @@
// hack when deploying over HTTP.
delete WebAssembly.instantiateStreaming;
</script>
<!-- this is the JS generated by the `wasm-bindgen` CLI tool -->
<script src="emigui_wasm.js"></script>
<script src="example.js"></script>
<script>
// we'll defer our execution until the wasm is ready to go
function wasm_loaded() {
console.log("wasm loaded");
initialize();
}
// here we tell bindgen the path to the wasm file so it can start
// initialization and return to us a promise when it's done
wasm_bindgen("./emigui_wasm_bg.wasm")
.then(wasm_loaded)["catch"](console.error);
wasm_bindgen("./example_bg.wasm")
.then(on_wasm_loaded)["catch"](console.error);
// ----------------------------------------------------------------------------
var g_webgl_painter = null;
var g_wasm_app = null;
function paint_gui(canvas, input) {
if (g_webgl_painter === null) {
g_webgl_painter = wasm_bindgen.new_webgl_gui("canvas", pixels_per_point());
if (g_wasm_app === null) {
g_wasm_app = wasm_bindgen.new_webgl_gui("canvas", pixels_per_point());
}
wasm_bindgen.run_gui(g_webgl_painter, JSON.stringify(input));
wasm_bindgen.run_gui(g_wasm_app, JSON.stringify(input));
}
// ----------------------------------------------------------------------------
var g_mouse_pos = { x: -1000.0, y: -1000.0 };
@ -93,7 +91,7 @@
};
}
function initialize() {
function on_wasm_loaded() {
console.log("window.devicePixelRatio: " + window.devicePixelRatio);
var canvas = document.getElementById("canvas");
var repaint = function() {

74
emigui_wasm/src/lib.rs

@ -1,79 +1,7 @@
#![deny(warnings)]
extern crate serde_json;
extern crate wasm_bindgen;
extern crate emigui;
use emigui::{label, widgets::Label, Align, Emigui, RawInput};
use wasm_bindgen::prelude::*;
mod app;
mod webgl;
fn now_ms() -> f64 {
web_sys::window()
.expect("should have a Window")
.performance()
.expect("should have a Performance")
.now()
}
#[wasm_bindgen]
pub struct State {
app: app::App,
emigui: Emigui,
webgl_painter: webgl::Painter,
everything_ms: f64,
}
impl State {
fn new(canvas_id: &str, pixels_per_point: f32) -> Result<State, JsValue> {
Ok(State {
app: Default::default(),
emigui: Emigui::new(pixels_per_point),
webgl_painter: webgl::Painter::new(canvas_id)?,
everything_ms: 0.0,
})
}
fn run(&mut self, raw_input: RawInput) -> Result<(), JsValue> {
let everything_start = now_ms();
self.emigui.new_frame(raw_input);
let mut region = self.emigui.whole_screen_region();
let mut region = region.centered_column(region.width().min(480.0), Align::Min);
self.app.show_gui(&mut region);
self.emigui.example(&mut region);
region.add(label!("WebGl painter info:"));
region.indent(|region| {
region.add(label!(self.webgl_painter.debug_info()));
});
region.add(label!("Everything: {:.1} ms", self.everything_ms));
let frame = self.emigui.paint();
let result =
self.webgl_painter
.paint(&frame, self.emigui.texture(), raw_input.pixels_per_point);
self.everything_ms = now_ms() - everything_start;
result
}
}
#[wasm_bindgen]
pub fn new_webgl_gui(canvas_id: &str, pixels_per_point: f32) -> Result<State, JsValue> {
State::new(canvas_id, pixels_per_point)
}
#[wasm_bindgen]
pub fn run_gui(state: &mut State, raw_input_json: &str) -> Result<(), JsValue> {
// TODO: nicer interface than JSON
let raw_input: RawInput = serde_json::from_str(raw_input_json).unwrap();
state.run(raw_input)
}
pub mod webgl;

33
example/Cargo.toml

@ -0,0 +1,33 @@
[package]
name = "example"
version = "0.1.0"
authors = ["Emil Ernerfeldt <emilernerfeldt@gmail.com>"]
edition = "2018"
[lib]
crate-type = ["cdylib", "rlib"]
[dependencies]
js-sys = "0.3"
serde = "1"
serde_json = "1"
wasm-bindgen = "0.2"
emigui = { path = "../emigui" }
emigui_wasm = { path = "../emigui_wasm" }
[dependencies.web-sys]
version = "0.3"
features = [
'Document',
'Element',
'HtmlCanvasElement',
'Performance',
'WebGlBuffer',
'WebGlProgram',
'WebGlRenderingContext',
'WebGlShader',
'WebGlTexture',
'WebGlUniformLocation',
'Window',
]

2
emigui_wasm/src/app.rs → example/src/app.rs

@ -25,7 +25,7 @@ impl Default for App {
impl App {
pub fn show_gui(&mut self, gui: &mut Region) {
gui.add(label!("Emigui").text_style(TextStyle::Heading));
gui.add(label!("Emigui!").text_style(TextStyle::Heading));
gui.add(label!("Emigui is an Immediate mode GUI written in Rust, compiled to WebAssembly, rendered with WebGL."));
gui.add(Separator::new());

79
example/src/lib.rs

@ -0,0 +1,79 @@
#![deny(warnings)]
extern crate serde_json;
extern crate wasm_bindgen;
extern crate emigui;
extern crate emigui_wasm;
use emigui::{label, widgets::Label, Align, Emigui, RawInput};
use wasm_bindgen::prelude::*;
mod app;
fn now_ms() -> f64 {
web_sys::window()
.expect("should have a Window")
.performance()
.expect("should have a Performance")
.now()
}
#[wasm_bindgen]
pub struct State {
app: app::App,
emigui: Emigui,
webgl_painter: emigui_wasm::webgl::Painter,
everything_ms: f64,
}
impl State {
fn new(canvas_id: &str, pixels_per_point: f32) -> Result<State, JsValue> {
Ok(State {
app: Default::default(),
emigui: Emigui::new(pixels_per_point),
webgl_painter: emigui_wasm::webgl::Painter::new(canvas_id)?,
everything_ms: 0.0,
})
}
fn run(&mut self, raw_input: RawInput) -> Result<(), JsValue> {
let everything_start = now_ms();
self.emigui.new_frame(raw_input);
let mut region = self.emigui.whole_screen_region();
let mut region = region.centered_column(region.width().min(480.0), Align::Min);
self.app.show_gui(&mut region);
self.emigui.example(&mut region);
region.add(label!("WebGl painter info:"));
region.indent(|region| {
region.add(label!(self.webgl_painter.debug_info()));
});
region.add(label!("Everything: {:.1} ms", self.everything_ms));
let frame = self.emigui.paint();
let result =
self.webgl_painter
.paint(&frame, self.emigui.texture(), raw_input.pixels_per_point);
self.everything_ms = now_ms() - everything_start;
result
}
}
#[wasm_bindgen]
pub fn new_webgl_gui(canvas_id: &str, pixels_per_point: f32) -> Result<State, JsValue> {
State::new(canvas_id, pixels_per_point)
}
#[wasm_bindgen]
pub fn run_gui(state: &mut State, raw_input_json: &str) -> Result<(), JsValue> {
// TODO: nicer interface than JSON
let raw_input: RawInput = serde_json::from_str(raw_input_json).unwrap();
state.run(raw_input)
}
Loading…
Cancel
Save