diff options
Diffstat (limited to 'WebInterface/wasm/webhogg')
-rw-r--r-- | WebInterface/wasm/webhogg/Cargo.toml | 30 | ||||
-rwxr-xr-x | WebInterface/wasm/webhogg/deploy | 4 | ||||
-rwxr-xr-x | WebInterface/wasm/webhogg/deploy.py | 42 | ||||
-rw-r--r-- | WebInterface/wasm/webhogg/graphics.js | 6 | ||||
-rw-r--r-- | WebInterface/wasm/webhogg/index.html | 24 | ||||
-rw-r--r-- | WebInterface/wasm/webhogg/lighttpd.config | 34 | ||||
-rw-r--r-- | WebInterface/wasm/webhogg/loader.js | 9 | ||||
-rw-r--r-- | WebInterface/wasm/webhogg/mimes | 1 | ||||
-rwxr-xr-x | WebInterface/wasm/webhogg/run | 3 | ||||
-rw-r--r-- | WebInterface/wasm/webhogg/src/app.rs | 22 | ||||
-rw-r--r-- | WebInterface/wasm/webhogg/src/canvas.rs | 42 | ||||
-rw-r--r-- | WebInterface/wasm/webhogg/src/client_logger.rs | 46 | ||||
-rw-r--r-- | WebInterface/wasm/webhogg/src/lib.rs | 41 | ||||
-rw-r--r-- | WebInterface/wasm/webhogg/src/page.rs | 26 | ||||
-rw-r--r-- | WebInterface/wasm/webhogg/src/webhogg_exception.rs | 39 | ||||
-rw-r--r-- | WebInterface/wasm/webhogg/target/.rustc_info.json | 1 | ||||
-rw-r--r-- | WebInterface/wasm/webhogg/webhogg.js | 117 |
17 files changed, 487 insertions, 0 deletions
diff --git a/WebInterface/wasm/webhogg/Cargo.toml b/WebInterface/wasm/webhogg/Cargo.toml new file mode 100644 index 0000000..a2e5f8e --- /dev/null +++ b/WebInterface/wasm/webhogg/Cargo.toml @@ -0,0 +1,30 @@ +[package] +name = "webhogg" +version = "0.1.0" +authors = [ + "natrixaeria", + "TrueDoctor" +] +edition = "2018" + +[lib] +crate-type = ["cdylib"] + +[dependencies] +wasm-bindgen = "0.2" +log = "0.4" +fern = "0.5" + +[dependencies.web-sys] +version = "0.3.22" +features = [ + 'Document', + 'Element', + 'HtmlCanvasElement', + 'WebGl2RenderingContext', + 'WebGlShader', + 'WebGlProgram', + 'WebGlBuffer', + 'Window', + 'Worker' +] diff --git a/WebInterface/wasm/webhogg/deploy b/WebInterface/wasm/webhogg/deploy new file mode 100755 index 0000000..01bc036 --- /dev/null +++ b/WebInterface/wasm/webhogg/deploy @@ -0,0 +1,4 @@ +#!/bin/sh +#killall darkhttpd +#darkhttpd . --addr 127.0.0.1 --port 8080 --mimetypes mimes +python3 deploy.py diff --git a/WebInterface/wasm/webhogg/deploy.py b/WebInterface/wasm/webhogg/deploy.py new file mode 100755 index 0000000..21d9a5e --- /dev/null +++ b/WebInterface/wasm/webhogg/deploy.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python3 + +from socket import socket, SOL_SOCKET, SO_REUSEADDR + +ws = socket() +ws.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) +ws.bind(('localhost', 8080)) +ws.listen() + +class Client: + def __init__(self, sock, addr): + self.sock, self.addr = sock, addr + + def rec(self): + b = b'' + while not b.endswith(b'\r\n\r\n'): + b += self.sock.recv(1) + lines = b.replace(b'\r\n', b'\n').decode('utf-8').strip('\n').split('\n') + method, loc, ver = lines[0].split(' ') + print(f'request from \'{self.addr}\': "{loc}"') + attrs = {key: value for key, value in (i.split(': ') for i in lines[1:])} + return method, loc, attrs + + def sen(self, loc, ver): + f = open(loc, 'rb') + c = f.read() + f.close() + self.sock.send(f'HTTP/1.1 200'.encode('utf-8') + c) + + def run(self): + method, loc, attrs = self.rec() + self.sen(loc, ver) + + +clients = [] + +while True: + c, a = ws.accept() + print(f'{a[0]}:{a[1]} connected') + client = Client(c, a) + clients.append(clients) + client.run() diff --git a/WebInterface/wasm/webhogg/graphics.js b/WebInterface/wasm/webhogg/graphics.js new file mode 100644 index 0000000..f3bab19 --- /dev/null +++ b/WebInterface/wasm/webhogg/graphics.js @@ -0,0 +1,6 @@ +import {default as init_r} from './webhogg.js' +import {init_x} from './webhogg.js' + +let module = init_r('./pkg/webhogg_bg.wasm'); + +init_x(module, 'graphics', null); diff --git a/WebInterface/wasm/webhogg/index.html b/WebInterface/wasm/webhogg/index.html new file mode 100644 index 0000000..ce09537 --- /dev/null +++ b/WebInterface/wasm/webhogg/index.html @@ -0,0 +1,24 @@ +<!doctype html> +<html> + <head> + <meta charset="UTF-8"> + <title>webhogg</title> + <script src='loader.js' type='module'></script> + <style> + body { + margin: 0; + background: black; + } + #canvas { + width: 100%; + height: 100%; + } + img { + background: violet; + } + </style> + </head> + <body> + <canvas id='canvas'></canvas> + </body> +</html> diff --git a/WebInterface/wasm/webhogg/lighttpd.config b/WebInterface/wasm/webhogg/lighttpd.config new file mode 100644 index 0000000..4072b30 --- /dev/null +++ b/WebInterface/wasm/webhogg/lighttpd.config @@ -0,0 +1,34 @@ +server.http-parseopts = ( + "header-strict" => "enable", + "host-strict" => "enable", + "host-normalize" => "enable", + "url-normalize" => "enable", + "url-normalize-unreserved" => "enable", + "url-normalize-required" => "enable", + "url-ctrls-reject" => "enable", + "url-path-2f-decode" => "enable", + "url-path-dotseg-remove" => "enable", + "url-query-20-plus" => "enable" +) + +server.modules += ( "mod_setenv" ) + +server.document-root = "/home/jan/projects/DiscoBot/WebInterface/wasm/webhogg" +server.port = 8080 +dir-listing.activate = "enable" +index-file.names = ( "index.html" ) +mimetype.assign = ( + ".html" => "text/html", + ".txt" => "text/plain", + ".css" => "text/css", + ".js" => "application/javascript", + ".jpg" => "image/jpeg", + ".jpeg" => "image/jpeg", + ".gif" => "image/gif", + ".png" => "image/png", + ".wasm" => "application/wasm", + "" => "application/octet-stream" +) +sentenv.add-response-header = ( + "Content-Security-Policy" => "worker-src localhost:*" +) diff --git a/WebInterface/wasm/webhogg/loader.js b/WebInterface/wasm/webhogg/loader.js new file mode 100644 index 0000000..cc66ff6 --- /dev/null +++ b/WebInterface/wasm/webhogg/loader.js @@ -0,0 +1,9 @@ +import {default as init_r} from './webhogg.js' +import {init_x} from './webhogg.js' + +let module = init_r('./pkg/webhogg_bg.wasm'); + +let graphics = new Worker('./graphics.js') + +init_x(module, 'game logic', graphics); + diff --git a/WebInterface/wasm/webhogg/mimes b/WebInterface/wasm/webhogg/mimes new file mode 100644 index 0000000..007445d --- /dev/null +++ b/WebInterface/wasm/webhogg/mimes @@ -0,0 +1 @@ +application/wasm wasm diff --git a/WebInterface/wasm/webhogg/run b/WebInterface/wasm/webhogg/run new file mode 100755 index 0000000..1da1e35 --- /dev/null +++ b/WebInterface/wasm/webhogg/run @@ -0,0 +1,3 @@ +#!/bin/sh + +wasm-pack build --release --target web diff --git a/WebInterface/wasm/webhogg/src/app.rs b/WebInterface/wasm/webhogg/src/app.rs new file mode 100644 index 0000000..7931418 --- /dev/null +++ b/WebInterface/wasm/webhogg/src/app.rs @@ -0,0 +1,22 @@ +use crate::webhogg_exception::WebhoggException; +use crate::page::Page; +use crate::canvas::Canvas; + +pub(crate) struct WebhoggApplication { + page: Page, + canvas: Canvas, +} + +impl WebhoggApplication { + pub fn new() -> Result<Self, WebhoggException> { + let page = Page::obtain()?; + let canvas = Canvas::from_existing("canvas", &page)?; + Ok(Self { + page, canvas, + }) + } + + pub fn run(self) -> Result<(), WebhoggException> { + Ok(()) + } +} diff --git a/WebInterface/wasm/webhogg/src/canvas.rs b/WebInterface/wasm/webhogg/src/canvas.rs new file mode 100644 index 0000000..a0ef7d1 --- /dev/null +++ b/WebInterface/wasm/webhogg/src/canvas.rs @@ -0,0 +1,42 @@ +use web_sys::WebGl2RenderingContext as WebGl2; +use wasm_bindgen::JsCast; +use crate::webhogg_exception::WebhoggException; +use crate::page::Page; + +pub struct Canvas { + ctx: WebGl2, +} + +impl Canvas { + pub fn from_existing(id: &str, page: &Page) -> Result<Self, WebhoggException> { + let canvas_element = page.get_element(id) + .ok_or(WebhoggException::DomError( + "could not obtain canvas element (id=canvas)" + .to_string()))?; + let canvas_element = canvas_element + .dyn_into::<web_sys::HtmlCanvasElement>() + .map_err(|_| WebhoggException::DomError( + "id=canvas is not a canvas element".to_string()))?; + debug!("successfully obtained canvas element"); + let ctx = canvas_element.get_context("webgl2") + .map_err(|_| WebhoggException::WebGlContextError( + "obtained invalid webgl2 context js value".to_string()))? + .ok_or(WebhoggException::WebGlContextError( + "could not obtaine webgl2 context".to_string()))? + .dyn_into::<WebGl2>() + .map_err(|_| WebhoggException::WebGlContextError( + "obtained invalid webgl2 context js object".to_string()))?; + debug!("successfully obtained webgl2 context"); + Ok(Self { + ctx, + }) + } + + pub fn gl<'a>(&'a self) -> &'a WebGl2 { + &self.ctx + } + + pub fn gl_mut<'a>(&'a mut self) -> &'a mut WebGl2 { + &mut self.ctx + } +} diff --git a/WebInterface/wasm/webhogg/src/client_logger.rs b/WebInterface/wasm/webhogg/src/client_logger.rs new file mode 100644 index 0000000..f71918f --- /dev/null +++ b/WebInterface/wasm/webhogg/src/client_logger.rs @@ -0,0 +1,46 @@ +use wasm_bindgen::prelude::*; + +#[wasm_bindgen] +extern "C" { + #[wasm_bindgen(js_namespace=console, js_name=debug)] + fn __console_debug_colored2(f: &str, c1: &str, c2: &str); + #[wasm_bindgen(js_namespace=console, js_name=info)] + fn __console_info_colored2(f: &str, c1: &str, c2: &str); + #[wasm_bindgen(js_namespace=console, js_name=warn)] + fn __console_warn_colored2(f: &str, c1: &str, c2: &str); + #[wasm_bindgen(js_namespace=console, js_name=error)] + fn __console_error_colored2(f: &str, c1: &str, c2: &str); +} + +fn log(rec: &log::Record) { + let log_fn = match rec.level() { + log::Level::Trace | log::Level::Debug => __console_debug_colored2, + log::Level::Info => __console_info_colored2, + log::Level::Warn => __console_warn_colored2, + log::Level::Error => __console_error_colored2, + }; + log_fn(&format!("{}", rec.args()), + &format!("color: {}", match rec.level() { + log::Level::Trace => "violet", + log::Level::Debug => "blue", + log::Level::Info => "green", + log::Level::Warn => "orange", + log::Level::Error => "red" + }), ""); +} + +pub fn init_logger() { + fern::Dispatch::new().format(|out, message, record|{ + out.finish(format_args!( + "%c{}%c {} > {}", + record.level(), + record.target(), + message + ) + ) + }) + .level(log::LevelFilter::Debug) + .chain(fern::Output::call(log)) + .apply().unwrap(); +} + diff --git a/WebInterface/wasm/webhogg/src/lib.rs b/WebInterface/wasm/webhogg/src/lib.rs new file mode 100644 index 0000000..4a79a24 --- /dev/null +++ b/WebInterface/wasm/webhogg/src/lib.rs @@ -0,0 +1,41 @@ +mod client_logger; +mod webhogg_exception; +mod page; +mod canvas; +mod app; + +use wasm_bindgen::prelude::*; +use app::WebhoggApplication as App; +use web_sys::Worker; + +#[macro_use] +extern crate log; + +fn run_application() { + match App::new().and_then(|app| app.run()) { + Ok(_) => info!("program terminated successfully"), + Err(e) => error!("program terminated with failure > {}", e) + } +} + +#[wasm_bindgen] +pub fn game_logic_entry(worker: Worker) { + client_logger::init_logger(); + + info!("game logic initialisation"); +} + +#[wasm_bindgen] +pub fn graphics_entry(worker: Worker) { + client_logger::init_logger(); + + info!("graphics initialisation"); +} + +pub fn entry2() { + client_logger::init_logger(); + + info!("begin running wasm application"); + + run_application() +} diff --git a/WebInterface/wasm/webhogg/src/page.rs b/WebInterface/wasm/webhogg/src/page.rs new file mode 100644 index 0000000..cb9ee3f --- /dev/null +++ b/WebInterface/wasm/webhogg/src/page.rs @@ -0,0 +1,26 @@ +use web_sys; + +use crate::webhogg_exception::WebhoggException; + +pub struct Page { + window: web_sys::Window, + document: web_sys::Document, +} + +impl Page { + pub fn obtain() -> Result<Self, WebhoggException> { + let window = web_sys::window() + .ok_or(WebhoggException::DomError("could not obtain window".to_string()))?; + let document = window.document() + .ok_or(WebhoggException::DomError("could not obtain document".to_string()))?; + debug!("initialised page"); + Ok(Self { + window, + document, + }) + } + + pub fn get_element(&self, id: &str) -> Option<web_sys::Element> { + self.document.get_element_by_id(id) + } +} diff --git a/WebInterface/wasm/webhogg/src/webhogg_exception.rs b/WebInterface/wasm/webhogg/src/webhogg_exception.rs new file mode 100644 index 0000000..46eedd6 --- /dev/null +++ b/WebInterface/wasm/webhogg/src/webhogg_exception.rs @@ -0,0 +1,39 @@ +use std::error::Error; + +#[derive(Debug)] +pub enum WebhoggException { + DomError(String), + WebGlContextError(String), +} + +impl WebhoggException { + fn err_name(&self) -> &str { + match self { + WebhoggException::DomError(_) => "DomError", + WebhoggException::WebGlContextError(_) => "WebGlContextError", + } + } +} + +impl Error for WebhoggException { + fn description(&self) -> &str { + match self { + WebhoggException::DomError(desc) => desc, + WebhoggException::WebGlContextError(desc) => desc, + } + } + + fn cause(&self) -> Option<&dyn Error> { + self.source() + } + + fn source(&self) -> Option<&(dyn Error + 'static)> { + None + } +} + +impl std::fmt::Display for WebhoggException { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "WebhoggException::{} {}", self.err_name(), self.description()) + } +} diff --git a/WebInterface/wasm/webhogg/target/.rustc_info.json b/WebInterface/wasm/webhogg/target/.rustc_info.json new file mode 100644 index 0000000..94a43da --- /dev/null +++ b/WebInterface/wasm/webhogg/target/.rustc_info.json @@ -0,0 +1 @@ +{"rustc_fingerprint":7082560745936267572,"outputs":{"1617349019360157463":["___\nlib___.rlib\nlib___.so\nlib___.so\nlib___.a\nlib___.so\n/home/jan/.rustup/toolchains/stable-x86_64-unknown-linux-gnu\ndebug_assertions\nproc_macro\ntarget_arch=\"x86_64\"\ntarget_endian=\"little\"\ntarget_env=\"gnu\"\ntarget_family=\"unix\"\ntarget_feature=\"fxsr\"\ntarget_feature=\"sse\"\ntarget_feature=\"sse2\"\ntarget_os=\"linux\"\ntarget_pointer_width=\"64\"\ntarget_vendor=\"unknown\"\nunix\n",""],"6217262102979750783":["___.wasm\nlib___.rlib\n___.wasm\nlib___.a\n/home/jan/.rustup/toolchains/stable-x86_64-unknown-linux-gnu\ndebug_assertions\nproc_macro\ntarget_arch=\"wasm32\"\ntarget_endian=\"little\"\ntarget_env=\"\"\ntarget_os=\"unknown\"\ntarget_pointer_width=\"32\"\ntarget_vendor=\"unknown\"\n","warning: dropping unsupported crate type `dylib` for target `wasm32-unknown-unknown`\n\nwarning: dropping unsupported crate type `proc-macro` for target `wasm32-unknown-unknown`\n\n"],"1164083562126845933":["rustc 1.34.1 (fc50f328b 2019-04-24)\nbinary: rustc\ncommit-hash: fc50f328b0353b285421b8ff5d4100966387a997\ncommit-date: 2019-04-24\nhost: x86_64-unknown-linux-gnu\nrelease: 1.34.1\nLLVM version: 8.0\n",""]},"successes":{}}
\ No newline at end of file diff --git a/WebInterface/wasm/webhogg/webhogg.js b/WebInterface/wasm/webhogg/webhogg.js new file mode 100644 index 0000000..751ac77 --- /dev/null +++ b/WebInterface/wasm/webhogg/webhogg.js @@ -0,0 +1,117 @@ + +const __exports = {}; +let wasm; + +let cachedTextDecoder = new TextDecoder('utf-8'); + +let cachegetUint8Memory = null; +function getUint8Memory() { + if (cachegetUint8Memory === null || cachegetUint8Memory.buffer !== wasm.memory.buffer) { + cachegetUint8Memory = new Uint8Array(wasm.memory.buffer); + } + return cachegetUint8Memory; +} + +function getStringFromWasm(ptr, len) { + return cachedTextDecoder.decode(getUint8Memory().subarray(ptr, ptr + len)); +} + +function __wbg_debug_eacd5b227c4c01c7(arg0, arg1, arg2, arg3, arg4, arg5) { + let varg0 = getStringFromWasm(arg0, arg1); + let varg2 = getStringFromWasm(arg2, arg3); + let varg4 = getStringFromWasm(arg4, arg5); + console.debug(varg0, varg2, varg4); +} +__exports.__wbg_debug_eacd5b227c4c01c7 = __wbg_debug_eacd5b227c4c01c7 + +function __wbg_info_be654745b6a55079(arg0, arg1, arg2, arg3, arg4, arg5) { + let varg0 = getStringFromWasm(arg0, arg1); + let varg2 = getStringFromWasm(arg2, arg3); + let varg4 = getStringFromWasm(arg4, arg5); + console.info(varg0, varg2, varg4); +} +__exports.__wbg_info_be654745b6a55079 = __wbg_info_be654745b6a55079 + +function __wbg_warn_804a0523852c6d10(arg0, arg1, arg2, arg3, arg4, arg5) { + let varg0 = getStringFromWasm(arg0, arg1); + let varg2 = getStringFromWasm(arg2, arg3); + let varg4 = getStringFromWasm(arg4, arg5); + console.warn(varg0, varg2, varg4); +} +__exports.__wbg_warn_804a0523852c6d10 = __wbg_warn_804a0523852c6d10 + +function __wbg_error_56a861ecc80f27e1(arg0, arg1, arg2, arg3, arg4, arg5) { + let varg0 = getStringFromWasm(arg0, arg1); + let varg2 = getStringFromWasm(arg2, arg3); + let varg4 = getStringFromWasm(arg4, arg5); + console.error(varg0, varg2, varg4); +} +__exports.__wbg_error_56a861ecc80f27e1 = __wbg_error_56a861ecc80f27e1 +/** +* @returns {void} +*/ +export function game_logic_entry(worker) { + return wasm.game_logic_entry(addHeapObject(worker)); +} +__exports.game_logic_entry = game_logic_entry + +/** +* @returns {void} +*/ +export function graphics_entry(worker) { + return wasm.graphics_entry(addHeapObject(worker)); +} +__exports.graphics_entry = graphics_entry + +function __wbindgen_throw(ptr, len) { + throw new Error(getStringFromWasm(ptr, len)); +} +__exports.__wbindgen_throw = __wbindgen_throw + +function init_r(module) { + let result; + const imports = { './webhogg': __exports }; + + if (module instanceof URL || typeof module === 'string' || module instanceof Request) { + + const response = fetch(module); + if (typeof WebAssembly.instantiateStreaming === 'function') { + result = WebAssembly.instantiateStreaming(response, imports) + .catch(e => { + console.warn("`WebAssembly.instantiateStreaming` failed. Assuming this is because your server does not serve wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n", e); + return response + .then(r => r.arrayBuffer()) + .then(bytes => WebAssembly.instantiate(bytes, imports)); + }); + } else { + result = response + .then(r => r.arrayBuffer()) + .then(bytes => WebAssembly.instantiate(bytes, imports)); + } + } else { + + result = WebAssembly.instantiate(module, imports) + .then(result => { + if (result instanceof WebAssembly.Instance) { + return { instance: result, module }; + } else { + return result; + } + }); + } + return result; +} + +function _init_x(result, bx) { + return result.then(({instance, module}) => { + wasm = instance.exports; + if (bx == 1) wasm.game_logic_entry(); + else wasm.graphics_entry(); + //init_r.__wbindgen_wasm_module = module; + //wasm.__wbindgen_start(); + return wasm; + }); +} + +export default init_r; +export var init_x = _init_x; |