From c45a9524b307c264e69aa017fcf370d71ea799da Mon Sep 17 00:00:00 2001 From: natrixaeria Date: Sun, 19 May 2019 15:39:48 +0200 Subject: Push new clients to a Map --- game_server/src/gameserver.rs | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/game_server/src/gameserver.rs b/game_server/src/gameserver.rs index 9334a27..6f6dead 100644 --- a/game_server/src/gameserver.rs +++ b/game_server/src/gameserver.rs @@ -4,8 +4,10 @@ use websocket::{OwnedMessage, server::{NoTlsAcceptor, InvalidConnection, sync::AcceptResult}}; use std::net::{SocketAddr, ToSocketAddrs, TcpStream}; -use std::sync::mpsc; -use std::sync::mpsc::{Sender, Receiver}; +use std::sync::{mpsc, + mpsc::{Sender, Receiver}, + Arc, Mutex}; +use std::collections::HashMap; use super::lobby::Lobby; use super::backend_connection::BackendConnection; @@ -25,6 +27,7 @@ pub struct GameServer { addr: SocketAddr, lobby: Lobby, backend: BackendConnection, + clients: Arc>>, } pub struct GameClient { @@ -47,7 +50,7 @@ impl GameClient { .recv_message() .ok()?; if let OwnedMessage::Text(text) = message { - text.parse::().ok() + text.parse().ok() } else { None } @@ -68,6 +71,7 @@ impl GameServer { addr, lobby, backend, + clients: Arc::new(Mutex::new(HashMap::new())), } } @@ -81,9 +85,15 @@ impl GameServer { } fn add_client(&self, mut client: GameClient) { + let clients = Arc::clone(&self.clients); std::thread::spawn(move || { - println!("Token: {:?}", client.require_token()); - loop { std::thread::sleep(std::time::Duration::from_millis(100)); } + let token = client.require_token(); + if let Some(token) = token { + println!("Token: {}", token); + clients.lock().unwrap().insert(token, client); + } else { + warn!("Client sent invalid token"); + } }); } -- cgit v1.2.3-54-g00ecf From 91a1321f0ae1a02df9c3d1a8f890d84a94953a61 Mon Sep 17 00:00:00 2001 From: natrixaeria Date: Sun, 19 May 2019 17:09:56 +0200 Subject: Validate tokens and then push client --- game_server/src/backend_connection.rs | 57 +++++++++++++++++++++++++++++------ game_server/src/gameserver.rs | 17 ++++++++--- 2 files changed, 59 insertions(+), 15 deletions(-) diff --git a/game_server/src/backend_connection.rs b/game_server/src/backend_connection.rs index 9307c4a..6d3537a 100644 --- a/game_server/src/backend_connection.rs +++ b/game_server/src/backend_connection.rs @@ -1,31 +1,68 @@ use reqwest::{Response, Client, Url, UrlError, Error as ReqError}; +use std::sync::mpsc::{Sender, Receiver}; +use std::sync::mpsc; +use super::gameserver::Token; pub struct BackendConnection { host: String, - client: Client, - last_response: Option> + req_sender: Sender, + res_rec: Receiver, } +#[derive(Debug)] +pub enum BackendError { + UrlError(UrlError), + RequestError(ReqError), + InvalidTokenFormat, + InvalidToken, +} + +pub type TokenValidity = Result<(), BackendError>; +pub type RequestData = Url; +pub type ResponseResult = Result; + impl BackendConnection { + fn run_background(req_rec: Receiver, res_sender: Sender) { + let client = Client::new(); + loop { + let request_data = req_rec.recv().unwrap(); + let location = request_data; + let request = client.get(location); + let response = request.send(); + res_sender.send(response); + } + } + pub fn new(host: &str) -> Self { + let (req_sender, req_rec): (Sender, Receiver) + = mpsc::channel(); + let (res_sender, res_rec): (Sender, Receiver) + = mpsc::channel(); + std::thread::spawn(move || Self::run_background(req_rec, res_sender)); BackendConnection { host: host.to_string(), - client: Client::new(), - last_response: None + req_sender, + res_rec, } } - pub fn request(&mut self, location: &str) -> Result<(), UrlError> { - Ok(self.last_response = - Some(self.client.get(Url::parse(&format!("{}{}", self.host, location))?) - .send())) + pub fn request(&self, location: &str) -> Result<(), UrlError> { + Ok(self.req_sender.send(Url::parse(&format!("{}{}", self.host, location))?).unwrap()) } - pub fn get_response(&self) -> &Option> { - &self.last_response + pub fn get_response(&self) -> ResponseResult { + self.res_rec.recv().unwrap() } pub fn host_name<'a>(&'a self) -> &'a str { &self.host } + + pub fn validate_token(&self, token: &Token) -> TokenValidity { + let location = format!("/api/lobby/tokens/{}", token); + self.request(&location).map_err(|err| BackendError::UrlError(err))?; + let response = self.get_response(); + println!("backend response: {:?}", response); + Ok(()) + } } diff --git a/game_server/src/gameserver.rs b/game_server/src/gameserver.rs index 6f6dead..a4b1ed5 100644 --- a/game_server/src/gameserver.rs +++ b/game_server/src/gameserver.rs @@ -13,7 +13,7 @@ use super::backend_connection::BackendConnection; const PROTOCOL: &str = "tuesday"; -type Token = u32; +pub type Token = u32; #[derive(Debug)] pub enum GameServerError { @@ -26,7 +26,7 @@ pub enum GameServerError { pub struct GameServer { addr: SocketAddr, lobby: Lobby, - backend: BackendConnection, + backend: Arc>, clients: Arc>>, } @@ -70,7 +70,7 @@ impl GameServer { GameServer { addr, lobby, - backend, + backend: Arc::new(Mutex::new(backend)), clients: Arc::new(Mutex::new(HashMap::new())), } } @@ -86,13 +86,20 @@ impl GameServer { fn add_client(&self, mut client: GameClient) { let clients = Arc::clone(&self.clients); + let backend = Arc::clone(&self.backend); std::thread::spawn(move || { let token = client.require_token(); if let Some(token) = token { println!("Token: {}", token); - clients.lock().unwrap().insert(token, client); + let locked_backend = backend.lock().unwrap(); + let result = locked_backend.validate_token(&token); + if let Err(err) = result { + warn!("token {} is invalid: '{:?}'", token, err); + } else { + clients.lock().unwrap().insert(token, client); + } } else { - warn!("Client sent invalid token"); + warn!("client sent invalid token"); } }); } -- cgit v1.2.3-54-g00ecf From b65c999daa5c83b9e76c6dca9df088a40e440642 Mon Sep 17 00:00:00 2001 From: natrixaeria Date: Sun, 19 May 2019 17:38:50 +0200 Subject: Change logger to fern --- game_server/Cargo.toml | 3 ++- game_server/src/backend_connection.rs | 2 +- game_server/src/game_logger.rs | 29 +++++++++++++++++++++++++++++ game_server/src/main.rs | 5 +++-- 4 files changed, 35 insertions(+), 4 deletions(-) create mode 100644 game_server/src/game_logger.rs diff --git a/game_server/Cargo.toml b/game_server/Cargo.toml index 97c0e77..bc14942 100644 --- a/game_server/Cargo.toml +++ b/game_server/Cargo.toml @@ -7,7 +7,8 @@ description = "A general game server for connections to web clients. Currently ( [dependencies] log = "0.4" -pretty_env_logger = "0.3" +fern = "0.5.8" +colored = "1.8" reqwest = "0.9" websocket = "0.22" hyper = "0.10" diff --git a/game_server/src/backend_connection.rs b/game_server/src/backend_connection.rs index 6d3537a..11642f2 100644 --- a/game_server/src/backend_connection.rs +++ b/game_server/src/backend_connection.rs @@ -29,7 +29,7 @@ impl BackendConnection { let location = request_data; let request = client.get(location); let response = request.send(); - res_sender.send(response); + res_sender.send(response).unwrap(); } } diff --git a/game_server/src/game_logger.rs b/game_server/src/game_logger.rs new file mode 100644 index 0000000..e49ebe8 --- /dev/null +++ b/game_server/src/game_logger.rs @@ -0,0 +1,29 @@ +use colored::*; + +fn color_level(level: log::Level) -> colored::ColoredString { + let text = format!("{: <8}", level); + match level { + log::Level::Error => text.red().bold(), + log::Level::Warn => text.yellow(), + log::Level::Info => text.green(), + log::Level::Debug => text.cyan(), + log::Level::Trace => text.magenta(), + } +} + +pub fn init_logger() { + fern::Dispatch::new().format(|out, message, record|{ + out.finish(format_args!( + "{} {} > {}", + color_level(record.level()), + record.target(), + message + ) + ) + }) + .level(log::LevelFilter::Debug) + .level_for("hyper", log::LevelFilter::Off) + .level_for("tokio-reactor", log::LevelFilter::Off) + .chain(std::io::stdout()) + .apply().unwrap(); +} diff --git a/game_server/src/main.rs b/game_server/src/main.rs index e129283..76e7a39 100644 --- a/game_server/src/main.rs +++ b/game_server/src/main.rs @@ -4,13 +4,14 @@ mod lobby; mod gameserver; mod backend_connection; +mod game_logger; + #[macro_use] extern crate log; -use pretty_env_logger; use backend_connection::BackendConnection; fn main() { - pretty_env_logger::init(); + game_logger::init_logger(); let addr = ("127.0.0.1", 5001); info!("create game server on {:?}", addr); -- cgit v1.2.3-54-g00ecf From c3bb858bb54dc8c64bbd48054c2c58dc0073f09c Mon Sep 17 00:00:00 2001 From: natrixaeria Date: Sun, 19 May 2019 17:39:50 +0200 Subject: Remove build script MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Copilation works now as usual with ´cargo run´ / ´cargo build´ --- game_server/build.sh | 21 --------------- game_server/err | 73 --------------------------------------------------- game_server/rbuild.sh | 2 -- 3 files changed, 96 deletions(-) delete mode 100755 game_server/build.sh delete mode 100644 game_server/err delete mode 100644 game_server/rbuild.sh diff --git a/game_server/build.sh b/game_server/build.sh deleted file mode 100755 index 1eb61a1..0000000 --- a/game_server/build.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/env sh - -case $1 in - ("") - if rustup run stable cargo --color always build; then - echo build success! - RUST_LOG=debug target/debug/game-server - else - echo build failed! - fi - ;; - -r) - sh build.sh &> err && cat err | tac - ;; - -c) - rustup run stable cargo clean - ;; - *) - echo invalid argument - ;; -esac diff --git a/game_server/err b/game_server/err deleted file mode 100644 index 6ca8a6f..0000000 --- a/game_server/err +++ /dev/null @@ -1,73 +0,0 @@ - Compiling game-server v0.1.0 (/home/jan/projects/DiscoBot/game_server) -error[E0277]: the trait bound `(): futures::future::Future` is not satisfied - --> src/backend_connection.rs:32:24 - | -32 |  hyper::rt::run(hyper::rt::lazy(|| { - |  ^^^^^^^^^^^^^^^ the trait `futures::future::Future` is not implemented for `()` - | - = note: required because of the requirements on the impl of `futures::future::IntoFuture` for `()` - = note: required by `futures::future::lazy::lazy` - -error[E0599]: no method named `wait` found for type `std::result::Result, [closure@src/backend_connection.rs:55:38: 55:73]>, http::uri::InvalidUri>` in the current scope - --> src/backend_connection.rs:56:24 - | -56 |  }).wait(); - |  ^^^^ - | - = note: the method `wait` exists but the following trait bounds were not satisfied: - `&mut std::result::Result, [closure@src/backend_connection.rs:55:38: 55:73]>, http::uri::InvalidUri> : futures::future::Future` - -error[E0308]: mismatched types - --> src/backend_connection.rs:58:17 - | -58 |  res - |  ^^^ expected (), found enum `std::result::Result` - | - = note: expected type `()` - found type `std::result::Result, http::uri::InvalidUri>` - -error[E0277]: the trait bound `(): futures::future::Future` is not satisfied - --> src/backend_connection.rs:32:24 - | -32 |   hyper::rt::run(hyper::rt::lazy(|| { - |  ________________________^ -33 | |  let client = hyper::Client::builder() -34 | |  .build::<_, hyper::Body>( -35 | |  HttpsConnector::new(4).unwrap() -... | -59 | |  } -60 | |  })); - | |__________^ the trait `futures::future::Future` is not implemented for `()` - | - = note: required because of the requirements on the impl of `futures::future::IntoFuture` for `()` - = note: required by `futures::future::lazy::Lazy` - -error[E0277]: the trait bound `(): futures::future::Future` is not satisfied - --> src/backend_connection.rs:32:9 - | -32 |  hyper::rt::run(hyper::rt::lazy(|| { - |  ^^^^^^^^^^^^^^ the trait `futures::future::Future` is not implemented for `()` - | - = note: required because of the requirements on the impl of `futures::future::IntoFuture` for `()` - = note: required by `hyper::rt::run` - -error[E0063]: missing field `res_receiver` in initializer of `backend_connection::BackendConnection` - --> src/backend_connection.rs:62:9 - | -62 |  BackendConnection { - |  ^^^^^^^^^^^^^^^^^ missing `res_receiver` - -error[E0609]: no field `request_sender` on type `&backend_connection::BackendConnection` - --> src/backend_connection.rs:69:14 - | -69 |  self.request_sender.send( - |  ^^^^^^^^^^^^^^ - -error: aborting due to 7 previous errors - -Some errors have detailed explanations: E0063, E0277, E0308, E0599, E0609. -For more information about an error, try `rustc --explain E0063`. -error: Could not compile `game-server`. - -To learn more, run the command again with --verbose. -build failed! diff --git a/game_server/rbuild.sh b/game_server/rbuild.sh deleted file mode 100644 index 22b10b5..0000000 --- a/game_server/rbuild.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -sh build.sh &> err && cat err | tac -- cgit v1.2.3-54-g00ecf From fbed43a319dae36d961f8d6a073c32d84c90c75f Mon Sep 17 00:00:00 2001 From: natrixaeria Date: Sun, 19 May 2019 17:43:34 +0200 Subject: Disable logging for tokio-core and reqwest --- game_server/src/game_logger.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/game_server/src/game_logger.rs b/game_server/src/game_logger.rs index e49ebe8..c51bfc5 100644 --- a/game_server/src/game_logger.rs +++ b/game_server/src/game_logger.rs @@ -23,7 +23,8 @@ pub fn init_logger() { }) .level(log::LevelFilter::Debug) .level_for("hyper", log::LevelFilter::Off) - .level_for("tokio-reactor", log::LevelFilter::Off) + .level_for("tokio_reactor", log::LevelFilter::Off) + .level_for("reqwest", log::LevelFilter::Off) .chain(std::io::stdout()) .apply().unwrap(); } -- cgit v1.2.3-54-g00ecf From 14c163e415a8ad37d9111e6a5a4a34e3cbe0ad74 Mon Sep 17 00:00:00 2001 From: natrixaeria Date: Sun, 19 May 2019 17:55:04 +0200 Subject: Rename gameserver module to server --- game_server/src/backend_connection.rs | 2 +- game_server/src/gameserver.rs | 164 ---------------------------------- game_server/src/main.rs | 4 +- game_server/src/server.rs | 164 ++++++++++++++++++++++++++++++++++ 4 files changed, 167 insertions(+), 167 deletions(-) delete mode 100644 game_server/src/gameserver.rs create mode 100644 game_server/src/server.rs diff --git a/game_server/src/backend_connection.rs b/game_server/src/backend_connection.rs index 11642f2..fa41791 100644 --- a/game_server/src/backend_connection.rs +++ b/game_server/src/backend_connection.rs @@ -1,7 +1,7 @@ use reqwest::{Response, Client, Url, UrlError, Error as ReqError}; use std::sync::mpsc::{Sender, Receiver}; use std::sync::mpsc; -use super::gameserver::Token; +use super::server::Token; pub struct BackendConnection { host: String, diff --git a/game_server/src/gameserver.rs b/game_server/src/gameserver.rs deleted file mode 100644 index a4b1ed5..0000000 --- a/game_server/src/gameserver.rs +++ /dev/null @@ -1,164 +0,0 @@ -use websocket::{OwnedMessage, - sync::Server, - client::sync::Client, - server::{NoTlsAcceptor, InvalidConnection, - sync::AcceptResult}}; -use std::net::{SocketAddr, ToSocketAddrs, TcpStream}; -use std::sync::{mpsc, - mpsc::{Sender, Receiver}, - Arc, Mutex}; -use std::collections::HashMap; -use super::lobby::Lobby; -use super::backend_connection::BackendConnection; - -const PROTOCOL: &str = "tuesday"; - -pub type Token = u32; - -#[derive(Debug)] -pub enum GameServerError { - BindError(std::io::Error), - HandshakeRequestError, - InvalidProtocolError, - AcceptError(std::io::Error) -} - -pub struct GameServer { - addr: SocketAddr, - lobby: Lobby, - backend: Arc>, - clients: Arc>>, -} - -pub struct GameClient { - addr: SocketAddr, - client: Client, -} - -impl GameClient { - fn from_raw(client: Client) -> Result { - let addr = client.peer_addr().map_err(|_| ())?; - info!("got a client connection from: {}", addr); - Ok(GameClient { - addr, - client, - }) - } - - fn require_token(&mut self) -> Option { - let message = self.client - .recv_message() - .ok()?; - if let OwnedMessage::Text(text) = message { - text.parse().ok() - } else { - None - } - } -} - -type ClientConnection = Result; - -impl GameServer { - pub fn new(addr: T) -> Self { - let addr = addr.to_socket_addrs().unwrap().next().unwrap(); - debug!("ws address: {}", addr); - info!("create lobby"); - let lobby = Lobby::new(); - let backend = BackendConnection::new("https://kobert.dev"); - info!("got a C# backend connection"); - GameServer { - addr, - lobby, - backend: Arc::new(Mutex::new(backend)), - clients: Arc::new(Mutex::new(HashMap::new())), - } - } - - pub fn run(&self) -> Result<(), GameServerError> { - let reader = self.read_clients(); - loop { - let mut connection = reader.recv().unwrap()?; - self.add_client(connection); - } - Ok(()) - } - - fn add_client(&self, mut client: GameClient) { - let clients = Arc::clone(&self.clients); - let backend = Arc::clone(&self.backend); - std::thread::spawn(move || { - let token = client.require_token(); - if let Some(token) = token { - println!("Token: {}", token); - let locked_backend = backend.lock().unwrap(); - let result = locked_backend.validate_token(&token); - if let Err(err) = result { - warn!("token {} is invalid: '{:?}'", token, err); - } else { - clients.lock().unwrap().insert(token, client); - } - } else { - warn!("client sent invalid token"); - } - }); - } - - fn read_clients(&self) -> Receiver { - let (s, r): (Sender, Receiver) - = mpsc::channel(); - let addr = self.addr; - std::thread::spawn(move || { - let result = Self::handle_requests(addr, &s).or_else(|e| s.send(Err(e))); - }); - r - } - - fn handle_requests(addr: SocketAddr, s: &Sender) -> Result<(), GameServerError> { - let server = match Server::::bind(addr) { - Ok(v) => v, - Err(e) => { - error!("websocket binding error"); - Err(GameServerError::BindError(e))? - }, - }; - info!("webserver is being launched"); - for req in server { - s.send(Ok(Self::handle_request(req)?)).unwrap(); - } - info!("webserver is being shut down"); - Ok(()) - } - - fn handle_request(req: AcceptResult) -> ClientConnection { - match req { - Ok(req) => { - if !req.protocols().contains(&PROTOCOL.to_string()) { - warn!("a client tried to connect without {} protocol", PROTOCOL); - req.reject().unwrap(); - Err(GameServerError::InvalidProtocolError) - } else { - match req.use_protocol(PROTOCOL).accept() { - Ok(client) => { - match GameClient::from_raw(client) { - Ok(client) => Ok(client), - Err(_) => { - error!("could not create a client"); - Err(GameServerError::HandshakeRequestError) - } - } - }, - Err((_, e)) => { - warn!("client handshake failed"); - Err(GameServerError::AcceptError(e)) - } - } - } - }, - Err(e) => { - warn!("invalid client request"); - Err(GameServerError::HandshakeRequestError) - } - } - } -} diff --git a/game_server/src/main.rs b/game_server/src/main.rs index 76e7a39..4d05efe 100644 --- a/game_server/src/main.rs +++ b/game_server/src/main.rs @@ -1,7 +1,7 @@ mod group; mod test_group; mod lobby; -mod gameserver; +mod server; mod backend_connection; mod game_logger; @@ -15,7 +15,7 @@ fn main() { let addr = ("127.0.0.1", 5001); info!("create game server on {:?}", addr); - let gameserver = gameserver::GameServer::new(addr); + let gameserver = server::GameServer::new(addr); gameserver.run().unwrap(); } diff --git a/game_server/src/server.rs b/game_server/src/server.rs new file mode 100644 index 0000000..a4b1ed5 --- /dev/null +++ b/game_server/src/server.rs @@ -0,0 +1,164 @@ +use websocket::{OwnedMessage, + sync::Server, + client::sync::Client, + server::{NoTlsAcceptor, InvalidConnection, + sync::AcceptResult}}; +use std::net::{SocketAddr, ToSocketAddrs, TcpStream}; +use std::sync::{mpsc, + mpsc::{Sender, Receiver}, + Arc, Mutex}; +use std::collections::HashMap; +use super::lobby::Lobby; +use super::backend_connection::BackendConnection; + +const PROTOCOL: &str = "tuesday"; + +pub type Token = u32; + +#[derive(Debug)] +pub enum GameServerError { + BindError(std::io::Error), + HandshakeRequestError, + InvalidProtocolError, + AcceptError(std::io::Error) +} + +pub struct GameServer { + addr: SocketAddr, + lobby: Lobby, + backend: Arc>, + clients: Arc>>, +} + +pub struct GameClient { + addr: SocketAddr, + client: Client, +} + +impl GameClient { + fn from_raw(client: Client) -> Result { + let addr = client.peer_addr().map_err(|_| ())?; + info!("got a client connection from: {}", addr); + Ok(GameClient { + addr, + client, + }) + } + + fn require_token(&mut self) -> Option { + let message = self.client + .recv_message() + .ok()?; + if let OwnedMessage::Text(text) = message { + text.parse().ok() + } else { + None + } + } +} + +type ClientConnection = Result; + +impl GameServer { + pub fn new(addr: T) -> Self { + let addr = addr.to_socket_addrs().unwrap().next().unwrap(); + debug!("ws address: {}", addr); + info!("create lobby"); + let lobby = Lobby::new(); + let backend = BackendConnection::new("https://kobert.dev"); + info!("got a C# backend connection"); + GameServer { + addr, + lobby, + backend: Arc::new(Mutex::new(backend)), + clients: Arc::new(Mutex::new(HashMap::new())), + } + } + + pub fn run(&self) -> Result<(), GameServerError> { + let reader = self.read_clients(); + loop { + let mut connection = reader.recv().unwrap()?; + self.add_client(connection); + } + Ok(()) + } + + fn add_client(&self, mut client: GameClient) { + let clients = Arc::clone(&self.clients); + let backend = Arc::clone(&self.backend); + std::thread::spawn(move || { + let token = client.require_token(); + if let Some(token) = token { + println!("Token: {}", token); + let locked_backend = backend.lock().unwrap(); + let result = locked_backend.validate_token(&token); + if let Err(err) = result { + warn!("token {} is invalid: '{:?}'", token, err); + } else { + clients.lock().unwrap().insert(token, client); + } + } else { + warn!("client sent invalid token"); + } + }); + } + + fn read_clients(&self) -> Receiver { + let (s, r): (Sender, Receiver) + = mpsc::channel(); + let addr = self.addr; + std::thread::spawn(move || { + let result = Self::handle_requests(addr, &s).or_else(|e| s.send(Err(e))); + }); + r + } + + fn handle_requests(addr: SocketAddr, s: &Sender) -> Result<(), GameServerError> { + let server = match Server::::bind(addr) { + Ok(v) => v, + Err(e) => { + error!("websocket binding error"); + Err(GameServerError::BindError(e))? + }, + }; + info!("webserver is being launched"); + for req in server { + s.send(Ok(Self::handle_request(req)?)).unwrap(); + } + info!("webserver is being shut down"); + Ok(()) + } + + fn handle_request(req: AcceptResult) -> ClientConnection { + match req { + Ok(req) => { + if !req.protocols().contains(&PROTOCOL.to_string()) { + warn!("a client tried to connect without {} protocol", PROTOCOL); + req.reject().unwrap(); + Err(GameServerError::InvalidProtocolError) + } else { + match req.use_protocol(PROTOCOL).accept() { + Ok(client) => { + match GameClient::from_raw(client) { + Ok(client) => Ok(client), + Err(_) => { + error!("could not create a client"); + Err(GameServerError::HandshakeRequestError) + } + } + }, + Err((_, e)) => { + warn!("client handshake failed"); + Err(GameServerError::AcceptError(e)) + } + } + } + }, + Err(e) => { + warn!("invalid client request"); + Err(GameServerError::HandshakeRequestError) + } + } + } +} -- cgit v1.2.3-54-g00ecf From 36df226f113151fe3c18831a082fea64ba8a0c03 Mon Sep 17 00:00:00 2001 From: natrixaeria Date: Sun, 19 May 2019 18:25:29 +0200 Subject: Validate tokens successfully --- game_server/src/backend_connection.rs | 18 +++++++++++++++--- game_server/src/server.rs | 9 +++++++-- game_server/src/ws_test.html | 3 ++- 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/game_server/src/backend_connection.rs b/game_server/src/backend_connection.rs index fa41791..4a12439 100644 --- a/game_server/src/backend_connection.rs +++ b/game_server/src/backend_connection.rs @@ -15,6 +15,11 @@ pub enum BackendError { RequestError(ReqError), InvalidTokenFormat, InvalidToken, + BadResponse(Response), +} + +struct TokenResponseStruct { + } pub type TokenValidity = Result<(), BackendError>; @@ -61,8 +66,15 @@ impl BackendConnection { pub fn validate_token(&self, token: &Token) -> TokenValidity { let location = format!("/api/lobby/tokens/{}", token); self.request(&location).map_err(|err| BackendError::UrlError(err))?; - let response = self.get_response(); - println!("backend response: {:?}", response); - Ok(()) + let mut response = self.get_response().map_err(|err| BackendError::RequestError(err))?; + if response.status().is_success() { + Ok(()) + } else if response.status() == reqwest::StatusCode::NOT_FOUND { + Err(BackendError::InvalidToken) + } else if response.status().is_client_error() { + Err(BackendError::InvalidTokenFormat) + } else { + Err(BackendError::BadResponse(response)) + } } } diff --git a/game_server/src/server.rs b/game_server/src/server.rs index a4b1ed5..79cd322 100644 --- a/game_server/src/server.rs +++ b/game_server/src/server.rs @@ -55,6 +55,10 @@ impl GameClient { None } } + + fn host_name(&self) -> SocketAddr { + self.addr + } } type ClientConnection = Result; @@ -90,12 +94,13 @@ impl GameServer { std::thread::spawn(move || { let token = client.require_token(); if let Some(token) = token { - println!("Token: {}", token); let locked_backend = backend.lock().unwrap(); let result = locked_backend.validate_token(&token); if let Err(err) = result { - warn!("token {} is invalid: '{:?}'", token, err); + warn!("client's token {} is not valid: '{:?}'", token, err); } else { + debug!("client validation was successfull"); + debug!("add client: ({}, {})", token, client.host_name()); clients.lock().unwrap().insert(token, client); } } else { diff --git a/game_server/src/ws_test.html b/game_server/src/ws_test.html index ea259b7..f802327 100644 --- a/game_server/src/ws_test.html +++ b/game_server/src/ws_test.html @@ -26,7 +26,8 @@ function test_connection() { ws.addEventListener('open', function (event) { add_text('connection established'); toggle_connected(true); - ws.send('1230123'); + // send token + ws.send('42'); }); ws.addEventListener('error', function (event) { add_text('ws error occured: "' + event + '"'); -- cgit v1.2.3-54-g00ecf From 2d815af3f6d062d55da2f2598ce5d506ee74cb6e Mon Sep 17 00:00:00 2001 From: natrixaeria Date: Sun, 19 May 2019 18:44:04 +0200 Subject: Refactor code --- game_server/src/backend_connection.rs | 10 +--------- game_server/src/main.rs | 2 -- game_server/src/server.rs | 7 +++---- 3 files changed, 4 insertions(+), 15 deletions(-) diff --git a/game_server/src/backend_connection.rs b/game_server/src/backend_connection.rs index 4a12439..ed112d9 100644 --- a/game_server/src/backend_connection.rs +++ b/game_server/src/backend_connection.rs @@ -18,10 +18,6 @@ pub enum BackendError { BadResponse(Response), } -struct TokenResponseStruct { - -} - pub type TokenValidity = Result<(), BackendError>; pub type RequestData = Url; pub type ResponseResult = Result; @@ -59,14 +55,10 @@ impl BackendConnection { self.res_rec.recv().unwrap() } - pub fn host_name<'a>(&'a self) -> &'a str { - &self.host - } - pub fn validate_token(&self, token: &Token) -> TokenValidity { let location = format!("/api/lobby/tokens/{}", token); self.request(&location).map_err(|err| BackendError::UrlError(err))?; - let mut response = self.get_response().map_err(|err| BackendError::RequestError(err))?; + let response = self.get_response().map_err(|err| BackendError::RequestError(err))?; if response.status().is_success() { Ok(()) } else if response.status() == reqwest::StatusCode::NOT_FOUND { diff --git a/game_server/src/main.rs b/game_server/src/main.rs index 4d05efe..628062e 100644 --- a/game_server/src/main.rs +++ b/game_server/src/main.rs @@ -8,8 +8,6 @@ mod game_logger; #[macro_use] extern crate log; -use backend_connection::BackendConnection; - fn main() { game_logger::init_logger(); diff --git a/game_server/src/server.rs b/game_server/src/server.rs index 79cd322..7a9c5b0 100644 --- a/game_server/src/server.rs +++ b/game_server/src/server.rs @@ -1,7 +1,7 @@ use websocket::{OwnedMessage, sync::Server, client::sync::Client, - server::{NoTlsAcceptor, InvalidConnection, + server::{NoTlsAcceptor, sync::AcceptResult}}; use std::net::{SocketAddr, ToSocketAddrs, TcpStream}; use std::sync::{mpsc, @@ -82,10 +82,9 @@ impl GameServer { pub fn run(&self) -> Result<(), GameServerError> { let reader = self.read_clients(); loop { - let mut connection = reader.recv().unwrap()?; + let connection = reader.recv().unwrap()?; self.add_client(connection); } - Ok(()) } fn add_client(&self, mut client: GameClient) { @@ -160,7 +159,7 @@ impl GameServer { } } }, - Err(e) => { + Err(_) => { warn!("invalid client request"); Err(GameServerError::HandshakeRequestError) } -- cgit v1.2.3-54-g00ecf From 054a2bfe069ed4118d2f9fd1f01428632049057b Mon Sep 17 00:00:00 2001 From: natrixaeria Date: Sun, 19 May 2019 22:38:25 +0200 Subject: Add a client handling system --- game_server/src/backend_connection.rs | 21 +++++++++++++--- game_server/src/group.rs | 8 +++++- game_server/src/lobby.rs | 30 ++++++++++++++++++++-- game_server/src/main.rs | 4 +-- game_server/src/scribble_group.rs | 42 +++++++++++++++++++++++++++++++ game_server/src/server.rs | 47 +++++++++++++++++++---------------- game_server/src/test_group.rs | 28 --------------------- 7 files changed, 122 insertions(+), 58 deletions(-) create mode 100644 game_server/src/scribble_group.rs delete mode 100644 game_server/src/test_group.rs diff --git a/game_server/src/backend_connection.rs b/game_server/src/backend_connection.rs index ed112d9..e1844ee 100644 --- a/game_server/src/backend_connection.rs +++ b/game_server/src/backend_connection.rs @@ -1,7 +1,8 @@ use reqwest::{Response, Client, Url, UrlError, Error as ReqError}; use std::sync::mpsc::{Sender, Receiver}; use std::sync::mpsc; -use super::server::Token; +use super::server::{UserId, Token}; +use super::group::GroupId; pub struct BackendConnection { host: String, @@ -18,10 +19,17 @@ pub enum BackendError { BadResponse(Response), } -pub type TokenValidity = Result<(), BackendError>; +pub type TokenValidity = Result; pub type RequestData = Url; pub type ResponseResult = Result; +pub struct TokenResponse { + pub group_id: GroupId, + pub group_type: String, + pub group_name: String, + pub user_id: UserId, +} + impl BackendConnection { fn run_background(req_rec: Receiver, res_sender: Sender) { let client = Client::new(); @@ -60,7 +68,14 @@ impl BackendConnection { self.request(&location).map_err(|err| BackendError::UrlError(err))?; let response = self.get_response().map_err(|err| BackendError::RequestError(err))?; if response.status().is_success() { - Ok(()) + // zu Testzwecken werden noch keine JSON-Daten deserialisiert + // Dennis Server gibt ja noch nix zurück + Ok(TokenResponse { + group_id: 12, + group_type: "scribble".to_string(), + group_name: "Scribble".to_string(), + user_id: 420 + }) } else if response.status() == reqwest::StatusCode::NOT_FOUND { Err(BackendError::InvalidToken) } else if response.status().is_client_error() { diff --git a/game_server/src/group.rs b/game_server/src/group.rs index 55e4fbf..6356a14 100644 --- a/game_server/src/group.rs +++ b/game_server/src/group.rs @@ -1,8 +1,14 @@ +use super::server::{UserId, GameClient}; + pub type GroupId = u32; pub trait Group { fn id(&self) -> GroupId; + fn group_type(&self) -> String; fn name(&self) -> String; - fn run(&self); + fn run(&mut self); + + fn add_client(&mut self, id: UserId, client: GameClient); + fn get_client(&self, client_id: UserId) -> Option<&GameClient>; } diff --git a/game_server/src/lobby.rs b/game_server/src/lobby.rs index fe3bdee..d03bd45 100644 --- a/game_server/src/lobby.rs +++ b/game_server/src/lobby.rs @@ -1,23 +1,49 @@ use std::collections::HashMap; use super::group::{Group, GroupId}; +use super::scribble_group::ScribbleGroup; + +use super::server::{UserId, GameClient}; pub struct Lobby { groups: HashMap>, } impl Lobby { - pub fn new() -> Lobby { + pub fn new() -> Self { Self { groups: HashMap::new(), } } + fn generate_group(group_type: &str, id: GroupId, name: &str) -> Option> { + match group_type { + "scribble" => { + Some(Box::new(ScribbleGroup::new(id, name.to_string()))) + }, + other => None, + } + } + pub fn add_group(&mut self, group: Box) { self.groups.insert(group.id(), group); } - pub fn iter<'a>(&'a self) -> GroupIterator<'a> { + pub fn add_client(&mut self, group_type: &str, group_id: GroupId, group_name: &str, + user_id: UserId, client: GameClient) { + if !self.groups.contains_key(&group_id) { + let mut group = match Self::generate_group(group_type, group_id, group_name) { + Some(x) => x, + _ => return, + }; + group.run(); + self.groups.insert(group_id, group); + } + let group = self.groups.get_mut(&group_id).unwrap(); + group.add_client(user_id, client); + } + + pub fn iter<'b>(&'b self) -> GroupIterator<'b> { GroupIterator { groups: self.groups.values() } } } diff --git a/game_server/src/main.rs b/game_server/src/main.rs index 628062e..8ff8f97 100644 --- a/game_server/src/main.rs +++ b/game_server/src/main.rs @@ -1,5 +1,5 @@ mod group; -mod test_group; +mod scribble_group; mod lobby; mod server; mod backend_connection; @@ -13,7 +13,7 @@ fn main() { let addr = ("127.0.0.1", 5001); info!("create game server on {:?}", addr); - let gameserver = server::GameServer::new(addr); + let mut gameserver = server::GameServer::new(addr); gameserver.run().unwrap(); } diff --git a/game_server/src/scribble_group.rs b/game_server/src/scribble_group.rs new file mode 100644 index 0000000..c240264 --- /dev/null +++ b/game_server/src/scribble_group.rs @@ -0,0 +1,42 @@ +use super::group::{Group, GroupId}; +use super::server::{UserId, GameClient}; +use std::collections::HashMap; + +pub struct ScribbleGroup { + id: GroupId, + name: String, + clients: HashMap +} + +impl Group for ScribbleGroup { + fn id(&self) -> GroupId { + self.id + } + + fn group_type(&self) -> String { + "scribble".to_string() + } + + fn name(&self) -> String { + self.name.clone() + } + + fn run(&mut self) { + info!("a new group {}:'{}' runs now", self.id, self.name); + } + + fn add_client(&mut self, id: UserId, client: GameClient) { + debug!("user {} joined the group {}:'{}'", id, self.id, self.name); + self.clients.insert(id, client); + } + + fn get_client(&self, client_id: UserId) -> Option<&GameClient> { + self.clients.get(&client_id) + } +} + +impl ScribbleGroup { + pub fn new(id: GroupId, name: String) -> Self { + Self { id, name, clients: HashMap::new() } + } +} diff --git a/game_server/src/server.rs b/game_server/src/server.rs index 7a9c5b0..c87594b 100644 --- a/game_server/src/server.rs +++ b/game_server/src/server.rs @@ -14,6 +14,7 @@ use super::backend_connection::BackendConnection; const PROTOCOL: &str = "tuesday"; pub type Token = u32; +pub type UserId = u32; #[derive(Debug)] pub enum GameServerError { @@ -26,8 +27,7 @@ pub enum GameServerError { pub struct GameServer { addr: SocketAddr, lobby: Lobby, - backend: Arc>, - clients: Arc>>, + backend: BackendConnection, } pub struct GameClient { @@ -73,13 +73,12 @@ impl GameServer { info!("got a C# backend connection"); GameServer { addr, - lobby, - backend: Arc::new(Mutex::new(backend)), - clients: Arc::new(Mutex::new(HashMap::new())), + lobby: lobby, + backend: backend, } } - pub fn run(&self) -> Result<(), GameServerError> { + pub fn run(&mut self) -> Result<(), GameServerError> { let reader = self.read_clients(); loop { let connection = reader.recv().unwrap()?; @@ -87,25 +86,29 @@ impl GameServer { } } - fn add_client(&self, mut client: GameClient) { - let clients = Arc::clone(&self.clients); - let backend = Arc::clone(&self.backend); - std::thread::spawn(move || { - let token = client.require_token(); - if let Some(token) = token { - let locked_backend = backend.lock().unwrap(); - let result = locked_backend.validate_token(&token); - if let Err(err) = result { - warn!("client's token {} is not valid: '{:?}'", token, err); - } else { + fn add_client(&mut self, mut client: GameClient) { + let token = client.require_token(); + if let Some(token) = token { + let result = self.backend.validate_token(&token); + match result { + Err(err) => warn!("client's token {} is not valid: '{:?}'", + token, err), + Ok(result) => { debug!("client validation was successfull"); - debug!("add client: ({}, {})", token, client.host_name()); - clients.lock().unwrap().insert(token, client); + let user_id = result.user_id; + let group_id = result.group_id; + let group_type = result.group_type; + let group_name = result.group_name; + debug!("add client: (id:{}, token:{}, host:{}) to \"{}\"", + user_id, token, client.host_name(), group_name); + //clients.lock().unwrap().insert(token, client); + self.lobby.add_client(&group_type, group_id, + &group_name, user_id, client); } - } else { - warn!("client sent invalid token"); } - }); + } else { + warn!("client sent invalid token"); + } } fn read_clients(&self) -> Receiver { diff --git a/game_server/src/test_group.rs b/game_server/src/test_group.rs deleted file mode 100644 index bd570e3..0000000 --- a/game_server/src/test_group.rs +++ /dev/null @@ -1,28 +0,0 @@ -use super::group::{Group, GroupId}; - -pub struct TestGroup { - id: GroupId, - name: String, -} - -impl Group for TestGroup { - fn id(&self) -> GroupId { - self.id - } - - fn name(&self) -> String { - self.name.clone() - } - - fn run(&self) { - let id = self.id; - let name = self.name.to_owned(); - std::thread::spawn(move || /*loop { println!("> group nr.{} wishes you: '{}'", id, name) }*/()); - } -} - -impl TestGroup { - pub fn new(id: GroupId, name: String) -> Self { - TestGroup { id, name } - } -} -- cgit v1.2.3-54-g00ecf From c7bc91ecd6c32afab52c5e45b569e3945bdd1056 Mon Sep 17 00:00:00 2001 From: natrixaeria Date: Mon, 20 May 2019 18:27:26 +0200 Subject: Broadcast all text packets around clients --- game_server/src/backend_connection.rs | 7 +++++-- game_server/src/group.rs | 1 - game_server/src/main.rs | 2 +- game_server/src/scribble_group.rs | 29 +++++++++++++++++++++-------- game_server/src/server.rs | 15 ++++++++++++--- game_server/src/ws_test.html | 7 ++++++- 6 files changed, 45 insertions(+), 16 deletions(-) diff --git a/game_server/src/backend_connection.rs b/game_server/src/backend_connection.rs index e1844ee..d32c58e 100644 --- a/game_server/src/backend_connection.rs +++ b/game_server/src/backend_connection.rs @@ -8,6 +8,7 @@ pub struct BackendConnection { host: String, req_sender: Sender, res_rec: Receiver, + max_uid: u32, } #[derive(Debug)] @@ -52,6 +53,7 @@ impl BackendConnection { host: host.to_string(), req_sender, res_rec, + max_uid: 420, } } @@ -63,18 +65,19 @@ impl BackendConnection { self.res_rec.recv().unwrap() } - pub fn validate_token(&self, token: &Token) -> TokenValidity { + pub fn validate_token(&mut self, token: &Token) -> TokenValidity { let location = format!("/api/lobby/tokens/{}", token); self.request(&location).map_err(|err| BackendError::UrlError(err))?; let response = self.get_response().map_err(|err| BackendError::RequestError(err))?; if response.status().is_success() { // zu Testzwecken werden noch keine JSON-Daten deserialisiert // Dennis Server gibt ja noch nix zurück + self.max_uid += 1; Ok(TokenResponse { group_id: 12, group_type: "scribble".to_string(), group_name: "Scribble".to_string(), - user_id: 420 + user_id: self.max_uid - 1, }) } else if response.status() == reqwest::StatusCode::NOT_FOUND { Err(BackendError::InvalidToken) diff --git a/game_server/src/group.rs b/game_server/src/group.rs index 6356a14..fcda12a 100644 --- a/game_server/src/group.rs +++ b/game_server/src/group.rs @@ -10,5 +10,4 @@ pub trait Group { fn run(&mut self); fn add_client(&mut self, id: UserId, client: GameClient); - fn get_client(&self, client_id: UserId) -> Option<&GameClient>; } diff --git a/game_server/src/main.rs b/game_server/src/main.rs index 8ff8f97..ab73a97 100644 --- a/game_server/src/main.rs +++ b/game_server/src/main.rs @@ -11,7 +11,7 @@ mod game_logger; fn main() { game_logger::init_logger(); - let addr = ("127.0.0.1", 5001); + let addr = ("0.0.0.0", 5001); info!("create game server on {:?}", addr); let mut gameserver = server::GameServer::new(addr); gameserver.run().unwrap(); diff --git a/game_server/src/scribble_group.rs b/game_server/src/scribble_group.rs index c240264..e68c6df 100644 --- a/game_server/src/scribble_group.rs +++ b/game_server/src/scribble_group.rs @@ -1,11 +1,13 @@ use super::group::{Group, GroupId}; -use super::server::{UserId, GameClient}; +use super::server::{UserId, GameClient, + ClientSender, ClientReceiver}; use std::collections::HashMap; +use std::sync::{Arc, Mutex}; pub struct ScribbleGroup { id: GroupId, name: String, - clients: HashMap + senders: Arc>> } impl Group for ScribbleGroup { @@ -27,16 +29,27 @@ impl Group for ScribbleGroup { fn add_client(&mut self, id: UserId, client: GameClient) { debug!("user {} joined the group {}:'{}'", id, self.id, self.name); - self.clients.insert(id, client); - } - - fn get_client(&self, client_id: UserId) -> Option<&GameClient> { - self.clients.get(&client_id) + let (sen, mut rec) = client.split(); + self.senders.lock().unwrap().insert(id, sen); + let senders_mutex = self.senders.clone(); + let self_uid = id; + std::thread::spawn(move || { + loop { + let message = rec.recv_message().unwrap(); + info!("got message: '{:?}'", message); + let mut senders = senders_mutex.lock().unwrap(); + for (uid, sender) in senders.iter_mut() { + if self_uid != *uid { + sender.send_message(&message); + } + } + } + }); } } impl ScribbleGroup { pub fn new(id: GroupId, name: String) -> Self { - Self { id, name, clients: HashMap::new() } + Self { id, name, senders: Arc::new(Mutex::new(HashMap::new())) } } } diff --git a/game_server/src/server.rs b/game_server/src/server.rs index c87594b..6294e2c 100644 --- a/game_server/src/server.rs +++ b/game_server/src/server.rs @@ -1,16 +1,20 @@ use websocket::{OwnedMessage, + stream::sync::Splittable, sync::Server, client::sync::Client, server::{NoTlsAcceptor, - sync::AcceptResult}}; + sync::AcceptResult}, + receiver, sender}; use std::net::{SocketAddr, ToSocketAddrs, TcpStream}; use std::sync::{mpsc, - mpsc::{Sender, Receiver}, - Arc, Mutex}; + mpsc::{Sender, Receiver}}; use std::collections::HashMap; use super::lobby::Lobby; use super::backend_connection::BackendConnection; +pub type ClientReceiver = receiver::Reader<::Reader>; +pub type ClientSender = sender::Writer<::Writer>; + const PROTOCOL: &str = "tuesday"; pub type Token = u32; @@ -59,6 +63,11 @@ impl GameClient { fn host_name(&self) -> SocketAddr { self.addr } + + pub fn split(self) -> (ClientSender, ClientReceiver) { + let (mut rec, mut sen) = self.client.split().unwrap(); + (sen, rec) + } } type ClientConnection = Result; diff --git a/game_server/src/ws_test.html b/game_server/src/ws_test.html index f802327..ee60b65 100644 --- a/game_server/src/ws_test.html +++ b/game_server/src/ws_test.html @@ -12,6 +12,7 @@
connected


Server address: + Message
+ + + +
+
+

+ +
+ + diff --git a/scribble/mainstyle.css b/scribble/mainstyle.css new file mode 100644 index 0000000..82045d1 --- /dev/null +++ b/scribble/mainstyle.css @@ -0,0 +1,53 @@ +body { + padding: 0,2; + margin: 0; + background: #222222; +} +.wrapper { + max-width: 900px; + margin: auto; + font-family: "Arial"; +} + +.toolbar{ + width: 100%; + background-color: #440044; + overflow: auto; +} + +.toolbar a { + float: left; + width: 11%; + text-align: center; + padding: 6px 5px; + transition: all 0.5s ease; + color: white; +} + +/* Change color on hover */ +.toolbar a:hover { + background-color: #000; + } + +/* Change color on selected icon */ +.selected { + background-color: #000; +} + +#my-canvas{ + width: 100%; + background: white; + border: 3px solid #000000; +} + +#img-data-div{ + width: 100%; + max-width: 900px; + height: 200px; +} + +/* Resize image to container */ +.toolbar a img{ + max-width:100%; + height:auto; +} diff --git a/scribble/script.js b/scribble/script.js new file mode 100644 index 0000000..75173ae --- /dev/null +++ b/scribble/script.js @@ -0,0 +1,215 @@ +const socket = new WebSocket("ws://localhost:5001", "tuesday"); + +//var exampleSocket = new WebSocket("ws://192.168.3.42:5001", "tuesday"); +socket.onopen = function (event) { + console.log("Connection established"); + // Display user friendly messages for the successful establishment of connection + socket.send("42"); +}; +socket.onmessage = function (event) { + console.log(event.data); + AddBrushPoint(JSON.parse(event.data)); + DrawBrush(); + SaveCanvasImage(); + RedrawCanvasImage(); +}; +window.onbeforeunload = function () { + socket.onclose = function () { }; // disable onclose handler first + console.log("Connection terminated"); + socket.close(); +}; + +let canvas; +let context; +let savedImageData; +let dragging = false; +let strokeColor = 'black'; +let fillColor = 'black'; +let color = 'black'; +let lineWidth = 2; +let currentTool = "brush"; +let canvasHeight = 1000; +let canvasWidth = 1000; + +let usingBrush = false; +let brushPoints = new Array(); + +class ShapeBoundingBox { + constructor(left, top, width, height) { + this.left = left; + this.top = top; + this.width = width; + this.height = height; + } +} + +class DrawPoint { + constructor(x, y, mouseDown) { + this.x = x; + this.y = y; + this.mouseDown = mouseDown; + } +} + +class MouseDownPos { + constructor(x, y) { + this.x = x; + this.y = y; + } +} + +class Location { + constructor(x, y) { + this.x = x; + this.y = y; + } +} + + +let shapeBoundingBox = new ShapeBoundingBox(0, 0, 0, 0); +let mousedown = new MouseDownPos(0, 0); +let loc = new Location(0, 0); + +document.addEventListener('DOMContentLoaded', setupCanvas); + +function setupCanvas() { + canvas = document.getElementById('my-canvas'); + context = canvas.getContext('2d'); + context.strokeStyles = strokeColor; + context.lineWidth = lineWidth; + canvas.addEventListener("mousedown", ReactToMouseDown); + canvas.addEventListener("mousemove", ReactToMouseMove); + canvas.addEventListener("mouseup", ReactToMouseUp); +} + + +function GetMousePosition(x, y) { + let canvasSizeData = canvas.getBoundingClientRect(); + return { + x: (x - canvasSizeData.left) * (canvas.width / canvasSizeData.width), + y: (y - canvasSizeData.top) * (canvas.height / canvasSizeData.height) + }; +} + +function SaveCanvasImage() { + savedImageData = context.getImageData(0, 0, canvas.width, canvas.height); +} + +function RedrawCanvasImage() { + context.putImageData(savedImageData, 0, 0); +} + +function UpdateRubberbandSizeData(location) { + shapeBoundingBox.width = Math.abs(location.x - mousedown.x); + shapeBoundingBox.height = Math.abs(location.y - mousedown.y); + + if (location.x > mousedown.x) { + shapeBoundingBox.left = mousedown.x; + } else { + shapeBoundingBox.left = location.x; + } + if (location.y > mousedown.y) { + shapeBoundingBox.top = mousedown.y; + } else { + shapeBoundingBox.top = location.y; + } +} + +function AddNetBrushPoint(x, y, mouseDown) { + let point = new DrawPoint(x, y, mouseDown); + socket.send(JSON.stringify(point)); + + AddBrushPoint(point); +} + +function AddBrushPoint(point) { + brushPoints.push(point); +} + +function DrawBrush() { + for (let i = 1; i < brushPoints.length; i++) { + context.beginPath(); + if (brushPoints[i].mouseDown) { + context.moveTo(brushPoints[i - 1].x, brushPoints[i - 1].y); + } else { + context.moveTo(brushPoints[i].x - 1, brushPoints[i].y); + } + context.lineTo(brushPoints[i].x, brushPoints[i].y) + context.closePath(); + context.stroke(); + } +} + +function UpdateRubberbandOnMove(location) { + UpdateRubberbandSizeData(location); + drawRubberbandShape(location); +} + +function drawRubberbandShape(location) { + context.strokeStyle = strokeColor; + context.fillStyle = fillColor; + + if (currentTool === "brush") { + DrawBrush(); + } else if (currentTool === "line") { + context.beginPath(); + context.moveTo(mousedown.x, mousedown.y); + context.lineTo(location.x, location.y); + context.closePath(); + context.stroke(); + } else if (currentTool === "rectangle") { + context.strokeRect(shapeBoundingBox.left, shapeBoundingBox.top, + shapeBoundingBox.width, shapeBoundingBox.height); + } +} + +function ReactToMouseDown(e) { + // Change the mouse pointer to a crosshair + canvas.style.cursor = "crosshair"; + // Store location + loc = GetMousePosition(e.clientX, e.clientY); + // Save the current canvas image + SaveCanvasImage(); + // Store mouse position when clicked + mousedown.x = loc.x; + mousedown.y = loc.y; + // Store that yes the mouse is being held down + dragging = true; + + if (currentTool === "brush") { + usingBrush = true; + AddNetBrushPoint(mousedown.x, mousedown.y); + } +}; + +function ReactToMouseMove(e) { + canvas.style.cursor = "crosshair"; + loc = GetMousePosition(e.clientX, e.clientY); + + if (currentTool === "brush" && dragging && usingBrush) { + if (loc.x > 0 && loc.x < canvasWidth && loc.y > 0 && loc.y < canvasHeight) { + AddNetBrushPoint(loc.x, loc.y, true); + } + RedrawCanvasImage(); + DrawBrush(); + } else if (dragging) { + RedrawCanvasImage(); + UpdateRubberbandOnMove(loc); + } +}; + +function ReactToMouseUp(e) { + canvas.style.cursor = "default"; + loc = GetMousePosition(e.clientX, e.clientY); + RedrawCanvasImage(); + UpdateRubberbandOnMove(loc); + dragging = false; + usingBrush = false; + + brushXPoints = new Array(); + brushYPoints = new Array(); + brushDownPos = new Array(); + if (currentTool === "brush") { + AddBrushPoint(loc.x, loc.y); + } +} -- cgit v1.2.3-54-g00ecf From 59b185a10091c80259e49e3e16d8903e8cd68add Mon Sep 17 00:00:00 2001 From: Dennis Kobert Date: Wed, 22 May 2019 16:21:46 +0200 Subject: Execute wasm-pack --- WebInterface/wasm/asm-paint/.gitignore | 6 ++++ WebInterface/wasm/asm-paint/Cargo.toml | 34 ++++++++++++++++++++ WebInterface/wasm/asm-paint/README.md | 53 ++++++++++++++++++++++++++++++++ WebInterface/wasm/asm-paint/src/lib.rs | 19 ++++++++++++ WebInterface/wasm/asm-paint/src/utils.rs | 10 ++++++ WebInterface/wasm/asm-paint/tests/web.rs | 13 ++++++++ 6 files changed, 135 insertions(+) create mode 100644 WebInterface/wasm/asm-paint/.gitignore create mode 100644 WebInterface/wasm/asm-paint/Cargo.toml create mode 100644 WebInterface/wasm/asm-paint/README.md create mode 100644 WebInterface/wasm/asm-paint/src/lib.rs create mode 100644 WebInterface/wasm/asm-paint/src/utils.rs create mode 100644 WebInterface/wasm/asm-paint/tests/web.rs diff --git a/WebInterface/wasm/asm-paint/.gitignore b/WebInterface/wasm/asm-paint/.gitignore new file mode 100644 index 0000000..4e30131 --- /dev/null +++ b/WebInterface/wasm/asm-paint/.gitignore @@ -0,0 +1,6 @@ +/target +**/*.rs.bk +Cargo.lock +bin/ +pkg/ +wasm-pack.log diff --git a/WebInterface/wasm/asm-paint/Cargo.toml b/WebInterface/wasm/asm-paint/Cargo.toml new file mode 100644 index 0000000..619630b --- /dev/null +++ b/WebInterface/wasm/asm-paint/Cargo.toml @@ -0,0 +1,34 @@ +[package] +name = "asm-paint" +version = "0.1.0" +authors = ["Dennis Kobert "] +edition = "2018" + +[lib] +crate-type = ["cdylib", "rlib"] + +[features] +default = ["console_error_panic_hook"] + +[dependencies] +wasm-bindgen = "0.2" + +# The `console_error_panic_hook` crate provides better debugging of panics by +# logging them with `console.error`. This is great for development, but requires +# all the `std::fmt` and `std::panicking` infrastructure, so isn't great for +# code size when deploying. +console_error_panic_hook = { version = "0.1.1", optional = true } + +# `wee_alloc` is a tiny allocator for wasm that is only ~1K in code size +# compared to the default allocator's ~10K. It is slower than the default +# allocator, however. +# +# Unfortunately, `wee_alloc` requires nightly Rust when targeting wasm for now. +wee_alloc = { version = "0.4.2", optional = true } + +[dev-dependencies] +wasm-bindgen-test = "0.2" + +[profile.release] +# Tell `rustc` to optimize for small code size. +opt-level = "s" diff --git a/WebInterface/wasm/asm-paint/README.md b/WebInterface/wasm/asm-paint/README.md new file mode 100644 index 0000000..5fcb76f --- /dev/null +++ b/WebInterface/wasm/asm-paint/README.md @@ -0,0 +1,53 @@ +# 🦀🕸️ `wasm-pack-template` + +A template for kick starting a Rust and WebAssembly project using +[`wasm-pack`](https://github.com/rustwasm/wasm-pack). + +[**📚 Read this template tutorial! 📚**][template-docs] + +This template is designed for compiling Rust libraries into WebAssembly and +publishing the resulting package to NPM. + +Be sure to check out [other `wasm-pack` tutorials online][tutorials] for other +templates and usages of `wasm-pack`. + +[tutorials]: https://rustwasm.github.io/docs/wasm-pack/tutorials/index.html +[template-docs]: https://rustwasm.github.io/docs/wasm-pack/tutorials/npm-browser-packages/index.html + +## 🚴 Usage + +### 🐑 Use `cargo generate` to Clone this Template + +[Learn more about `cargo generate` here.](https://github.com/ashleygwilliams/cargo-generate) + +``` +cargo generate --git https://github.com/rustwasm/wasm-pack-template.git --name my-project +cd my-project +``` + +### 🛠️ Build with `wasm-pack build` + +``` +wasm-pack build +``` + +### 🔬 Test in Headless Browsers with `wasm-pack test` + +``` +wasm-pack test --headless --firefox +``` + +### 🎁 Publish to NPM with `wasm-pack publish` + +``` +wasm-pack publish +``` + +## 🔋 Batteries Included + +* [`wasm-bindgen`](https://github.com/rustwasm/wasm-bindgen) for communicating + between WebAssembly and JavaScript. +* [`console_error_panic_hook`](https://github.com/rustwasm/console_error_panic_hook) + for logging panic messages to the developer console. +* [`wee_alloc`](https://github.com/rustwasm/wee_alloc), an allocator optimized + for small code size. diff --git a/WebInterface/wasm/asm-paint/src/lib.rs b/WebInterface/wasm/asm-paint/src/lib.rs new file mode 100644 index 0000000..908b857 --- /dev/null +++ b/WebInterface/wasm/asm-paint/src/lib.rs @@ -0,0 +1,19 @@ +mod utils; + +use wasm_bindgen::prelude::*; + +// When the `wee_alloc` feature is enabled, use `wee_alloc` as the global +// allocator. +#[cfg(feature = "wee_alloc")] +#[global_allocator] +static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT; + +#[wasm_bindgen] +extern { + fn log(s: &str); +} + +#[wasm_bindgen] +pub fn greet() { + log("Hello, asm-paint!"); +} diff --git a/WebInterface/wasm/asm-paint/src/utils.rs b/WebInterface/wasm/asm-paint/src/utils.rs new file mode 100644 index 0000000..b1d7929 --- /dev/null +++ b/WebInterface/wasm/asm-paint/src/utils.rs @@ -0,0 +1,10 @@ +pub fn set_panic_hook() { + // When the `console_error_panic_hook` feature is enabled, we can call the + // `set_panic_hook` function at least once during initialization, and then + // we will get better error messages if our code ever panics. + // + // For more details see + // https://github.com/rustwasm/console_error_panic_hook#readme + #[cfg(feature = "console_error_panic_hook")] + console_error_panic_hook::set_once(); +} diff --git a/WebInterface/wasm/asm-paint/tests/web.rs b/WebInterface/wasm/asm-paint/tests/web.rs new file mode 100644 index 0000000..de5c1da --- /dev/null +++ b/WebInterface/wasm/asm-paint/tests/web.rs @@ -0,0 +1,13 @@ +//! Test suite for the Web and headless browsers. + +#![cfg(target_arch = "wasm32")] + +extern crate wasm_bindgen_test; +use wasm_bindgen_test::*; + +wasm_bindgen_test_configure!(run_in_browser); + +#[wasm_bindgen_test] +fn pass() { + assert_eq!(1 + 1, 2); +} -- cgit v1.2.3-54-g00ecf From 6ebf9428fb00811605f09c8f5be4d6454dc8c80d Mon Sep 17 00:00:00 2001 From: Dennis Kobert Date: Wed, 22 May 2019 19:48:05 +0200 Subject: Mode index.html up a dir --- WebInterface/wasm/asm-paint/index.html | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 WebInterface/wasm/asm-paint/index.html diff --git a/WebInterface/wasm/asm-paint/index.html b/WebInterface/wasm/asm-paint/index.html new file mode 100644 index 0000000..424255b --- /dev/null +++ b/WebInterface/wasm/asm-paint/index.html @@ -0,0 +1,14 @@ + + +
+ Scribblio + +
+ + + -- cgit v1.2.3-54-g00ecf From 1633d8a8b8191b9885af63a2314985842d4254f8 Mon Sep 17 00:00:00 2001 From: natrixaeria Date: Wed, 22 May 2019 20:05:41 +0200 Subject: Add a python-implemented test-webserver --- WebInterface/wasm/asm-paint/deploy.py | 99 +++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 WebInterface/wasm/asm-paint/deploy.py diff --git a/WebInterface/wasm/asm-paint/deploy.py b/WebInterface/wasm/asm-paint/deploy.py new file mode 100644 index 0000000..5410359 --- /dev/null +++ b/WebInterface/wasm/asm-paint/deploy.py @@ -0,0 +1,99 @@ +from socket import (socket, AF_INET, SOCK_STREAM, IPPROTO_TCP, + SOL_SOCKET, SO_REUSEADDR) +from threading import Thread + +WASM_MIME = 'application/wasm' +JS_MIME = 'application/javascript' +PLAIN_MIME = 'text/plain' +HTML_MIME = 'text/html' + +REQUESTS = { + '/': ('index.html', HTML_MIME), +# '/load_ws.js': ('load_ws.js', JS_MIME), + '/asm_paint_bg.wasm': ('pkg/asm_paint_bg.wasm', WASM_MIME) +} + +PAGE_404 = ''' + +

Request '404 Not Found'

+ resource
'{}'
not found
+ +''' + +def header_line_to_entry(line): + key, value = line.decode('utf-8').split(': ') + return key, value + + +class Server: + def __init__(self): + self.s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) + self.s.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) + self.threads = [] + + def rec_http(self, client): + headers = b'' + while not headers.endswith(b'\r\n' * 2): + headers += client.recv(1) + headers = headers.split(b'\r\n') + head, headers = headers[0], headers[1:] + method, url, _ = head.split(b' ') + url = url.decode('utf-8') + headers = dict(header_line_to_entry(v) for v in headers if v) + if 'Content-Length' in headers: + client.recv(int(headers['Content-Length'])) + return method, url, headers + + def sen_http(self, client, status='200 OK', payload=b'', mime=PLAIN_MIME): + print('sende...') + client.send((f'HTTP/1.1 {status}\r\n' + f'Content-Length: {len(payload)}\r\n' + f'Content-Type: {mime}\r\n\r\n').encode('utf-8') + + payload) + print('gesendet') + + def run_client(self, client, addr): + while True: + print('wait for receive') + method, url, headers = self.rec_http(client) + print('got receive') + if method == b'GET': + if not url.startswith('/'): + url += '/' + print(f'got request for "{url}"') + if url in REQUESTS: + path, mime = REQUESTS[url] + f = open(path, 'rb') + payload = f.read() + f.close() + self.sen_http(client, '200 OK', payload, mime) + elif url == '/close': + client.close() + self.kill() + exit() + else: + self.sen_http(client, '404 Not Found', + PAGE_404.format(url).encode('utf-8'), + HTML_MIME) + else: + self.sen_http(client, '400 Bad Request', b'only supporting GET') + + def deploy(self, host='localhost', port=8080): + self.s.bind((host, port)) + self.s.listen(1) + while True: + client, addr = self.s.accept() + thread = Thread(target=self.run_client, args=(client,addr)) + self.threads.append(thread) + thread.run() + + def kill(self): + self.s.close() + + +if __name__ == '__main__': + try: + server = Server() + server.deploy() + finally: + server.kill() -- cgit v1.2.3-54-g00ecf From e724788ce9345f6fb049d4de447657861ac46f69 Mon Sep 17 00:00:00 2001 From: natrixaeria Date: Wed, 22 May 2019 20:20:16 +0200 Subject: Load the wasm --- WebInterface/wasm/asm-paint/deploy.py | 2 +- WebInterface/wasm/asm-paint/index.html | 12 ++++-------- WebInterface/wasm/asm-paint/loader.js | 17 +++++++++++++++++ 3 files changed, 22 insertions(+), 9 deletions(-) create mode 100644 WebInterface/wasm/asm-paint/loader.js diff --git a/WebInterface/wasm/asm-paint/deploy.py b/WebInterface/wasm/asm-paint/deploy.py index 5410359..f81ebb8 100644 --- a/WebInterface/wasm/asm-paint/deploy.py +++ b/WebInterface/wasm/asm-paint/deploy.py @@ -9,7 +9,7 @@ HTML_MIME = 'text/html' REQUESTS = { '/': ('index.html', HTML_MIME), -# '/load_ws.js': ('load_ws.js', JS_MIME), + '/loader.js': ('loader.js', JS_MIME), '/asm_paint_bg.wasm': ('pkg/asm_paint_bg.wasm', WASM_MIME) } diff --git a/WebInterface/wasm/asm-paint/index.html b/WebInterface/wasm/asm-paint/index.html index 424255b..a0264cf 100644 --- a/WebInterface/wasm/asm-paint/index.html +++ b/WebInterface/wasm/asm-paint/index.html @@ -1,14 +1,10 @@ -
+ + Scribblio - -
+ + diff --git a/WebInterface/wasm/asm-paint/loader.js b/WebInterface/wasm/asm-paint/loader.js new file mode 100644 index 0000000..8348c35 --- /dev/null +++ b/WebInterface/wasm/asm-paint/loader.js @@ -0,0 +1,17 @@ +console.log('js> create import object'); +let importObject = { imports: { imported_func: arg => console.log(arg) } }; + +console.log('js> create fetch object'); + +let asm_paint_bg = fetch('asm_paint_bg.wasm'); + +console.log('js> instantiate streaming'); + +function and_then(obj) { + console.log('js> reached instantiate streaming\'s then'); + return obj.instance.exports.exported_func(); +} + +WebAssembly.instantiateStreaming(asm_paint_bg, importObject) + .then(and_then); + -- cgit v1.2.3-54-g00ecf From 9cc2841cf49a6180dc9426892d11e957142e88ea Mon Sep 17 00:00:00 2001 From: natrixaeria Date: Wed, 22 May 2019 20:55:43 +0200 Subject: Play around with wasm --- WebInterface/wasm/asm-paint/loader.js | 5 +++-- WebInterface/wasm/asm-paint/src/lib.rs | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/WebInterface/wasm/asm-paint/loader.js b/WebInterface/wasm/asm-paint/loader.js index 8348c35..7313fa0 100644 --- a/WebInterface/wasm/asm-paint/loader.js +++ b/WebInterface/wasm/asm-paint/loader.js @@ -1,5 +1,6 @@ console.log('js> create import object'); -let importObject = { imports: { imported_func: arg => console.log(arg) } }; +let importObject = { imports: { my_alert: arg => alert(arg) } }; +//let importObject = {}; console.log('js> create fetch object'); @@ -9,7 +10,7 @@ console.log('js> instantiate streaming'); function and_then(obj) { console.log('js> reached instantiate streaming\'s then'); - return obj.instance.exports.exported_func(); + return obj.instance.exports.greet(); } WebAssembly.instantiateStreaming(asm_paint_bg, importObject) diff --git a/WebInterface/wasm/asm-paint/src/lib.rs b/WebInterface/wasm/asm-paint/src/lib.rs index 908b857..a4f4f54 100644 --- a/WebInterface/wasm/asm-paint/src/lib.rs +++ b/WebInterface/wasm/asm-paint/src/lib.rs @@ -10,10 +10,10 @@ static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT; #[wasm_bindgen] extern { - fn log(s: &str); + fn my_alert(s: &str); } #[wasm_bindgen] pub fn greet() { - log("Hello, asm-paint!"); + my_alert("Hello, asm-paint!"); } -- cgit v1.2.3-54-g00ecf From 28c16ac6e6955b98f6485564d2c15f639bef5802 Mon Sep 17 00:00:00 2001 From: natrixaeria Date: Wed, 22 May 2019 22:00:23 +0200 Subject: Load wasm into the browser and execute it --- WebInterface/wasm/asm-paint/Cargo.toml | 27 --------------------------- WebInterface/wasm/asm-paint/deploy.py | 4 ++-- WebInterface/wasm/asm-paint/index.html | 2 +- WebInterface/wasm/asm-paint/loader.js | 18 ------------------ WebInterface/wasm/asm-paint/src/lib.rs | 19 ------------------- WebInterface/wasm/asm-paint/src/main.rs | 3 +++ WebInterface/wasm/asm-paint/src/utils.rs | 10 ---------- WebInterface/wasm/asm-paint/tests/web.rs | 13 ------------- 8 files changed, 6 insertions(+), 90 deletions(-) delete mode 100644 WebInterface/wasm/asm-paint/loader.js delete mode 100644 WebInterface/wasm/asm-paint/src/lib.rs create mode 100644 WebInterface/wasm/asm-paint/src/main.rs delete mode 100644 WebInterface/wasm/asm-paint/src/utils.rs delete mode 100644 WebInterface/wasm/asm-paint/tests/web.rs diff --git a/WebInterface/wasm/asm-paint/Cargo.toml b/WebInterface/wasm/asm-paint/Cargo.toml index 619630b..8a4cc92 100644 --- a/WebInterface/wasm/asm-paint/Cargo.toml +++ b/WebInterface/wasm/asm-paint/Cargo.toml @@ -4,31 +4,4 @@ version = "0.1.0" authors = ["Dennis Kobert "] edition = "2018" -[lib] -crate-type = ["cdylib", "rlib"] - -[features] -default = ["console_error_panic_hook"] - [dependencies] -wasm-bindgen = "0.2" - -# The `console_error_panic_hook` crate provides better debugging of panics by -# logging them with `console.error`. This is great for development, but requires -# all the `std::fmt` and `std::panicking` infrastructure, so isn't great for -# code size when deploying. -console_error_panic_hook = { version = "0.1.1", optional = true } - -# `wee_alloc` is a tiny allocator for wasm that is only ~1K in code size -# compared to the default allocator's ~10K. It is slower than the default -# allocator, however. -# -# Unfortunately, `wee_alloc` requires nightly Rust when targeting wasm for now. -wee_alloc = { version = "0.4.2", optional = true } - -[dev-dependencies] -wasm-bindgen-test = "0.2" - -[profile.release] -# Tell `rustc` to optimize for small code size. -opt-level = "s" diff --git a/WebInterface/wasm/asm-paint/deploy.py b/WebInterface/wasm/asm-paint/deploy.py index f81ebb8..ed4e0dd 100644 --- a/WebInterface/wasm/asm-paint/deploy.py +++ b/WebInterface/wasm/asm-paint/deploy.py @@ -9,8 +9,8 @@ HTML_MIME = 'text/html' REQUESTS = { '/': ('index.html', HTML_MIME), - '/loader.js': ('loader.js', JS_MIME), - '/asm_paint_bg.wasm': ('pkg/asm_paint_bg.wasm', WASM_MIME) + '/asm-paint.js': ('target/wasm32-unknown-emscripten/release/asm-paint.js', JS_MIME), + '/asm_paint.wasm': ('target/wasm32-unknown-emscripten/release/asm_paint.wasm', WASM_MIME), } PAGE_404 = ''' diff --git a/WebInterface/wasm/asm-paint/index.html b/WebInterface/wasm/asm-paint/index.html index a0264cf..b03a295 100644 --- a/WebInterface/wasm/asm-paint/index.html +++ b/WebInterface/wasm/asm-paint/index.html @@ -3,7 +3,7 @@ Scribblio - + diff --git a/WebInterface/wasm/asm-paint/loader.js b/WebInterface/wasm/asm-paint/loader.js deleted file mode 100644 index 7313fa0..0000000 --- a/WebInterface/wasm/asm-paint/loader.js +++ /dev/null @@ -1,18 +0,0 @@ -console.log('js> create import object'); -let importObject = { imports: { my_alert: arg => alert(arg) } }; -//let importObject = {}; - -console.log('js> create fetch object'); - -let asm_paint_bg = fetch('asm_paint_bg.wasm'); - -console.log('js> instantiate streaming'); - -function and_then(obj) { - console.log('js> reached instantiate streaming\'s then'); - return obj.instance.exports.greet(); -} - -WebAssembly.instantiateStreaming(asm_paint_bg, importObject) - .then(and_then); - diff --git a/WebInterface/wasm/asm-paint/src/lib.rs b/WebInterface/wasm/asm-paint/src/lib.rs deleted file mode 100644 index a4f4f54..0000000 --- a/WebInterface/wasm/asm-paint/src/lib.rs +++ /dev/null @@ -1,19 +0,0 @@ -mod utils; - -use wasm_bindgen::prelude::*; - -// When the `wee_alloc` feature is enabled, use `wee_alloc` as the global -// allocator. -#[cfg(feature = "wee_alloc")] -#[global_allocator] -static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT; - -#[wasm_bindgen] -extern { - fn my_alert(s: &str); -} - -#[wasm_bindgen] -pub fn greet() { - my_alert("Hello, asm-paint!"); -} diff --git a/WebInterface/wasm/asm-paint/src/main.rs b/WebInterface/wasm/asm-paint/src/main.rs new file mode 100644 index 0000000..0d01b18 --- /dev/null +++ b/WebInterface/wasm/asm-paint/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("hello wasm world!"); +} diff --git a/WebInterface/wasm/asm-paint/src/utils.rs b/WebInterface/wasm/asm-paint/src/utils.rs deleted file mode 100644 index b1d7929..0000000 --- a/WebInterface/wasm/asm-paint/src/utils.rs +++ /dev/null @@ -1,10 +0,0 @@ -pub fn set_panic_hook() { - // When the `console_error_panic_hook` feature is enabled, we can call the - // `set_panic_hook` function at least once during initialization, and then - // we will get better error messages if our code ever panics. - // - // For more details see - // https://github.com/rustwasm/console_error_panic_hook#readme - #[cfg(feature = "console_error_panic_hook")] - console_error_panic_hook::set_once(); -} diff --git a/WebInterface/wasm/asm-paint/tests/web.rs b/WebInterface/wasm/asm-paint/tests/web.rs deleted file mode 100644 index de5c1da..0000000 --- a/WebInterface/wasm/asm-paint/tests/web.rs +++ /dev/null @@ -1,13 +0,0 @@ -//! Test suite for the Web and headless browsers. - -#![cfg(target_arch = "wasm32")] - -extern crate wasm_bindgen_test; -use wasm_bindgen_test::*; - -wasm_bindgen_test_configure!(run_in_browser); - -#[wasm_bindgen_test] -fn pass() { - assert_eq!(1 + 1, 2); -} -- cgit v1.2.3-54-g00ecf From 233106ee4fc302579af0224611e55be5b1479f51 Mon Sep 17 00:00:00 2001 From: natrixaeria Date: Sat, 25 May 2019 00:35:30 +0200 Subject: Do shitty wasm shit --- WebInterface/wasm/asm-paint/build.sh | 2 ++ WebInterface/wasm/asm-paint/deploy.py | 1 + WebInterface/wasm/asm-paint/index.html | 1 + WebInterface/wasm/asm-paint/loader.js | 1 + WebInterface/wasm/asm-paint/src/main.rs | 13 ++++++++++++- 5 files changed, 17 insertions(+), 1 deletion(-) create mode 100755 WebInterface/wasm/asm-paint/build.sh create mode 100644 WebInterface/wasm/asm-paint/loader.js diff --git a/WebInterface/wasm/asm-paint/build.sh b/WebInterface/wasm/asm-paint/build.sh new file mode 100755 index 0000000..457d1d8 --- /dev/null +++ b/WebInterface/wasm/asm-paint/build.sh @@ -0,0 +1,2 @@ +#!/bin/sh +cargo build --target=wasm32-unknown-emscripten --release diff --git a/WebInterface/wasm/asm-paint/deploy.py b/WebInterface/wasm/asm-paint/deploy.py index ed4e0dd..fce7a02 100644 --- a/WebInterface/wasm/asm-paint/deploy.py +++ b/WebInterface/wasm/asm-paint/deploy.py @@ -9,6 +9,7 @@ HTML_MIME = 'text/html' REQUESTS = { '/': ('index.html', HTML_MIME), + '/loader.js': ('loader.js', JS_MIME), '/asm-paint.js': ('target/wasm32-unknown-emscripten/release/asm-paint.js', JS_MIME), '/asm_paint.wasm': ('target/wasm32-unknown-emscripten/release/asm_paint.wasm', WASM_MIME), } diff --git a/WebInterface/wasm/asm-paint/index.html b/WebInterface/wasm/asm-paint/index.html index b03a295..c47d89d 100644 --- a/WebInterface/wasm/asm-paint/index.html +++ b/WebInterface/wasm/asm-paint/index.html @@ -4,6 +4,7 @@ Scribblio + diff --git a/WebInterface/wasm/asm-paint/loader.js b/WebInterface/wasm/asm-paint/loader.js new file mode 100644 index 0000000..3e25291 --- /dev/null +++ b/WebInterface/wasm/asm-paint/loader.js @@ -0,0 +1 @@ +//Module. diff --git a/WebInterface/wasm/asm-paint/src/main.rs b/WebInterface/wasm/asm-paint/src/main.rs index 0d01b18..f8949ee 100644 --- a/WebInterface/wasm/asm-paint/src/main.rs +++ b/WebInterface/wasm/asm-paint/src/main.rs @@ -1,3 +1,14 @@ +use std::os::raw::c_int; + +#[no_mangle] +pub extern fn run_infinite() { + std::thread::spawn(move || { + loop { + println!("iterating infititely"); + } + }); +} + fn main() { - println!("hello wasm world!"); + println!("haha from wasm lol"); } -- cgit v1.2.3-54-g00ecf From 90be5f8d63e77ee51256270dec018e2c7448e115 Mon Sep 17 00:00:00 2001 From: natrixaeria Date: Sat, 25 May 2019 02:06:41 +0200 Subject: Resetup webassembly on the cool way --- WebInterface/wasm/asm-paint/Cargo.toml | 6 +++++- WebInterface/wasm/asm-paint/build.sh | 3 ++- WebInterface/wasm/asm-paint/deploy | 4 ++++ WebInterface/wasm/asm-paint/deploy.py | 6 ++++-- WebInterface/wasm/asm-paint/index.html | 3 +-- WebInterface/wasm/asm-paint/loader.js | 3 ++- WebInterface/wasm/asm-paint/src/lib.rs | 16 ++++++++++++++++ WebInterface/wasm/asm-paint/src/main.rs | 14 -------------- 8 files changed, 34 insertions(+), 21 deletions(-) create mode 100755 WebInterface/wasm/asm-paint/deploy mode change 100644 => 100755 WebInterface/wasm/asm-paint/deploy.py create mode 100644 WebInterface/wasm/asm-paint/src/lib.rs delete mode 100644 WebInterface/wasm/asm-paint/src/main.rs diff --git a/WebInterface/wasm/asm-paint/Cargo.toml b/WebInterface/wasm/asm-paint/Cargo.toml index 8a4cc92..c0a7c68 100644 --- a/WebInterface/wasm/asm-paint/Cargo.toml +++ b/WebInterface/wasm/asm-paint/Cargo.toml @@ -1,7 +1,11 @@ [package] -name = "asm-paint" +name = "asm-paint-rs" version = "0.1.0" authors = ["Dennis Kobert "] edition = "2018" +[lib] +crate-type = ["cdylib"] + [dependencies] +wasm-bindgen = "0.2" diff --git a/WebInterface/wasm/asm-paint/build.sh b/WebInterface/wasm/asm-paint/build.sh index 457d1d8..61c1997 100755 --- a/WebInterface/wasm/asm-paint/build.sh +++ b/WebInterface/wasm/asm-paint/build.sh @@ -1,2 +1,3 @@ #!/bin/sh -cargo build --target=wasm32-unknown-emscripten --release + +wasm-pack build --target web diff --git a/WebInterface/wasm/asm-paint/deploy b/WebInterface/wasm/asm-paint/deploy new file mode 100755 index 0000000..9f7f823 --- /dev/null +++ b/WebInterface/wasm/asm-paint/deploy @@ -0,0 +1,4 @@ +#!/bin/sh + +./build.sh +./deploy.py diff --git a/WebInterface/wasm/asm-paint/deploy.py b/WebInterface/wasm/asm-paint/deploy.py old mode 100644 new mode 100755 index fce7a02..b64c322 --- a/WebInterface/wasm/asm-paint/deploy.py +++ b/WebInterface/wasm/asm-paint/deploy.py @@ -1,3 +1,5 @@ +#!/usr/bin/env python3 + from socket import (socket, AF_INET, SOCK_STREAM, IPPROTO_TCP, SOL_SOCKET, SO_REUSEADDR) from threading import Thread @@ -10,8 +12,8 @@ HTML_MIME = 'text/html' REQUESTS = { '/': ('index.html', HTML_MIME), '/loader.js': ('loader.js', JS_MIME), - '/asm-paint.js': ('target/wasm32-unknown-emscripten/release/asm-paint.js', JS_MIME), - '/asm_paint.wasm': ('target/wasm32-unknown-emscripten/release/asm_paint.wasm', WASM_MIME), + '/asm_paint_rs.js': ('pkg/asm_paint_rs.js', JS_MIME), + '/asm_paint_rs_bg.wasm': ('pkg/asm_paint_rs_bg.wasm', WASM_MIME), } PAGE_404 = ''' diff --git a/WebInterface/wasm/asm-paint/index.html b/WebInterface/wasm/asm-paint/index.html index c47d89d..46be213 100644 --- a/WebInterface/wasm/asm-paint/index.html +++ b/WebInterface/wasm/asm-paint/index.html @@ -3,8 +3,7 @@ Scribblio - - + diff --git a/WebInterface/wasm/asm-paint/loader.js b/WebInterface/wasm/asm-paint/loader.js index 3e25291..f1d15ef 100644 --- a/WebInterface/wasm/asm-paint/loader.js +++ b/WebInterface/wasm/asm-paint/loader.js @@ -1 +1,2 @@ -//Module. +import {default as init} from './asm_paint_rs.js' +init('asm_paint_rs_bg.wasm'); diff --git a/WebInterface/wasm/asm-paint/src/lib.rs b/WebInterface/wasm/asm-paint/src/lib.rs new file mode 100644 index 0000000..52ddc8f --- /dev/null +++ b/WebInterface/wasm/asm-paint/src/lib.rs @@ -0,0 +1,16 @@ +use wasm_bindgen::prelude::*; + +macro_rules! console_log { + ($($t:tt)*) => (log(&format_args!($($t)*).to_string())) +} + +#[wasm_bindgen] +extern "C" { + #[wasm_bindgen(js_namespace = console)] + fn log(s: &str); +} + +#[wasm_bindgen(start)] +pub fn entry() { + console_log!("hello {} wasm", 42); +} diff --git a/WebInterface/wasm/asm-paint/src/main.rs b/WebInterface/wasm/asm-paint/src/main.rs deleted file mode 100644 index f8949ee..0000000 --- a/WebInterface/wasm/asm-paint/src/main.rs +++ /dev/null @@ -1,14 +0,0 @@ -use std::os::raw::c_int; - -#[no_mangle] -pub extern fn run_infinite() { - std::thread::spawn(move || { - loop { - println!("iterating infititely"); - } - }); -} - -fn main() { - println!("haha from wasm lol"); -} -- cgit v1.2.3-54-g00ecf From 04792563e216f57984219e582de491947e2d7f40 Mon Sep 17 00:00:00 2001 From: natrixaeria Date: Sat, 25 May 2019 02:40:00 +0200 Subject: Manipulate DOM --- WebInterface/wasm/asm-paint/Cargo.toml | 1 + WebInterface/wasm/asm-paint/src/lib.rs | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/WebInterface/wasm/asm-paint/Cargo.toml b/WebInterface/wasm/asm-paint/Cargo.toml index c0a7c68..5713415 100644 --- a/WebInterface/wasm/asm-paint/Cargo.toml +++ b/WebInterface/wasm/asm-paint/Cargo.toml @@ -9,3 +9,4 @@ crate-type = ["cdylib"] [dependencies] wasm-bindgen = "0.2" +web-sys = {version="0.3.22", features=["Window", "Document", "HtmlElement", "Node", "Element"]} diff --git a/WebInterface/wasm/asm-paint/src/lib.rs b/WebInterface/wasm/asm-paint/src/lib.rs index 52ddc8f..462a89d 100644 --- a/WebInterface/wasm/asm-paint/src/lib.rs +++ b/WebInterface/wasm/asm-paint/src/lib.rs @@ -12,5 +12,16 @@ extern "C" { #[wasm_bindgen(start)] pub fn entry() { + use web_sys; console_log!("hello {} wasm", 42); + + let window = web_sys::window().unwrap(); + + let document = window.document().unwrap(); + + let body = document.body().unwrap(); + + //body.set_inner_html("

Hello from WASM

"); + + body.set_inner_html("oho"); } -- cgit v1.2.3-54-g00ecf From d727f6e769ae6f3210a57f32f6c198469efaa9b8 Mon Sep 17 00:00:00 2001 From: natrixaeria Date: Sat, 25 May 2019 22:44:04 +0200 Subject: Run with lighttpd and remove deploy.py --- WebInterface/wasm/asm-paint/Cargo.toml | 1 - WebInterface/wasm/asm-paint/build.sh | 3 - WebInterface/wasm/asm-paint/deploy | 4 -- WebInterface/wasm/asm-paint/deploy.py | 102 ---------------------------- WebInterface/wasm/asm-paint/lighttpd.config | 29 ++++++++ WebInterface/wasm/asm-paint/loader.js | 4 +- WebInterface/wasm/asm-paint/run | 3 + WebInterface/wasm/asm-paint/src/lib.rs | 16 ++--- 8 files changed, 39 insertions(+), 123 deletions(-) delete mode 100755 WebInterface/wasm/asm-paint/build.sh delete mode 100755 WebInterface/wasm/asm-paint/deploy delete mode 100755 WebInterface/wasm/asm-paint/deploy.py create mode 100644 WebInterface/wasm/asm-paint/lighttpd.config create mode 100755 WebInterface/wasm/asm-paint/run diff --git a/WebInterface/wasm/asm-paint/Cargo.toml b/WebInterface/wasm/asm-paint/Cargo.toml index 5713415..c0a7c68 100644 --- a/WebInterface/wasm/asm-paint/Cargo.toml +++ b/WebInterface/wasm/asm-paint/Cargo.toml @@ -9,4 +9,3 @@ crate-type = ["cdylib"] [dependencies] wasm-bindgen = "0.2" -web-sys = {version="0.3.22", features=["Window", "Document", "HtmlElement", "Node", "Element"]} diff --git a/WebInterface/wasm/asm-paint/build.sh b/WebInterface/wasm/asm-paint/build.sh deleted file mode 100755 index 61c1997..0000000 --- a/WebInterface/wasm/asm-paint/build.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh - -wasm-pack build --target web diff --git a/WebInterface/wasm/asm-paint/deploy b/WebInterface/wasm/asm-paint/deploy deleted file mode 100755 index 9f7f823..0000000 --- a/WebInterface/wasm/asm-paint/deploy +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh - -./build.sh -./deploy.py diff --git a/WebInterface/wasm/asm-paint/deploy.py b/WebInterface/wasm/asm-paint/deploy.py deleted file mode 100755 index b64c322..0000000 --- a/WebInterface/wasm/asm-paint/deploy.py +++ /dev/null @@ -1,102 +0,0 @@ -#!/usr/bin/env python3 - -from socket import (socket, AF_INET, SOCK_STREAM, IPPROTO_TCP, - SOL_SOCKET, SO_REUSEADDR) -from threading import Thread - -WASM_MIME = 'application/wasm' -JS_MIME = 'application/javascript' -PLAIN_MIME = 'text/plain' -HTML_MIME = 'text/html' - -REQUESTS = { - '/': ('index.html', HTML_MIME), - '/loader.js': ('loader.js', JS_MIME), - '/asm_paint_rs.js': ('pkg/asm_paint_rs.js', JS_MIME), - '/asm_paint_rs_bg.wasm': ('pkg/asm_paint_rs_bg.wasm', WASM_MIME), -} - -PAGE_404 = ''' - -

Request '404 Not Found'

- resource
'{}'
not found
- -''' - -def header_line_to_entry(line): - key, value = line.decode('utf-8').split(': ') - return key, value - - -class Server: - def __init__(self): - self.s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) - self.s.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) - self.threads = [] - - def rec_http(self, client): - headers = b'' - while not headers.endswith(b'\r\n' * 2): - headers += client.recv(1) - headers = headers.split(b'\r\n') - head, headers = headers[0], headers[1:] - method, url, _ = head.split(b' ') - url = url.decode('utf-8') - headers = dict(header_line_to_entry(v) for v in headers if v) - if 'Content-Length' in headers: - client.recv(int(headers['Content-Length'])) - return method, url, headers - - def sen_http(self, client, status='200 OK', payload=b'', mime=PLAIN_MIME): - print('sende...') - client.send((f'HTTP/1.1 {status}\r\n' - f'Content-Length: {len(payload)}\r\n' - f'Content-Type: {mime}\r\n\r\n').encode('utf-8') - + payload) - print('gesendet') - - def run_client(self, client, addr): - while True: - print('wait for receive') - method, url, headers = self.rec_http(client) - print('got receive') - if method == b'GET': - if not url.startswith('/'): - url += '/' - print(f'got request for "{url}"') - if url in REQUESTS: - path, mime = REQUESTS[url] - f = open(path, 'rb') - payload = f.read() - f.close() - self.sen_http(client, '200 OK', payload, mime) - elif url == '/close': - client.close() - self.kill() - exit() - else: - self.sen_http(client, '404 Not Found', - PAGE_404.format(url).encode('utf-8'), - HTML_MIME) - else: - self.sen_http(client, '400 Bad Request', b'only supporting GET') - - def deploy(self, host='localhost', port=8080): - self.s.bind((host, port)) - self.s.listen(1) - while True: - client, addr = self.s.accept() - thread = Thread(target=self.run_client, args=(client,addr)) - self.threads.append(thread) - thread.run() - - def kill(self): - self.s.close() - - -if __name__ == '__main__': - try: - server = Server() - server.deploy() - finally: - server.kill() diff --git a/WebInterface/wasm/asm-paint/lighttpd.config b/WebInterface/wasm/asm-paint/lighttpd.config new file mode 100644 index 0000000..5fae32d --- /dev/null +++ b/WebInterface/wasm/asm-paint/lighttpd.config @@ -0,0 +1,29 @@ +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.document-root = "/home/jan/projects/DiscoBot/WebInterface/wasm/asm-paint" +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/x-javascript", + ".jpg" => "image/jpeg", + ".jpeg" => "image/jpeg", + ".gif" => "image/gif", + ".png" => "image/png", + ".wasm" => "application/wasm", + "" => "application/octet-stream" +) diff --git a/WebInterface/wasm/asm-paint/loader.js b/WebInterface/wasm/asm-paint/loader.js index f1d15ef..4566ee1 100644 --- a/WebInterface/wasm/asm-paint/loader.js +++ b/WebInterface/wasm/asm-paint/loader.js @@ -1,2 +1,2 @@ -import {default as init} from './asm_paint_rs.js' -init('asm_paint_rs_bg.wasm'); +import {default as init} from './pkg/asm_paint_rs.js' +init('./pkg/asm_paint_rs_bg.wasm'); diff --git a/WebInterface/wasm/asm-paint/run b/WebInterface/wasm/asm-paint/run new file mode 100755 index 0000000..61c1997 --- /dev/null +++ b/WebInterface/wasm/asm-paint/run @@ -0,0 +1,3 @@ +#!/bin/sh + +wasm-pack build --target web diff --git a/WebInterface/wasm/asm-paint/src/lib.rs b/WebInterface/wasm/asm-paint/src/lib.rs index 462a89d..b6a5840 100644 --- a/WebInterface/wasm/asm-paint/src/lib.rs +++ b/WebInterface/wasm/asm-paint/src/lib.rs @@ -8,20 +8,14 @@ macro_rules! console_log { extern "C" { #[wasm_bindgen(js_namespace = console)] fn log(s: &str); + + #[wasm_bindgen(js_namespace = document)] + fn write(s: &str); } #[wasm_bindgen(start)] pub fn entry() { - use web_sys; - console_log!("hello {} wasm", 42); - - let window = web_sys::window().unwrap(); - - let document = window.document().unwrap(); - - let body = document.body().unwrap(); - - //body.set_inner_html("

Hello from WASM

"); + console_log!("hello {} wasm", 44); - body.set_inner_html("oho"); + write("gooo"); } -- cgit v1.2.3-54-g00ecf From e2e4f0f698b95ca979e78ac12fa2395635321dd3 Mon Sep 17 00:00:00 2001 From: natrixaeria Date: Sat, 25 May 2019 23:47:02 +0200 Subject: Add colored logging with fern --- WebInterface/wasm/asm-paint/Cargo.toml | 20 +++++++++++++- WebInterface/wasm/asm-paint/index.html | 1 + WebInterface/wasm/asm-paint/src/client_logger.rs | 34 ++++++++++++++++++++++++ WebInterface/wasm/asm-paint/src/lib.rs | 20 +++++--------- 4 files changed, 60 insertions(+), 15 deletions(-) create mode 100644 WebInterface/wasm/asm-paint/src/client_logger.rs diff --git a/WebInterface/wasm/asm-paint/Cargo.toml b/WebInterface/wasm/asm-paint/Cargo.toml index c0a7c68..e8f5acb 100644 --- a/WebInterface/wasm/asm-paint/Cargo.toml +++ b/WebInterface/wasm/asm-paint/Cargo.toml @@ -1,7 +1,10 @@ [package] name = "asm-paint-rs" version = "0.1.0" -authors = ["Dennis Kobert "] +authors = [ + "natrixaeria", + "Dennis Kobert " +] edition = "2018" [lib] @@ -9,3 +12,18 @@ crate-type = ["cdylib"] [dependencies] wasm-bindgen = "0.2" +log = "0.4" +fern = "0.5" + +[dependencies.web-sys] +version = "0.3" +features = [ + 'Document', + 'Element', + 'HtmlCanvasElement', + 'WebGlBuffer', + 'WebGlRenderingContext', + 'WebGlProgram', + 'WebGlShader', + 'Window' +] diff --git a/WebInterface/wasm/asm-paint/index.html b/WebInterface/wasm/asm-paint/index.html index 46be213..631122d 100644 --- a/WebInterface/wasm/asm-paint/index.html +++ b/WebInterface/wasm/asm-paint/index.html @@ -6,5 +6,6 @@ + diff --git a/WebInterface/wasm/asm-paint/src/client_logger.rs b/WebInterface/wasm/asm-paint/src/client_logger.rs new file mode 100644 index 0000000..a8765c6 --- /dev/null +++ b/WebInterface/wasm/asm-paint/src/client_logger.rs @@ -0,0 +1,34 @@ +use wasm_bindgen::prelude::*; + +#[wasm_bindgen] +extern "C" { + #[wasm_bindgen(js_namespace=console, js_name=log)] + fn __console_log_colored2(f: &str, c1: &str, c2: &str); +} + +fn log(rec: &log::Record) { + __console_log_colored2(&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/asm-paint/src/lib.rs b/WebInterface/wasm/asm-paint/src/lib.rs index b6a5840..fea9d0f 100644 --- a/WebInterface/wasm/asm-paint/src/lib.rs +++ b/WebInterface/wasm/asm-paint/src/lib.rs @@ -1,21 +1,13 @@ -use wasm_bindgen::prelude::*; - -macro_rules! console_log { - ($($t:tt)*) => (log(&format_args!($($t)*).to_string())) -} +mod client_logger; -#[wasm_bindgen] -extern "C" { - #[wasm_bindgen(js_namespace = console)] - fn log(s: &str); +use wasm_bindgen::prelude::*; - #[wasm_bindgen(js_namespace = document)] - fn write(s: &str); -} +#[macro_use] +extern crate log; #[wasm_bindgen(start)] pub fn entry() { - console_log!("hello {} wasm", 44); + client_logger::init_logger(); - write("gooo"); + info!("{}", 42); } -- cgit v1.2.3-54-g00ecf From fb31751fab32c8b67affd75603084e4f143bc758 Mon Sep 17 00:00:00 2001 From: natrixaeria Date: Sun, 26 May 2019 16:09:03 +0200 Subject: Add basic project structure --- WebInterface/wasm/asm-paint/Cargo.toml | 2 +- WebInterface/wasm/asm-paint/run | 2 +- WebInterface/wasm/asm-paint/src/app.rs | 16 ++++++++++++++++ WebInterface/wasm/asm-paint/src/lib.rs | 7 ++++++- WebInterface/wasm/asm-paint/src/site.rs | 18 ++++++++++++++++++ 5 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 WebInterface/wasm/asm-paint/src/app.rs create mode 100644 WebInterface/wasm/asm-paint/src/site.rs diff --git a/WebInterface/wasm/asm-paint/Cargo.toml b/WebInterface/wasm/asm-paint/Cargo.toml index e8f5acb..e2b1e17 100644 --- a/WebInterface/wasm/asm-paint/Cargo.toml +++ b/WebInterface/wasm/asm-paint/Cargo.toml @@ -3,7 +3,7 @@ name = "asm-paint-rs" version = "0.1.0" authors = [ "natrixaeria", - "Dennis Kobert " + "TrueDoctor" ] edition = "2018" diff --git a/WebInterface/wasm/asm-paint/run b/WebInterface/wasm/asm-paint/run index 61c1997..1da1e35 100755 --- a/WebInterface/wasm/asm-paint/run +++ b/WebInterface/wasm/asm-paint/run @@ -1,3 +1,3 @@ #!/bin/sh -wasm-pack build --target web +wasm-pack build --release --target web diff --git a/WebInterface/wasm/asm-paint/src/app.rs b/WebInterface/wasm/asm-paint/src/app.rs new file mode 100644 index 0000000..d5d0e45 --- /dev/null +++ b/WebInterface/wasm/asm-paint/src/app.rs @@ -0,0 +1,16 @@ +use crate::site::Site; + +pub struct App { + site: Site, +} + +impl App { + pub fn new() -> Option { + Some(Self { + site: Site::from_current()?, + }) + } + + pub fn run(&self) { + } +} diff --git a/WebInterface/wasm/asm-paint/src/lib.rs b/WebInterface/wasm/asm-paint/src/lib.rs index fea9d0f..037e8e9 100644 --- a/WebInterface/wasm/asm-paint/src/lib.rs +++ b/WebInterface/wasm/asm-paint/src/lib.rs @@ -1,4 +1,6 @@ mod client_logger; +mod site; +mod app; use wasm_bindgen::prelude::*; @@ -9,5 +11,8 @@ extern crate log; pub fn entry() { client_logger::init_logger(); - info!("{}", 42); + info!("begin running wasm application"); + + let app = app::App::new().unwrap(); + app.run(); } diff --git a/WebInterface/wasm/asm-paint/src/site.rs b/WebInterface/wasm/asm-paint/src/site.rs new file mode 100644 index 0000000..740cb90 --- /dev/null +++ b/WebInterface/wasm/asm-paint/src/site.rs @@ -0,0 +1,18 @@ +use web_sys; + +pub struct Site { + window: web_sys::Window, + document: web_sys::Document, +} + +impl Site { + pub fn from_current() -> Option { + let window = web_sys::window() + .or_else(|| {error!("unable to query window"); None})?; + let document = window.document() + .or_else(|| {error!("unable to query document"); None})?; + Some(Self { + window, document + }) + } +} -- cgit v1.2.3-54-g00ecf From 12dcfc7320b7fd2b9e72f34e7411a6632cc3e4e0 Mon Sep 17 00:00:00 2001 From: natrixaeria Date: Sun, 26 May 2019 18:04:40 +0200 Subject: Create a canvas --- WebInterface/wasm/asm-paint/deploy | 2 ++ WebInterface/wasm/asm-paint/index.html | 10 +++++++++ WebInterface/wasm/asm-paint/src/app.rs | 2 ++ WebInterface/wasm/asm-paint/src/canvas.rs | 27 ++++++++++++++++++++++++ WebInterface/wasm/asm-paint/src/client_logger.rs | 18 +++++++++++++--- WebInterface/wasm/asm-paint/src/lib.rs | 1 + WebInterface/wasm/asm-paint/src/site.rs | 9 ++++++++ 7 files changed, 66 insertions(+), 3 deletions(-) create mode 100755 WebInterface/wasm/asm-paint/deploy create mode 100644 WebInterface/wasm/asm-paint/src/canvas.rs diff --git a/WebInterface/wasm/asm-paint/deploy b/WebInterface/wasm/asm-paint/deploy new file mode 100755 index 0000000..13d1d0a --- /dev/null +++ b/WebInterface/wasm/asm-paint/deploy @@ -0,0 +1,2 @@ +#!/bin/sh +lighttpd -f ./lighttpd.config diff --git a/WebInterface/wasm/asm-paint/index.html b/WebInterface/wasm/asm-paint/index.html index 631122d..5a221e3 100644 --- a/WebInterface/wasm/asm-paint/index.html +++ b/WebInterface/wasm/asm-paint/index.html @@ -4,6 +4,16 @@ Scribblio + diff --git a/WebInterface/wasm/asm-paint/src/app.rs b/WebInterface/wasm/asm-paint/src/app.rs index d5d0e45..003a2a1 100644 --- a/WebInterface/wasm/asm-paint/src/app.rs +++ b/WebInterface/wasm/asm-paint/src/app.rs @@ -12,5 +12,7 @@ impl App { } pub fn run(&self) { + let canvas = self.site.create_canvas().unwrap(); + canvas.render(); } } diff --git a/WebInterface/wasm/asm-paint/src/canvas.rs b/WebInterface/wasm/asm-paint/src/canvas.rs new file mode 100644 index 0000000..a1ef415 --- /dev/null +++ b/WebInterface/wasm/asm-paint/src/canvas.rs @@ -0,0 +1,27 @@ +use web_sys; +use web_sys::{WebGlProgram, WebGlRenderingContext, WebGlShader}; +use wasm_bindgen::JsCast; + +pub struct Canvas { + element: web_sys::HtmlCanvasElement, + ctx: WebGlRenderingContext, +} + +impl Canvas { + pub fn new(element: web_sys::Element) -> Option { + let element: web_sys::HtmlCanvasElement = + element.dyn_into::() + .ok()?; + debug!("create webgl2 context"); + error!("'{:#?}'", element.get_context("webgl2").ok()??.dyn_into::()); + let ctx = element.get_context("webgl2").ok()?? + .dyn_into::().ok()?; + Some(Self { + element, ctx + }) + } + + pub fn render(&self) { + info!("rich kidd"); + } +} diff --git a/WebInterface/wasm/asm-paint/src/client_logger.rs b/WebInterface/wasm/asm-paint/src/client_logger.rs index a8765c6..f71918f 100644 --- a/WebInterface/wasm/asm-paint/src/client_logger.rs +++ b/WebInterface/wasm/asm-paint/src/client_logger.rs @@ -2,12 +2,24 @@ use wasm_bindgen::prelude::*; #[wasm_bindgen] extern "C" { - #[wasm_bindgen(js_namespace=console, js_name=log)] - fn __console_log_colored2(f: &str, c1: &str, c2: &str); + #[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) { - __console_log_colored2(&format!("{}", rec.args()), + 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", diff --git a/WebInterface/wasm/asm-paint/src/lib.rs b/WebInterface/wasm/asm-paint/src/lib.rs index 037e8e9..8b0ee8f 100644 --- a/WebInterface/wasm/asm-paint/src/lib.rs +++ b/WebInterface/wasm/asm-paint/src/lib.rs @@ -1,4 +1,5 @@ mod client_logger; +mod canvas; mod site; mod app; diff --git a/WebInterface/wasm/asm-paint/src/site.rs b/WebInterface/wasm/asm-paint/src/site.rs index 740cb90..47afd19 100644 --- a/WebInterface/wasm/asm-paint/src/site.rs +++ b/WebInterface/wasm/asm-paint/src/site.rs @@ -1,4 +1,5 @@ use web_sys; +use crate::canvas::Canvas; pub struct Site { window: web_sys::Window, @@ -15,4 +16,12 @@ impl Site { window, document }) } + + pub fn create_canvas(&self) -> Option { + debug!("gain canvas element"); + let element = self.document.get_element_by_id("canvas") + .or_else(|| {error!("could not gain canvas element"); None})?; + Canvas::new(element) + .or_else(|| {error!("could not create a webgl2 canvas"); None}) + } } -- cgit v1.2.3-54-g00ecf From 77a41c3065aea3269f0c48da9cc736c404a624c0 Mon Sep 17 00:00:00 2001 From: natrixaeria Date: Sun, 26 May 2019 18:15:48 +0200 Subject: Fix WebGl -> WebGl2 bug --- WebInterface/wasm/asm-paint/Cargo.toml | 6 +- WebInterface/wasm/asm-paint/src/canvas.rs | 10 +-- WebInterface/wasm/asm-paint/src/lib.rs | 119 ++++++++++++++++++++++++++++++ 3 files changed, 126 insertions(+), 9 deletions(-) diff --git a/WebInterface/wasm/asm-paint/Cargo.toml b/WebInterface/wasm/asm-paint/Cargo.toml index e2b1e17..748bb8e 100644 --- a/WebInterface/wasm/asm-paint/Cargo.toml +++ b/WebInterface/wasm/asm-paint/Cargo.toml @@ -14,6 +14,7 @@ crate-type = ["cdylib"] wasm-bindgen = "0.2" log = "0.4" fern = "0.5" +js-sys = "0.3" [dependencies.web-sys] version = "0.3" @@ -21,9 +22,6 @@ features = [ 'Document', 'Element', 'HtmlCanvasElement', - 'WebGlBuffer', - 'WebGlRenderingContext', - 'WebGlProgram', - 'WebGlShader', + 'WebGl2RenderingContext', 'Window' ] diff --git a/WebInterface/wasm/asm-paint/src/canvas.rs b/WebInterface/wasm/asm-paint/src/canvas.rs index a1ef415..1956be0 100644 --- a/WebInterface/wasm/asm-paint/src/canvas.rs +++ b/WebInterface/wasm/asm-paint/src/canvas.rs @@ -1,10 +1,10 @@ use web_sys; -use web_sys::{WebGlProgram, WebGlRenderingContext, WebGlShader}; +use web_sys::{WebGl2RenderingContext}; use wasm_bindgen::JsCast; pub struct Canvas { element: web_sys::HtmlCanvasElement, - ctx: WebGlRenderingContext, + ctx: WebGl2RenderingContext, } impl Canvas { @@ -13,15 +13,15 @@ impl Canvas { element.dyn_into::() .ok()?; debug!("create webgl2 context"); - error!("'{:#?}'", element.get_context("webgl2").ok()??.dyn_into::()); let ctx = element.get_context("webgl2").ok()?? - .dyn_into::().ok()?; + .dyn_into::().ok()?; + info!("created webgl2 context successfully"); Some(Self { element, ctx }) } pub fn render(&self) { - info!("rich kidd"); + info!("do a barrel roll"); } } diff --git a/WebInterface/wasm/asm-paint/src/lib.rs b/WebInterface/wasm/asm-paint/src/lib.rs index 8b0ee8f..432c370 100644 --- a/WebInterface/wasm/asm-paint/src/lib.rs +++ b/WebInterface/wasm/asm-paint/src/lib.rs @@ -17,3 +17,122 @@ pub fn entry() { let app = app::App::new().unwrap(); app.run(); } + +/* +use js_sys::WebAssembly; +use wasm_bindgen::prelude::*; +use wasm_bindgen::JsCast; +use web_sys::{WebGlProgram, WebGlRenderingContext, WebGlShader}; + +#[wasm_bindgen(start)] +pub fn start() -> Result<(), JsValue> { + let document = web_sys::window().unwrap().document().unwrap(); + let canvas = document.get_element_by_id("canvas").unwrap(); + let canvas: web_sys::HtmlCanvasElement = canvas.dyn_into::()?; + + let context = canvas + .get_context("webgl")? + .unwrap() + .dyn_into::()?; + + let vert_shader = compile_shader( + &context, + WebGlRenderingContext::VERTEX_SHADER, + r#" + attribute vec4 position; + void main() { + gl_Position = position; + } + "#, + )?; + let frag_shader = compile_shader( + &context, + WebGlRenderingContext::FRAGMENT_SHADER, + r#" + void main() { + gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); + } + "#, + )?; + let program = link_program(&context, &vert_shader, &frag_shader)?; + context.use_program(Some(&program)); + + let vertices: [f32; 9] = [-0.7, -0.7, 0.0, 0.7, -0.7, 0.0, 0.0, 0.7, 0.0]; + let memory_buffer = wasm_bindgen::memory() + .dyn_into::()? + .buffer(); + let vertices_location = vertices.as_ptr() as u32 / 4; + let vert_array = js_sys::Float32Array::new(&memory_buffer) + .subarray(vertices_location, vertices_location + vertices.len() as u32); + + let buffer = context.create_buffer().ok_or("failed to create buffer")?; + context.bind_buffer(WebGlRenderingContext::ARRAY_BUFFER, Some(&buffer)); + context.buffer_data_with_array_buffer_view( + WebGlRenderingContext::ARRAY_BUFFER, + &vert_array, + WebGlRenderingContext::STATIC_DRAW, + ); + context.vertex_attrib_pointer_with_i32(0, 3, WebGlRenderingContext::FLOAT, false, 0, 0); + context.enable_vertex_attrib_array(0); + + context.clear_color(0.0, 0.0, 0.0, 1.0); + context.clear(WebGlRenderingContext::COLOR_BUFFER_BIT); + + context.draw_arrays( + WebGlRenderingContext::TRIANGLES, + 0, + (vertices.len() / 3) as i32, + ); + Ok(()) +} + +pub fn compile_shader( + context: &WebGlRenderingContext, + shader_type: u32, + source: &str, +) -> Result { + let shader = context + .create_shader(shader_type) + .ok_or_else(|| String::from("Unable to create shader object"))?; + context.shader_source(&shader, source); + context.compile_shader(&shader); + + if context + .get_shader_parameter(&shader, WebGlRenderingContext::COMPILE_STATUS) + .as_bool() + .unwrap_or(false) + { + Ok(shader) + } else { + Err(context + .get_shader_info_log(&shader) + .unwrap_or_else(|| String::from("Unknown error creating shader"))) + } +} + +pub fn link_program( + context: &WebGlRenderingContext, + vert_shader: &WebGlShader, + frag_shader: &WebGlShader, +) -> Result { + let program = context + .create_program() + .ok_or_else(|| String::from("Unable to create shader object"))?; + + context.attach_shader(&program, vert_shader); + context.attach_shader(&program, frag_shader); + context.link_program(&program); + + if context + .get_program_parameter(&program, WebGlRenderingContext::LINK_STATUS) + .as_bool() + .unwrap_or(false) + { + Ok(program) + } else { + Err(context + .get_program_info_log(&program) + .unwrap_or_else(|| String::from("Unknown error creating program object"))) + } +} +*/ -- cgit v1.2.3-54-g00ecf From 9f0f87a772743ce67e37700516cae0ead17cced9 Mon Sep 17 00:00:00 2001 From: natrixaeria Date: Sun, 26 May 2019 19:25:38 +0200 Subject: Create shaders --- WebInterface/wasm/asm-paint/Cargo.toml | 2 + WebInterface/wasm/asm-paint/src/app.rs | 7 ++-- WebInterface/wasm/asm-paint/src/canvas.rs | 20 ++++++++-- WebInterface/wasm/asm-paint/src/lib.rs | 3 +- WebInterface/wasm/asm-paint/src/shader.rs | 62 +++++++++++++++++++++++++++++++ WebInterface/wasm/asm-paint/src/site.rs | 3 +- 6 files changed, 89 insertions(+), 8 deletions(-) create mode 100644 WebInterface/wasm/asm-paint/src/shader.rs diff --git a/WebInterface/wasm/asm-paint/Cargo.toml b/WebInterface/wasm/asm-paint/Cargo.toml index 748bb8e..269d77d 100644 --- a/WebInterface/wasm/asm-paint/Cargo.toml +++ b/WebInterface/wasm/asm-paint/Cargo.toml @@ -23,5 +23,7 @@ features = [ 'Element', 'HtmlCanvasElement', 'WebGl2RenderingContext', + 'WebGlProgram', + 'WebGlShader', 'Window' ] diff --git a/WebInterface/wasm/asm-paint/src/app.rs b/WebInterface/wasm/asm-paint/src/app.rs index 003a2a1..005764d 100644 --- a/WebInterface/wasm/asm-paint/src/app.rs +++ b/WebInterface/wasm/asm-paint/src/app.rs @@ -11,8 +11,9 @@ impl App { }) } - pub fn run(&self) { - let canvas = self.site.create_canvas().unwrap(); - canvas.render(); + pub fn run(&mut self) { + let mut canvas = self.site.create_canvas().unwrap(); + canvas.init().unwrap(); + info!("canvas initialisation was succuessfull"); } } diff --git a/WebInterface/wasm/asm-paint/src/canvas.rs b/WebInterface/wasm/asm-paint/src/canvas.rs index 1956be0..ddf6d51 100644 --- a/WebInterface/wasm/asm-paint/src/canvas.rs +++ b/WebInterface/wasm/asm-paint/src/canvas.rs @@ -1,10 +1,12 @@ use web_sys; use web_sys::{WebGl2RenderingContext}; use wasm_bindgen::JsCast; +use crate::shader::Shaders; pub struct Canvas { element: web_sys::HtmlCanvasElement, ctx: WebGl2RenderingContext, + shaders: Shaders, } impl Canvas { @@ -17,11 +19,23 @@ impl Canvas { .dyn_into::().ok()?; info!("created webgl2 context successfully"); Some(Self { - element, ctx + element, ctx, + shaders: Shaders::new(), }) } - pub fn render(&self) { - info!("do a barrel roll"); + pub fn init(&mut self) -> Result<(), ()> { + debug!("create program"); + self.shaders.create_program(&self.ctx) + .map_err(|e| error!("webgl2 create program: {}", e))?; + debug!("create vertex shader"); + self.shaders.create_vertex_shader(&self.ctx) + .map_err(|e| error!("webgl2 create vertex shader: {}", e))?; + debug!("create fragment shader"); + self.shaders.create_fragment_shader(&self.ctx) + .map_err(|e| error!("webgl2 create fragment shader: {}", e))?; + debug!("compile shader program"); + self.shaders.compile(&self.ctx) + .map_err(|e| error!("webgl2 shader: {}", e)) } } diff --git a/WebInterface/wasm/asm-paint/src/lib.rs b/WebInterface/wasm/asm-paint/src/lib.rs index 432c370..945f2b1 100644 --- a/WebInterface/wasm/asm-paint/src/lib.rs +++ b/WebInterface/wasm/asm-paint/src/lib.rs @@ -1,4 +1,5 @@ mod client_logger; +mod shader; mod canvas; mod site; mod app; @@ -14,7 +15,7 @@ pub fn entry() { info!("begin running wasm application"); - let app = app::App::new().unwrap(); + let mut app = app::App::new().unwrap(); app.run(); } diff --git a/WebInterface/wasm/asm-paint/src/shader.rs b/WebInterface/wasm/asm-paint/src/shader.rs new file mode 100644 index 0000000..ac7c767 --- /dev/null +++ b/WebInterface/wasm/asm-paint/src/shader.rs @@ -0,0 +1,62 @@ +use web_sys::{WebGlProgram, WebGl2RenderingContext}; + +const VERTEX_SHADER: &str = r#"#version 300 es +in vec4 pos; +void main() { + gl_Position = pos; +} +"#; + +const FRAGMENT_SHADER: &str = r#"#version 300 es +precision mediump float; +out vec4 color; + +void main() { + color = vec4(1, 0, 0, 1); +} +"#; + +pub struct Shaders { + program: Option, +} + +impl Shaders { + pub fn new() -> Self { + Self { + program: None, + } + } + + pub fn create_program(&mut self, ctx: &WebGl2RenderingContext) -> Result<(), String> { + self.program = Some(ctx.create_program().ok_or("could not create program id")?); + Ok(()) + } + + fn create_shader(&mut self, ctx: &WebGl2RenderingContext, + shader_type: u32, source: &str) -> Result<(), String> { + let program = self.program.as_ref().ok_or("could not find created program")?; + let shader = ctx.create_shader(shader_type) + .ok_or("could not create shader")?; + ctx.shader_source(&shader, source); + ctx.compile_shader(&shader); + let status = ctx.get_shader_parameter(&shader, WebGl2RenderingContext::COMPILE_STATUS); + if status == wasm_bindgen::JsValue::TRUE { + ctx.attach_shader(program, &shader); + Ok(()) + } else { + Err(format!("\n{}", ctx.get_shader_info_log(&shader).unwrap_or_default())) + } + } + + pub fn create_vertex_shader(&mut self, ctx: &WebGl2RenderingContext) -> Result<(), String> { + self.create_shader(ctx, WebGl2RenderingContext::VERTEX_SHADER, VERTEX_SHADER) + } + + pub fn create_fragment_shader(&mut self, ctx: &WebGl2RenderingContext) -> Result<(), String> { + self.create_shader(ctx, WebGl2RenderingContext::FRAGMENT_SHADER, FRAGMENT_SHADER) + } + + pub fn compile(&mut self, ctx: &WebGl2RenderingContext) -> Result<(), String> { + Ok(()) + } +} diff --git a/WebInterface/wasm/asm-paint/src/site.rs b/WebInterface/wasm/asm-paint/src/site.rs index 47afd19..4ae0237 100644 --- a/WebInterface/wasm/asm-paint/src/site.rs +++ b/WebInterface/wasm/asm-paint/src/site.rs @@ -22,6 +22,7 @@ impl Site { let element = self.document.get_element_by_id("canvas") .or_else(|| {error!("could not gain canvas element"); None})?; Canvas::new(element) - .or_else(|| {error!("could not create a webgl2 canvas"); None}) + .or_else(|| {error!("could not create a webgl2 canvas. + Your browser doesn't seem to support webgl2"); None}) } } -- cgit v1.2.3-54-g00ecf From 5f74e093a4679cdc0fe9fa42822a14fecc7b1cbb Mon Sep 17 00:00:00 2001 From: natrixaeria Date: Sun, 26 May 2019 20:59:02 +0200 Subject: Compile webgl shader program --- WebInterface/wasm/asm-paint/Cargo.toml | 6 +++--- WebInterface/wasm/asm-paint/src/canvas.rs | 6 ++++++ WebInterface/wasm/asm-paint/src/shader.rs | 13 ++++++++++++- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/WebInterface/wasm/asm-paint/Cargo.toml b/WebInterface/wasm/asm-paint/Cargo.toml index 269d77d..ceb1866 100644 --- a/WebInterface/wasm/asm-paint/Cargo.toml +++ b/WebInterface/wasm/asm-paint/Cargo.toml @@ -14,16 +14,16 @@ crate-type = ["cdylib"] wasm-bindgen = "0.2" log = "0.4" fern = "0.5" -js-sys = "0.3" [dependencies.web-sys] -version = "0.3" +version = "0.3.22" features = [ 'Document', 'Element', 'HtmlCanvasElement', 'WebGl2RenderingContext', - 'WebGlProgram', 'WebGlShader', + 'WebGlProgram', + 'WebGlBuffer', 'Window' ] diff --git a/WebInterface/wasm/asm-paint/src/canvas.rs b/WebInterface/wasm/asm-paint/src/canvas.rs index ddf6d51..54691e8 100644 --- a/WebInterface/wasm/asm-paint/src/canvas.rs +++ b/WebInterface/wasm/asm-paint/src/canvas.rs @@ -39,3 +39,9 @@ impl Canvas { .map_err(|e| error!("webgl2 shader: {}", e)) } } + +impl Drop for Canvas { + fn drop(&mut self) { + self.shaders.remove(&self.ctx); + } +} diff --git a/WebInterface/wasm/asm-paint/src/shader.rs b/WebInterface/wasm/asm-paint/src/shader.rs index ac7c767..3311b6a 100644 --- a/WebInterface/wasm/asm-paint/src/shader.rs +++ b/WebInterface/wasm/asm-paint/src/shader.rs @@ -57,6 +57,17 @@ impl Shaders { } pub fn compile(&mut self, ctx: &WebGl2RenderingContext) -> Result<(), String> { - Ok(()) + let program = self.program.as_ref().ok_or("could not find created program")?; + ctx.link_program(program); + let status = ctx.get_program_parameter(program, WebGl2RenderingContext::LINK_STATUS); + if status == wasm_bindgen::JsValue::TRUE { + Ok(()) + } else { + Err(format!("\n{}", ctx.get_program_info_log(program).unwrap_or_default())) + } + } + + pub fn remove(&mut self, ctx: &WebGl2RenderingContext) { + ctx.delete_program(self.program.as_ref()) } } -- cgit v1.2.3-54-g00ecf From 3c21251fec1a1ce4cee42337e727cc8dadfd9563 Mon Sep 17 00:00:00 2001 From: natrixaeria Date: Sat, 21 Dec 2019 20:45:49 +0100 Subject: Draw violet background --- WebInterface/wasm/asm-paint/src/canvas.rs | 16 ++++------------ WebInterface/wasm/asm-paint/src/shader.rs | 30 ++++++++++++++++++++++++++---- 2 files changed, 30 insertions(+), 16 deletions(-) diff --git a/WebInterface/wasm/asm-paint/src/canvas.rs b/WebInterface/wasm/asm-paint/src/canvas.rs index 54691e8..400e258 100644 --- a/WebInterface/wasm/asm-paint/src/canvas.rs +++ b/WebInterface/wasm/asm-paint/src/canvas.rs @@ -25,18 +25,10 @@ impl Canvas { } pub fn init(&mut self) -> Result<(), ()> { - debug!("create program"); - self.shaders.create_program(&self.ctx) - .map_err(|e| error!("webgl2 create program: {}", e))?; - debug!("create vertex shader"); - self.shaders.create_vertex_shader(&self.ctx) - .map_err(|e| error!("webgl2 create vertex shader: {}", e))?; - debug!("create fragment shader"); - self.shaders.create_fragment_shader(&self.ctx) - .map_err(|e| error!("webgl2 create fragment shader: {}", e))?; - debug!("compile shader program"); - self.shaders.compile(&self.ctx) - .map_err(|e| error!("webgl2 shader: {}", e)) + self.shaders.init(&self.ctx).map_err(|_|())?; + self.ctx.clear_color(1.0, 0.2, 1.0, 1.0); + self.ctx.clear(WebGl2RenderingContext::COLOR_BUFFER_BIT); + Ok(()) } } diff --git a/WebInterface/wasm/asm-paint/src/shader.rs b/WebInterface/wasm/asm-paint/src/shader.rs index 3311b6a..2823cd4 100644 --- a/WebInterface/wasm/asm-paint/src/shader.rs +++ b/WebInterface/wasm/asm-paint/src/shader.rs @@ -18,16 +18,18 @@ void main() { pub struct Shaders { program: Option, + pos_loc: i32, } impl Shaders { pub fn new() -> Self { Self { program: None, + pos_loc: -1 } } - pub fn create_program(&mut self, ctx: &WebGl2RenderingContext) -> Result<(), String> { + fn create_program(&mut self, ctx: &WebGl2RenderingContext) -> Result<(), String> { self.program = Some(ctx.create_program().ok_or("could not create program id")?); Ok(()) } @@ -48,15 +50,15 @@ impl Shaders { } } - pub fn create_vertex_shader(&mut self, ctx: &WebGl2RenderingContext) -> Result<(), String> { + fn create_vertex_shader(&mut self, ctx: &WebGl2RenderingContext) -> Result<(), String> { self.create_shader(ctx, WebGl2RenderingContext::VERTEX_SHADER, VERTEX_SHADER) } - pub fn create_fragment_shader(&mut self, ctx: &WebGl2RenderingContext) -> Result<(), String> { + fn create_fragment_shader(&mut self, ctx: &WebGl2RenderingContext) -> Result<(), String> { self.create_shader(ctx, WebGl2RenderingContext::FRAGMENT_SHADER, FRAGMENT_SHADER) } - pub fn compile(&mut self, ctx: &WebGl2RenderingContext) -> Result<(), String> { + fn compile(&mut self, ctx: &WebGl2RenderingContext) -> Result<(), String> { let program = self.program.as_ref().ok_or("could not find created program")?; ctx.link_program(program); let status = ctx.get_program_parameter(program, WebGl2RenderingContext::LINK_STATUS); @@ -67,6 +69,26 @@ impl Shaders { } } + pub fn init(&mut self, ctx: &WebGl2RenderingContext) -> Result<(), String> { + debug!("create program"); + self.create_program(ctx) + .map_err(|e| { error!("webgl2 create program: {}", e); e})?; + debug!("create vertex shader"); + self.create_vertex_shader(ctx) + .map_err(|e| { error!("webgl2 create vertex shader: {}", e); e})?; + debug!("create fragment shader"); + self.create_fragment_shader(ctx) + .map_err(|e| { error!("webgl2 create fragment shader: {}", e); e})?; + debug!("compile shader program"); + self.compile(ctx) + .map_err(|e| { error!("webgl2 shader: {}", e); e})?; + let program = self.program.as_ref().ok_or("could not find created program")?; + self.pos_loc = ctx.get_attrib_location(program, "pos"); + trace!("got attrib location 'pos'({})", self.pos_loc); + info!("initialised shader program"); + Ok(()) + } + pub fn remove(&mut self, ctx: &WebGl2RenderingContext) { ctx.delete_program(self.program.as_ref()) } -- cgit v1.2.3-54-g00ecf From a6d2d62fae44b6d8c96e51055f7222bc679efc48 Mon Sep 17 00:00:00 2001 From: natrixaeria Date: Wed, 29 May 2019 21:00:49 +0200 Subject: Reforge code snippets --- WebInterface/wasm/asm-paint/index.html | 3 + WebInterface/wasm/asm-paint/src/lib.rs | 119 ------------------------------ WebInterface/wasm/asm-paint/src/shader.rs | 6 +- 3 files changed, 7 insertions(+), 121 deletions(-) diff --git a/WebInterface/wasm/asm-paint/index.html b/WebInterface/wasm/asm-paint/index.html index 5a221e3..c4f3734 100644 --- a/WebInterface/wasm/asm-paint/index.html +++ b/WebInterface/wasm/asm-paint/index.html @@ -13,6 +13,9 @@ width: 100%; height: 100%; } + img { + background: violet; + } diff --git a/WebInterface/wasm/asm-paint/src/lib.rs b/WebInterface/wasm/asm-paint/src/lib.rs index 945f2b1..6c773c5 100644 --- a/WebInterface/wasm/asm-paint/src/lib.rs +++ b/WebInterface/wasm/asm-paint/src/lib.rs @@ -18,122 +18,3 @@ pub fn entry() { let mut app = app::App::new().unwrap(); app.run(); } - -/* -use js_sys::WebAssembly; -use wasm_bindgen::prelude::*; -use wasm_bindgen::JsCast; -use web_sys::{WebGlProgram, WebGlRenderingContext, WebGlShader}; - -#[wasm_bindgen(start)] -pub fn start() -> Result<(), JsValue> { - let document = web_sys::window().unwrap().document().unwrap(); - let canvas = document.get_element_by_id("canvas").unwrap(); - let canvas: web_sys::HtmlCanvasElement = canvas.dyn_into::()?; - - let context = canvas - .get_context("webgl")? - .unwrap() - .dyn_into::()?; - - let vert_shader = compile_shader( - &context, - WebGlRenderingContext::VERTEX_SHADER, - r#" - attribute vec4 position; - void main() { - gl_Position = position; - } - "#, - )?; - let frag_shader = compile_shader( - &context, - WebGlRenderingContext::FRAGMENT_SHADER, - r#" - void main() { - gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); - } - "#, - )?; - let program = link_program(&context, &vert_shader, &frag_shader)?; - context.use_program(Some(&program)); - - let vertices: [f32; 9] = [-0.7, -0.7, 0.0, 0.7, -0.7, 0.0, 0.0, 0.7, 0.0]; - let memory_buffer = wasm_bindgen::memory() - .dyn_into::()? - .buffer(); - let vertices_location = vertices.as_ptr() as u32 / 4; - let vert_array = js_sys::Float32Array::new(&memory_buffer) - .subarray(vertices_location, vertices_location + vertices.len() as u32); - - let buffer = context.create_buffer().ok_or("failed to create buffer")?; - context.bind_buffer(WebGlRenderingContext::ARRAY_BUFFER, Some(&buffer)); - context.buffer_data_with_array_buffer_view( - WebGlRenderingContext::ARRAY_BUFFER, - &vert_array, - WebGlRenderingContext::STATIC_DRAW, - ); - context.vertex_attrib_pointer_with_i32(0, 3, WebGlRenderingContext::FLOAT, false, 0, 0); - context.enable_vertex_attrib_array(0); - - context.clear_color(0.0, 0.0, 0.0, 1.0); - context.clear(WebGlRenderingContext::COLOR_BUFFER_BIT); - - context.draw_arrays( - WebGlRenderingContext::TRIANGLES, - 0, - (vertices.len() / 3) as i32, - ); - Ok(()) -} - -pub fn compile_shader( - context: &WebGlRenderingContext, - shader_type: u32, - source: &str, -) -> Result { - let shader = context - .create_shader(shader_type) - .ok_or_else(|| String::from("Unable to create shader object"))?; - context.shader_source(&shader, source); - context.compile_shader(&shader); - - if context - .get_shader_parameter(&shader, WebGlRenderingContext::COMPILE_STATUS) - .as_bool() - .unwrap_or(false) - { - Ok(shader) - } else { - Err(context - .get_shader_info_log(&shader) - .unwrap_or_else(|| String::from("Unknown error creating shader"))) - } -} - -pub fn link_program( - context: &WebGlRenderingContext, - vert_shader: &WebGlShader, - frag_shader: &WebGlShader, -) -> Result { - let program = context - .create_program() - .ok_or_else(|| String::from("Unable to create shader object"))?; - - context.attach_shader(&program, vert_shader); - context.attach_shader(&program, frag_shader); - context.link_program(&program); - - if context - .get_program_parameter(&program, WebGlRenderingContext::LINK_STATUS) - .as_bool() - .unwrap_or(false) - { - Ok(program) - } else { - Err(context - .get_program_info_log(&program) - .unwrap_or_else(|| String::from("Unknown error creating program object"))) - } -} -*/ diff --git a/WebInterface/wasm/asm-paint/src/shader.rs b/WebInterface/wasm/asm-paint/src/shader.rs index 2823cd4..3352bcf 100644 --- a/WebInterface/wasm/asm-paint/src/shader.rs +++ b/WebInterface/wasm/asm-paint/src/shader.rs @@ -1,13 +1,15 @@ use web_sys::{WebGlProgram, WebGl2RenderingContext}; -const VERTEX_SHADER: &str = r#"#version 300 es +const VERTEX_SHADER: &str = +r#"#version 300 es in vec4 pos; void main() { gl_Position = pos; } "#; -const FRAGMENT_SHADER: &str = r#"#version 300 es +const FRAGMENT_SHADER: &str = +r#"#version 300 es precision mediump float; out vec4 color; -- cgit v1.2.3-54-g00ecf From bf0137c3fc6093df085b9d95cd251b7f67d94815 Mon Sep 17 00:00:00 2001 From: natrixaeria Date: Wed, 29 May 2019 21:51:49 +0200 Subject: Create webhogg project directory --- WebInterface/wasm/webhogg/Cargo.toml | 29 ++++++++++++++ WebInterface/wasm/webhogg/deploy | 2 + WebInterface/wasm/webhogg/index.html | 24 +++++++++++ WebInterface/wasm/webhogg/lighttpd.config | 29 ++++++++++++++ WebInterface/wasm/webhogg/loader.js | 2 + WebInterface/wasm/webhogg/run | 3 ++ WebInterface/wasm/webhogg/src/app.rs | 15 +++++++ WebInterface/wasm/webhogg/src/client_logger.rs | 46 ++++++++++++++++++++++ WebInterface/wasm/webhogg/src/lib.rs | 25 ++++++++++++ WebInterface/wasm/webhogg/src/webhogg_exception.rs | 25 ++++++++++++ WebInterface/wasm/webhogg/target/.rustc_info.json | 1 + 11 files changed, 201 insertions(+) create mode 100644 WebInterface/wasm/webhogg/Cargo.toml create mode 100755 WebInterface/wasm/webhogg/deploy create mode 100644 WebInterface/wasm/webhogg/index.html create mode 100644 WebInterface/wasm/webhogg/lighttpd.config create mode 100644 WebInterface/wasm/webhogg/loader.js create mode 100755 WebInterface/wasm/webhogg/run create mode 100644 WebInterface/wasm/webhogg/src/app.rs create mode 100644 WebInterface/wasm/webhogg/src/client_logger.rs create mode 100644 WebInterface/wasm/webhogg/src/lib.rs create mode 100644 WebInterface/wasm/webhogg/src/webhogg_exception.rs create mode 100644 WebInterface/wasm/webhogg/target/.rustc_info.json diff --git a/WebInterface/wasm/webhogg/Cargo.toml b/WebInterface/wasm/webhogg/Cargo.toml new file mode 100644 index 0000000..4342a68 --- /dev/null +++ b/WebInterface/wasm/webhogg/Cargo.toml @@ -0,0 +1,29 @@ +[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' +] diff --git a/WebInterface/wasm/webhogg/deploy b/WebInterface/wasm/webhogg/deploy new file mode 100755 index 0000000..13d1d0a --- /dev/null +++ b/WebInterface/wasm/webhogg/deploy @@ -0,0 +1,2 @@ +#!/bin/sh +lighttpd -f ./lighttpd.config 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 @@ + + + + + webhogg + + + + + + + diff --git a/WebInterface/wasm/webhogg/lighttpd.config b/WebInterface/wasm/webhogg/lighttpd.config new file mode 100644 index 0000000..406b009 --- /dev/null +++ b/WebInterface/wasm/webhogg/lighttpd.config @@ -0,0 +1,29 @@ +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.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/x-javascript", + ".jpg" => "image/jpeg", + ".jpeg" => "image/jpeg", + ".gif" => "image/gif", + ".png" => "image/png", + ".wasm" => "application/wasm", + "" => "application/octet-stream" +) diff --git a/WebInterface/wasm/webhogg/loader.js b/WebInterface/wasm/webhogg/loader.js new file mode 100644 index 0000000..81ecbc7 --- /dev/null +++ b/WebInterface/wasm/webhogg/loader.js @@ -0,0 +1,2 @@ +import {default as init} from './pkg/webhogg.js' +init('./pkg/webhogg_bg.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..bee7c08 --- /dev/null +++ b/WebInterface/wasm/webhogg/src/app.rs @@ -0,0 +1,15 @@ +use crate::webhogg_exception::WebhoggException; + +pub struct WebhoggApplication { +} + +impl WebhoggApplication { + pub fn new() -> Result { + Ok(Self { + }) + } + + pub fn run(&mut self) -> Result<(), WebhoggException> { + Ok(()) + } +} 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..8b75ee1 --- /dev/null +++ b/WebInterface/wasm/webhogg/src/lib.rs @@ -0,0 +1,25 @@ +mod client_logger; +mod webhogg_exception; +mod app; + +use wasm_bindgen::prelude::*; +use app::WebhoggApplication as App; + +#[macro_use] +extern crate log; + +fn run_application() { + match App::new().and_then(|mut app| app.run()) { + Ok(_) => info!("program terminated successfully"), + Err(e) => error!("program terminated with failure > {}", e) + } +} + +#[wasm_bindgen(start)] +pub fn entry() { + client_logger::init_logger(); + + info!("begin running wasm application"); + + run_application() +} diff --git a/WebInterface/wasm/webhogg/src/webhogg_exception.rs b/WebInterface/wasm/webhogg/src/webhogg_exception.rs new file mode 100644 index 0000000..eac67c7 --- /dev/null +++ b/WebInterface/wasm/webhogg/src/webhogg_exception.rs @@ -0,0 +1,25 @@ +use std::error::Error; + +#[derive(Debug)] +pub enum WebhoggException { +} + +impl Error for WebhoggException { + fn description(&self) -> &str { + "webhogg exception" + } + + 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.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 -- cgit v1.2.3-54-g00ecf From 43f14444fa6f4756aaac255e9c1b47b756d0ecd5 Mon Sep 17 00:00:00 2001 From: natrixaeria Date: Thu, 30 May 2019 00:13:18 +0200 Subject: Initialise WebGl2 context --- WebInterface/wasm/webhogg/src/app.rs | 11 ++++-- WebInterface/wasm/webhogg/src/canvas.rs | 42 ++++++++++++++++++++++ WebInterface/wasm/webhogg/src/lib.rs | 4 ++- WebInterface/wasm/webhogg/src/page.rs | 26 ++++++++++++++ WebInterface/wasm/webhogg/src/webhogg_exception.rs | 18 ++++++++-- 5 files changed, 96 insertions(+), 5 deletions(-) create mode 100644 WebInterface/wasm/webhogg/src/canvas.rs create mode 100644 WebInterface/wasm/webhogg/src/page.rs diff --git a/WebInterface/wasm/webhogg/src/app.rs b/WebInterface/wasm/webhogg/src/app.rs index bee7c08..7931418 100644 --- a/WebInterface/wasm/webhogg/src/app.rs +++ b/WebInterface/wasm/webhogg/src/app.rs @@ -1,15 +1,22 @@ use crate::webhogg_exception::WebhoggException; +use crate::page::Page; +use crate::canvas::Canvas; -pub struct WebhoggApplication { +pub(crate) struct WebhoggApplication { + page: Page, + canvas: Canvas, } impl WebhoggApplication { pub fn new() -> Result { + let page = Page::obtain()?; + let canvas = Canvas::from_existing("canvas", &page)?; Ok(Self { + page, canvas, }) } - pub fn run(&mut self) -> Result<(), WebhoggException> { + 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 { + 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::() + .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::() + .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/lib.rs b/WebInterface/wasm/webhogg/src/lib.rs index 8b75ee1..81a3237 100644 --- a/WebInterface/wasm/webhogg/src/lib.rs +++ b/WebInterface/wasm/webhogg/src/lib.rs @@ -1,5 +1,7 @@ mod client_logger; mod webhogg_exception; +mod page; +mod canvas; mod app; use wasm_bindgen::prelude::*; @@ -9,7 +11,7 @@ use app::WebhoggApplication as App; extern crate log; fn run_application() { - match App::new().and_then(|mut app| app.run()) { + match App::new().and_then(|app| app.run()) { Ok(_) => info!("program terminated successfully"), Err(e) => error!("program terminated with failure > {}", e) } 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 { + 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 { + 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 index eac67c7..46eedd6 100644 --- a/WebInterface/wasm/webhogg/src/webhogg_exception.rs +++ b/WebInterface/wasm/webhogg/src/webhogg_exception.rs @@ -2,11 +2,25 @@ 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 { - "webhogg exception" + match self { + WebhoggException::DomError(desc) => desc, + WebhoggException::WebGlContextError(desc) => desc, + } } fn cause(&self) -> Option<&dyn Error> { @@ -20,6 +34,6 @@ impl Error for WebhoggException { impl std::fmt::Display for WebhoggException { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - write!(f, "WebhoggException: {}", self.description()) + write!(f, "WebhoggException::{} {}", self.err_name(), self.description()) } } -- cgit v1.2.3-54-g00ecf From 3f539662518609390964c60acf2f38d9a08aee6d Mon Sep 17 00:00:00 2001 From: Dennis Kobert Date: Fri, 31 May 2019 04:17:35 +0200 Subject: Extract connention loop to seperate funtion --- game_server/src/scribble_group.rs | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/game_server/src/scribble_group.rs b/game_server/src/scribble_group.rs index 01090de..2eb16f2 100644 --- a/game_server/src/scribble_group.rs +++ b/game_server/src/scribble_group.rs @@ -33,24 +33,7 @@ impl Group for ScribbleGroup { self.senders.lock().unwrap().insert(id, sen); let senders_mutex = self.senders.clone(); let self_uid = id; - std::thread::spawn(move || { - loop { - let message = match rec.recv_message() { - Ok(x) => x, - _ => break - }; - //trace!("got message: '{:?}'", message); - let mut senders = senders_mutex.lock().unwrap(); - for (uid, sender) in senders.iter_mut() { - if self_uid != *uid { - sender.send_message(&message) - .unwrap_or_else(|_| debug!("tried to send message to {}, but failed", *uid)); - } - } - } - senders_mutex.lock().unwrap().remove(&self_uid); - info!("client {} has left", self_uid); - }); + std::thread::spawn(move || Self::broadcast_clients(self_uid, rec, senders_mutex)); } } @@ -58,4 +41,23 @@ impl ScribbleGroup { pub fn new(id: GroupId, name: String) -> Self { Self { id, name, senders: Arc::new(Mutex::new(HashMap::new())) } } + + fn broadcast_clients(self_uid: UserId, mut rec: ClientReceiver, senders_mutex: Arc>>) { + loop { + let message = match rec.recv_message() { + Ok(x) => x, + _ => break + }; + //trace!("got message: '{:?}'", message); + let mut senders = senders_mutex.lock().unwrap(); + for (uid, sender) in senders.iter_mut() { + if self_uid != *uid { + sender.send_message(&message) + .unwrap_or_else(|_| debug!("tried to send message to {}, but failed", *uid)); + } + } + } + senders_mutex.lock().unwrap().remove(&self_uid); + info!("client {} has left", self_uid); + } } -- cgit v1.2.3-54-g00ecf From 1b6b5acf63d5d78207dcd746d080cafcd1bfbd84 Mon Sep 17 00:00:00 2001 From: Dennis Kobert Date: Fri, 31 May 2019 04:20:08 +0200 Subject: Make reciver and sender of the Gameclient imutable --- game_server/src/server.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/game_server/src/server.rs b/game_server/src/server.rs index 6294e2c..ea33e2a 100644 --- a/game_server/src/server.rs +++ b/game_server/src/server.rs @@ -65,7 +65,7 @@ impl GameClient { } pub fn split(self) -> (ClientSender, ClientReceiver) { - let (mut rec, mut sen) = self.client.split().unwrap(); + let (rec, sen) = self.client.split().unwrap(); (sen, rec) } } -- cgit v1.2.3-54-g00ecf From cdb4799231837e1e1a07f484b0b8a944819e6e78 Mon Sep 17 00:00:00 2001 From: Dennis Kobert Date: Fri, 31 May 2019 04:57:08 +0200 Subject: Get rid of WarningGet rid of Warninss --- WebInterface/Web.config | 15 --------------- game_server/src/lobby.rs | 4 +++- game_server/src/scribble_group.rs | 2 +- game_server/src/server.rs | 14 ++++++++------ 4 files changed, 12 insertions(+), 23 deletions(-) delete mode 100644 WebInterface/Web.config diff --git a/WebInterface/Web.config b/WebInterface/Web.config deleted file mode 100644 index 741b7d8..0000000 --- a/WebInterface/Web.config +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/game_server/src/lobby.rs b/game_server/src/lobby.rs index d03bd45..ef164af 100644 --- a/game_server/src/lobby.rs +++ b/game_server/src/lobby.rs @@ -9,6 +9,7 @@ pub struct Lobby { groups: HashMap>, } +#[allow(dead_code)] impl Lobby { pub fn new() -> Self { Self { @@ -21,7 +22,7 @@ impl Lobby { "scribble" => { Some(Box::new(ScribbleGroup::new(id, name.to_string()))) }, - other => None, + _ => None, } } @@ -48,6 +49,7 @@ impl Lobby { } } +#[allow(dead_code)] pub struct GroupIterator<'a> { groups: std::collections::hash_map::Values<'a, GroupId, Box> } diff --git a/game_server/src/scribble_group.rs b/game_server/src/scribble_group.rs index 2eb16f2..0d2c0f1 100644 --- a/game_server/src/scribble_group.rs +++ b/game_server/src/scribble_group.rs @@ -29,7 +29,7 @@ impl Group for ScribbleGroup { fn add_client(&mut self, id: UserId, client: GameClient) { debug!("user {} joined the group {}:'{}'", id, self.id, self.name); - let (sen, mut rec) = client.split(); + let (sen, rec) = client.split(); self.senders.lock().unwrap().insert(id, sen); let senders_mutex = self.senders.clone(); let self_uid = id; diff --git a/game_server/src/server.rs b/game_server/src/server.rs index ea33e2a..0b76f15 100644 --- a/game_server/src/server.rs +++ b/game_server/src/server.rs @@ -8,7 +8,6 @@ use websocket::{OwnedMessage, use std::net::{SocketAddr, ToSocketAddrs, TcpStream}; use std::sync::{mpsc, mpsc::{Sender, Receiver}}; -use std::collections::HashMap; use super::lobby::Lobby; use super::backend_connection::BackendConnection; @@ -121,16 +120,19 @@ impl GameServer { } fn read_clients(&self) -> Receiver { - let (s, r): (Sender, Receiver) + let (sen, rec): (Sender, Receiver) = mpsc::channel(); let addr = self.addr; std::thread::spawn(move || { - let result = Self::handle_requests(addr, &s).or_else(|e| s.send(Err(e))); + match Self::handle_requests(addr, &sen) { + Err(e) => sen.send(Err(e)).unwrap(), + _ => (), + } }); - r + rec } - fn handle_requests(addr: SocketAddr, s: &Sender) -> Result<(), GameServerError> { + fn handle_requests(addr: SocketAddr, sen: &Sender) -> Result<(), GameServerError> { let server = match Server::::bind(addr) { Ok(v) => v, Err(e) => { @@ -140,7 +142,7 @@ impl GameServer { }; info!("webserver is being launched"); for req in server { - s.send(Ok(Self::handle_request(req)?)).unwrap(); + sen.send(Ok(Self::handle_request(req)?)).unwrap(); } info!("webserver is being shut down"); Ok(()) -- cgit v1.2.3-54-g00ecf From b5ec9c693f3abfe36d6d1e4dbf86e084872a4676 Mon Sep 17 00:00:00 2001 From: natrixaeria Date: Fri, 31 May 2019 05:26:50 +0200 Subject: Split into two entry points --- WebInterface/wasm/webhogg/loader.js | 10 ++- WebInterface/wasm/webhogg/src/lib.rs | 17 ++++- WebInterface/wasm/webhogg/webhogg.js | 117 +++++++++++++++++++++++++++++++++++ 3 files changed, 140 insertions(+), 4 deletions(-) create mode 100644 WebInterface/wasm/webhogg/webhogg.js diff --git a/WebInterface/wasm/webhogg/loader.js b/WebInterface/wasm/webhogg/loader.js index 81ecbc7..50bf69d 100644 --- a/WebInterface/wasm/webhogg/loader.js +++ b/WebInterface/wasm/webhogg/loader.js @@ -1,2 +1,8 @@ -import {default as init} from './pkg/webhogg.js' -init('./pkg/webhogg_bg.wasm'); +import {default as init_r} from './webhogg.js' +import {init_x} from './webhogg.js' + +let m1 = init_r('./pkg/webhogg_bg.wasm'); +let m2 = init_r('./pkg/webhogg_bg.wasm'); + +init_x(m1, 1); +init_x(m2, 2); diff --git a/WebInterface/wasm/webhogg/src/lib.rs b/WebInterface/wasm/webhogg/src/lib.rs index 81a3237..2812ed9 100644 --- a/WebInterface/wasm/webhogg/src/lib.rs +++ b/WebInterface/wasm/webhogg/src/lib.rs @@ -17,8 +17,21 @@ fn run_application() { } } -#[wasm_bindgen(start)] -pub fn entry() { +#[wasm_bindgen] +pub fn game_logic_entry() { + client_logger::init_logger(); + + info!("game logic initialisation"); +} + +#[wasm_bindgen] +pub fn graphics_entry() { + client_logger::init_logger(); + + info!("graphics initialisation"); +} + +pub fn entry2() { client_logger::init_logger(); info!("begin running wasm application"); diff --git a/WebInterface/wasm/webhogg/webhogg.js b/WebInterface/wasm/webhogg/webhogg.js new file mode 100644 index 0000000..1011eef --- /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() { + return wasm.game_logic_entry(); +} +__exports.game_logic_entry = game_logic_entry + +/** +* @returns {void} +*/ +export function graphics_entry() { + return wasm.graphics_entry(); +} +__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; -- cgit v1.2.3-54-g00ecf From 031ba8a21d3899d4e24bd1423ec738ebf95ab947 Mon Sep 17 00:00:00 2001 From: Dennis Kobert Date: Fri, 31 May 2019 06:49:25 +0200 Subject: Improve Exception Handling Add WebhoggGroup --- game_server/src/backend_connection.rs | 4 +- game_server/src/group.rs | 4 +- game_server/src/lobby.rs | 12 +++--- game_server/src/main.rs | 1 + game_server/src/scribble_group.rs | 10 +++-- game_server/src/server.rs | 24 ++++++++++-- game_server/src/webhogg_group.rs | 71 +++++++++++++++++++++++++++++++++++ 7 files changed, 108 insertions(+), 18 deletions(-) create mode 100644 game_server/src/webhogg_group.rs diff --git a/game_server/src/backend_connection.rs b/game_server/src/backend_connection.rs index d32c58e..a751b30 100644 --- a/game_server/src/backend_connection.rs +++ b/game_server/src/backend_connection.rs @@ -1,8 +1,8 @@ use reqwest::{Response, Client, Url, UrlError, Error as ReqError}; use std::sync::mpsc::{Sender, Receiver}; use std::sync::mpsc; -use super::server::{UserId, Token}; -use super::group::GroupId; +use crate::server::{UserId, Token}; +use crate::group::GroupId; pub struct BackendConnection { host: String, diff --git a/game_server/src/group.rs b/game_server/src/group.rs index fcda12a..74a04f7 100644 --- a/game_server/src/group.rs +++ b/game_server/src/group.rs @@ -1,4 +1,4 @@ -use super::server::{UserId, GameClient}; +use crate::server::{UserId, GameClient, GameServerError}; pub type GroupId = u32; @@ -9,5 +9,5 @@ pub trait Group { fn run(&mut self); - fn add_client(&mut self, id: UserId, client: GameClient); + fn add_client(&mut self, id: UserId, client: GameClient) -> Result<(), GameServerError>; } diff --git a/game_server/src/lobby.rs b/game_server/src/lobby.rs index ef164af..6d11a5f 100644 --- a/game_server/src/lobby.rs +++ b/game_server/src/lobby.rs @@ -1,9 +1,9 @@ use std::collections::HashMap; -use super::group::{Group, GroupId}; -use super::scribble_group::ScribbleGroup; +use crate::group::{Group, GroupId}; +use crate::scribble_group::ScribbleGroup; -use super::server::{UserId, GameClient}; +use crate::server::{UserId, GameClient, GameServerError}; pub struct Lobby { groups: HashMap>, @@ -31,17 +31,17 @@ impl Lobby { } pub fn add_client(&mut self, group_type: &str, group_id: GroupId, group_name: &str, - user_id: UserId, client: GameClient) { + user_id: UserId, client: GameClient) -> Result<(), GameServerError> { if !self.groups.contains_key(&group_id) { let mut group = match Self::generate_group(group_type, group_id, group_name) { Some(x) => x, - _ => return, + _ => return Err(GameServerError::GroupCreationError(format!("failed to generate '{}' group", group_type))), }; group.run(); self.groups.insert(group_id, group); } let group = self.groups.get_mut(&group_id).unwrap(); - group.add_client(user_id, client); + group.add_client(user_id, client) } pub fn iter<'b>(&'b self) -> GroupIterator<'b> { diff --git a/game_server/src/main.rs b/game_server/src/main.rs index ab73a97..a6cc608 100644 --- a/game_server/src/main.rs +++ b/game_server/src/main.rs @@ -1,5 +1,6 @@ mod group; mod scribble_group; +mod webhogg_group; mod lobby; mod server; mod backend_connection; diff --git a/game_server/src/scribble_group.rs b/game_server/src/scribble_group.rs index 0d2c0f1..8980e7b 100644 --- a/game_server/src/scribble_group.rs +++ b/game_server/src/scribble_group.rs @@ -1,6 +1,7 @@ -use super::group::{Group, GroupId}; -use super::server::{UserId, GameClient, - ClientSender, ClientReceiver}; +use crate::group::{Group, GroupId}; +use crate::server::{UserId, GameClient, + ClientSender, ClientReceiver, + GameServerError}; use std::collections::HashMap; use std::sync::{Arc, Mutex}; @@ -27,13 +28,14 @@ impl Group for ScribbleGroup { info!("a new group {}:'{}' runs now", self.id, self.name); } - fn add_client(&mut self, id: UserId, client: GameClient) { + fn add_client(&mut self, id: UserId, client: GameClient) -> Result<(), GameServerError> { debug!("user {} joined the group {}:'{}'", id, self.id, self.name); let (sen, rec) = client.split(); self.senders.lock().unwrap().insert(id, sen); let senders_mutex = self.senders.clone(); let self_uid = id; std::thread::spawn(move || Self::broadcast_clients(self_uid, rec, senders_mutex)); + Ok(()) } } diff --git a/game_server/src/server.rs b/game_server/src/server.rs index 0b76f15..5b1a7a9 100644 --- a/game_server/src/server.rs +++ b/game_server/src/server.rs @@ -8,8 +8,8 @@ use websocket::{OwnedMessage, use std::net::{SocketAddr, ToSocketAddrs, TcpStream}; use std::sync::{mpsc, mpsc::{Sender, Receiver}}; -use super::lobby::Lobby; -use super::backend_connection::BackendConnection; +use crate::lobby::Lobby; +use crate::backend_connection::BackendConnection; pub type ClientReceiver = receiver::Reader<::Reader>; pub type ClientSender = sender::Writer<::Writer>; @@ -24,7 +24,22 @@ pub enum GameServerError { BindError(std::io::Error), HandshakeRequestError, InvalidProtocolError, - AcceptError(std::io::Error) + AcceptError(std::io::Error), + GroupError(String), + GroupCreationError(String), +} + +impl std::fmt::Display for GameServerError { + fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> { + match self { + GameServerError::BindError(e) => write!(f, "BindError: {}", e), + GameServerError::HandshakeRequestError => write!(f, "HandshakeRequestError"), + GameServerError::InvalidProtocolError => write!(f, "InvalidProtocolError"), + GameServerError::AcceptError(e) => write!(f, "AcceptError: {}", e), + GameServerError::GroupError(e) => write!(f, "GroupError: {}", e), + GameServerError::GroupCreationError(e) => write!(f, "GroupCreationError: {}", e), + } + } } pub struct GameServer { @@ -111,7 +126,8 @@ impl GameServer { user_id, token, client.host_name(), group_name); //clients.lock().unwrap().insert(token, client); self.lobby.add_client(&group_type, group_id, - &group_name, user_id, client); + &group_name, user_id, client) + .unwrap_or_else(|e| warn!("failed to add client: {}", e)); } } } else { diff --git a/game_server/src/webhogg_group.rs b/game_server/src/webhogg_group.rs new file mode 100644 index 0000000..091f7f8 --- /dev/null +++ b/game_server/src/webhogg_group.rs @@ -0,0 +1,71 @@ +use crate::group::{Group, GroupId}; +use crate::server::{UserId, GameClient, + ClientSender, ClientReceiver, + GameServerError}; +use std::collections::HashMap; +use std::sync::{Arc, Mutex}; + +pub struct WebhoggGroup { + id: GroupId, + name: String, + senders: Arc>> +} + +impl Group for WebhoggGroup { + fn id(&self) -> GroupId { + self.id + } + + fn group_type(&self) -> String { + "webhogg".to_string() + } + + fn name(&self) -> String { + self.name.clone() + } + + fn run(&mut self) { + info!("a new group {}:'{}' runs now", self.id, self.name); + } + + fn add_client(&mut self, id: UserId, client: GameClient) -> Result<(), GameServerError> { + if self.senders.lock().unwrap().len() > 1 { + return Err(GameServerError::GroupError( + format!("user {} was not able to join the {} group, {}", + "because the client limit has been exceeded", + id, self.name))); + } + debug!("user {} joined the group {}:'{}'", id, self.id, self.name); + let (sen, rec) = client.split(); + self.senders.lock().unwrap().insert(id, sen); + let senders_mutex = self.senders.clone(); + let self_uid = id; + std::thread::spawn(move || Self::broadcast_clients(self_uid, rec, senders_mutex)); + Ok(()) + } +} + +impl WebhoggGroup { + pub fn new(id: GroupId, name: String) -> Self { + Self { id, name, senders: Arc::new(Mutex::new(HashMap::new())) } + } + + fn broadcast_clients(self_uid: UserId, mut rec: ClientReceiver, senders_mutex: Arc>>) { + loop { + let message = match rec.recv_message() { + Ok(x) => x, + _ => break + }; + //trace!("got message: '{:?}'", message); + let mut senders = senders_mutex.lock().unwrap(); + for (uid, sender) in senders.iter_mut() { + if self_uid != *uid { + sender.send_message(&message) + .unwrap_or_else(|_| debug!("tried to send message to {}, but failed", *uid)); + } + } + } + senders_mutex.lock().unwrap().remove(&self_uid); + info!("client {} has left", self_uid); + } +} -- cgit v1.2.3-54-g00ecf From 3527f10f8767b3b62b876f8a3f3bc5bd3ba56b2d Mon Sep 17 00:00:00 2001 From: Dennis Kobert Date: Fri, 31 May 2019 07:35:55 +0200 Subject: Add Vec2 --- game_server/src/maths.rs | 54 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 game_server/src/maths.rs diff --git a/game_server/src/maths.rs b/game_server/src/maths.rs new file mode 100644 index 0000000..635eed6 --- /dev/null +++ b/game_server/src/maths.rs @@ -0,0 +1,54 @@ +pub struct Vec2 { + pub x: f32, + pub y: f32, +} + +impl std::ops::Add for Vec2 { + type Output = Self; + fn add(self, other: Self) -> Self { + Self { + x: x + other.x, + y: y + other.y + } + } +} + +impl std::ops::Sub for Vec2 { + type Output = Self; + fn sub(self, other: Self) -> Self { + Self { + x: x - other.x, + y: y - other.y + } + } +} + +impl std::ops::Neg for Vec2 { + type Output = Self; + fn sub(self) -> Self { + Self { + x: -x, + y: -y + } + } +} + +impl std::cmp::PartialEq for Vec2 { + type Output = bool; + fn eq(&self, other: &Self) -> bool { + f32::abs(self.x - other.x) < 1e-8 + && f32::abs(self.y - other.y) < 1e-8 + } +} + +impl std::cmp::Eq for Vec2 {} + +impl Vec2 { + pub fn distance(&self) -> f32 { + f32::sqrt(self.distance2) + } + + pub fn distance2(&self) -> f32 { + self.x * self.x + self.y * self.y + } +} -- cgit v1.2.3-54-g00ecf From a8908cac9524fabdcf4232c1394a51848f0335af Mon Sep 17 00:00:00 2001 From: natrixaeria Date: Fri, 31 May 2019 14:33:57 +0200 Subject: Create web workers --- WebInterface/wasm/webhogg/Cargo.toml | 3 ++- WebInterface/wasm/webhogg/deploy | 4 ++- WebInterface/wasm/webhogg/deploy.py | 42 +++++++++++++++++++++++++++++++ WebInterface/wasm/webhogg/graphics.js | 6 +++++ WebInterface/wasm/webhogg/lighttpd.config | 7 +++++- WebInterface/wasm/webhogg/loader.js | 9 ++++--- WebInterface/wasm/webhogg/mimes | 1 + WebInterface/wasm/webhogg/src/lib.rs | 5 ++-- WebInterface/wasm/webhogg/webhogg.js | 8 +++--- 9 files changed, 72 insertions(+), 13 deletions(-) create mode 100755 WebInterface/wasm/webhogg/deploy.py create mode 100644 WebInterface/wasm/webhogg/graphics.js create mode 100644 WebInterface/wasm/webhogg/mimes diff --git a/WebInterface/wasm/webhogg/Cargo.toml b/WebInterface/wasm/webhogg/Cargo.toml index 4342a68..a2e5f8e 100644 --- a/WebInterface/wasm/webhogg/Cargo.toml +++ b/WebInterface/wasm/webhogg/Cargo.toml @@ -25,5 +25,6 @@ features = [ 'WebGlShader', 'WebGlProgram', 'WebGlBuffer', - 'Window' + 'Window', + 'Worker' ] diff --git a/WebInterface/wasm/webhogg/deploy b/WebInterface/wasm/webhogg/deploy index 13d1d0a..01bc036 100755 --- a/WebInterface/wasm/webhogg/deploy +++ b/WebInterface/wasm/webhogg/deploy @@ -1,2 +1,4 @@ #!/bin/sh -lighttpd -f ./lighttpd.config +#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/lighttpd.config b/WebInterface/wasm/webhogg/lighttpd.config index 406b009..4072b30 100644 --- a/WebInterface/wasm/webhogg/lighttpd.config +++ b/WebInterface/wasm/webhogg/lighttpd.config @@ -11,6 +11,8 @@ server.http-parseopts = ( "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" @@ -19,7 +21,7 @@ mimetype.assign = ( ".html" => "text/html", ".txt" => "text/plain", ".css" => "text/css", - ".js" => "application/x-javascript", + ".js" => "application/javascript", ".jpg" => "image/jpeg", ".jpeg" => "image/jpeg", ".gif" => "image/gif", @@ -27,3 +29,6 @@ mimetype.assign = ( ".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 index 50bf69d..cc66ff6 100644 --- a/WebInterface/wasm/webhogg/loader.js +++ b/WebInterface/wasm/webhogg/loader.js @@ -1,8 +1,9 @@ import {default as init_r} from './webhogg.js' import {init_x} from './webhogg.js' -let m1 = init_r('./pkg/webhogg_bg.wasm'); -let m2 = init_r('./pkg/webhogg_bg.wasm'); +let module = init_r('./pkg/webhogg_bg.wasm'); + +let graphics = new Worker('./graphics.js') + +init_x(module, 'game logic', graphics); -init_x(m1, 1); -init_x(m2, 2); 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/src/lib.rs b/WebInterface/wasm/webhogg/src/lib.rs index 2812ed9..4a79a24 100644 --- a/WebInterface/wasm/webhogg/src/lib.rs +++ b/WebInterface/wasm/webhogg/src/lib.rs @@ -6,6 +6,7 @@ mod app; use wasm_bindgen::prelude::*; use app::WebhoggApplication as App; +use web_sys::Worker; #[macro_use] extern crate log; @@ -18,14 +19,14 @@ fn run_application() { } #[wasm_bindgen] -pub fn game_logic_entry() { +pub fn game_logic_entry(worker: Worker) { client_logger::init_logger(); info!("game logic initialisation"); } #[wasm_bindgen] -pub fn graphics_entry() { +pub fn graphics_entry(worker: Worker) { client_logger::init_logger(); info!("graphics initialisation"); diff --git a/WebInterface/wasm/webhogg/webhogg.js b/WebInterface/wasm/webhogg/webhogg.js index 1011eef..751ac77 100644 --- a/WebInterface/wasm/webhogg/webhogg.js +++ b/WebInterface/wasm/webhogg/webhogg.js @@ -50,16 +50,16 @@ __exports.__wbg_error_56a861ecc80f27e1 = __wbg_error_56a861ecc80f27e1 /** * @returns {void} */ -export function game_logic_entry() { - return wasm.game_logic_entry(); +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() { - return wasm.graphics_entry(); +export function graphics_entry(worker) { + return wasm.graphics_entry(addHeapObject(worker)); } __exports.graphics_entry = graphics_entry -- cgit v1.2.3-54-g00ecf From 79db730d4e42ce592af753059422410979ff26b0 Mon Sep 17 00:00:00 2001 From: Dennis Kobert Date: Fri, 31 May 2019 14:53:37 +0200 Subject: tart implementing game logic --- game_server/src/collide.rs | 36 +++++++++++ game_server/src/main.rs | 7 +++ game_server/src/maths.rs | 123 ++++++++++++++++++++++++++++++++++++++ game_server/src/webhogg_game.rs | 13 ++++ game_server/src/webhogg_group.rs | 71 ++++++++++++++++++++++ game_server/src/webhogg_player.rs | 3 + 6 files changed, 253 insertions(+) create mode 100644 game_server/src/collide.rs create mode 100644 game_server/src/maths.rs create mode 100644 game_server/src/webhogg_game.rs create mode 100644 game_server/src/webhogg_group.rs create mode 100644 game_server/src/webhogg_player.rs diff --git a/game_server/src/collide.rs b/game_server/src/collide.rs new file mode 100644 index 0000000..4169787 --- /dev/null +++ b/game_server/src/collide.rs @@ -0,0 +1,36 @@ +pub trait Collide { + fn collides(&self, other: &Rhs) -> bool; +} + +impl Collide for Vec2 { + fn collides(self, other: Self) { + self == other + } +} + +impl Collide for Box { + fn collides(self, other: Vec2) { + self.pos < other < self.pos + self.size + } +} + +impl Collide for Box { + fn collides(self, other: Self) { + self.collides(other.pos) + || other.collides(self.pos) + } +} + +impl Collide for RBox { + fn collides(self, other: Vec2) { + + || other.pos < self.pos < other.pos + other.size + } +} + +impl Collide for Box { + fn collides(self, other: Self) { + self.pos < other.pos < self.pos + self.size + || other.pos < self.pos < other.pos + other.size + } +} diff --git a/game_server/src/main.rs b/game_server/src/main.rs index ab73a97..e10fe3c 100644 --- a/game_server/src/main.rs +++ b/game_server/src/main.rs @@ -1,5 +1,12 @@ mod group; +mod maths; mod scribble_group; +<<<<<<< Updated upstream +======= +mod webhogg_group; +mod webhogg_game; +mod collide; +>>>>>>> Stashed changes mod lobby; mod server; mod backend_connection; diff --git a/game_server/src/maths.rs b/game_server/src/maths.rs new file mode 100644 index 0000000..8844c6e --- /dev/null +++ b/game_server/src/maths.rs @@ -0,0 +1,123 @@ +#[derive(Clone, Copy)] +pub struct Vec2 { + pub x: f32, + pub y: f32, +} + +impl std::ops::Add for Vec2 { + type Output = Self; + fn add(self, other: Self) -> Self { + Self { + x: self.x + other.x, + y: self.y + other.y + } + } +} + +impl std::ops::Sub for Vec2 { + type Output = Self; + fn sub(self, other: Self) -> Self { + Self { + x: self.x - other.x, + y: self.y - other.y + } + } +} + +impl std::ops::Neg for Vec2 { + type Output = Self; + fn neg(self) -> Self { + Self { + x: -self.x, + y: -self.y + } + } +} + +impl std::cmp::PartialOrd for Vec2 { + fn partial_cmp(&self, other: &Self) -> Option { + Some(if self.x < other.x && self.y < other.y { + std::cmp::Ordering::Less + } else if self.x > other.x && self.y > other.y { + std::cmp::Ordering::Greater + } else { + std::cmp::Ordering::Equal + }) + } +} + +impl std::cmp::PartialEq for Vec2 { + fn eq(&self, other: &Self) -> bool { + f32::abs(self.x - other.x) < 1e-8 + && f32::abs(self.y - other.y) < 1e-8 + } +} + +impl std::cmp::Eq for Vec2 {} + +impl Vec2 { + pub fn distance(&self) -> f32 { + f32::sqrt(self.distance2()) + } + + pub fn distance2(&self) -> f32 { + self.x * self.x + self.y * self.y + } +} + +pub struct Box { + pub pos: Vec2, + /// the size may not be smaller than zero + pub size: Vec2, +} + +impl std::ops::Add for Box { + type Output = Self; + fn add(self, other: Vec2) -> Self { + Self { + p1: self.p1 + other, + p2: self.p2 + other, + } + } +} + +impl std::ops::Sub for Box { + type Output = Self; + fn sub(self, other: Vec2) -> Self { + Self { + pos: self.pos + other, + size: self.size + other + } + } +} + +pub struct RBox { + /// Point 1 + pub p1: Vec2, + /// Point 2 + pub p2: Vec2, + /// Width + pub w: f32, +} + +impl std::ops::Add for RBox { + type Output = Self; + fn add(self, other: Vec2) -> Self { + Self { + p1: self.p1 + other, + p2: self.p2 + other, + w: self.w, + } + } +} + +impl std::ops::Sub for RBox { + type Output = Self; + fn sub(self, other: Vec2) -> Self { + Self { + p1: self.p1 + other, + p2: self.p2 + other, + w: self.w, + } + } +} diff --git a/game_server/src/webhogg_game.rs b/game_server/src/webhogg_game.rs new file mode 100644 index 0000000..7b94fcb --- /dev/null +++ b/game_server/src/webhogg_game.rs @@ -0,0 +1,13 @@ +use crate::maths::Vec2; + +pub struct WebhoggPlayer { + pos: Vec2, +} + +pub struct WebhoggGame { + player1: WebhoggPlayer, + player2: WebhoggPlayer, +} + +impl WebhoggGame { +} diff --git a/game_server/src/webhogg_group.rs b/game_server/src/webhogg_group.rs new file mode 100644 index 0000000..5a326d8 --- /dev/null +++ b/game_server/src/webhogg_group.rs @@ -0,0 +1,71 @@ +use crate::group::{Group, GroupId}; +use crate::server::{UserId, GameClient, + ClientSender, ClientReceiver, + GameServerError}; +use std::collections::HashMap; +use std::sync::{Arc, Mutex}; + +pub struct WebhoggGroup { + id: GroupId, + name: String, + senders: Arc>> +} + +impl Group for WebhoggGroup { + fn id(&self) -> GroupId { + self.id + } + + fn group_type(&self) -> String { + "webhogg".to_string() + } + + fn name(&self) -> String { + self.name.clone() + } + + fn run(&mut self) { + info!("a new group {}:'{}' runs now", self.id, self.name); + } + + fn add_client(&mut self, id: UserId, client: GameClient) -> Result<(), GameServerError> { + if self.senders.lock().unwrap().len() > 1 { + return Err(GameServerError::GroupError( + format!("user {} was not able to join the {} group, {}", + "because the client limit has been exceeded", + id, self.name))); + } + debug!("user {} joined the group {}:'{}'", id, self.id, self.name); + let (sen, rec) = client.split(); + self.senders.lock().unwrap().insert(id, sen); + let senders_mutex = self.senders.clone(); + let self_uid = id; + std::thread::spawn(move || Self::launch_game(self_uid, rec, senders_mutex)); + Ok(()) + } +} + +impl WebhoggGroup { + pub fn new(id: GroupId, name: String) -> Self { + Self { id, name, senders: Arc::new(Mutex::new(HashMap::new())) } + } + + fn launch_game(self_uid: UserId, mut rec: ClientReceiver, senders_mutex: Arc>>) { + loop { + let message = match rec.recv_message() { + Ok(x) => x, + _ => break + }; + //trace!("got message: '{:?}'", message); + let mut senders = senders_mutex.lock().unwrap(); + for (uid, sender) in senders.iter_mut() { + if self_uid != *uid { + sender.send_message(&message) + .unwrap_or_else(|_| debug!("tried to send message to {}, but failed", *uid)); + } + } + } + senders_mutex.lock().unwrap().remove(&self_uid); + info!("client {} has left", self_uid); + } +} diff --git a/game_server/src/webhogg_player.rs b/game_server/src/webhogg_player.rs new file mode 100644 index 0000000..38b9596 --- /dev/null +++ b/game_server/src/webhogg_player.rs @@ -0,0 +1,3 @@ +pub struct WebhoggPlayer { + +} -- cgit v1.2.3-54-g00ecf From 205402f5f2b26b92fb40769ad25046c5baa7bcca Mon Sep 17 00:00:00 2001 From: natrixaeria Date: Fri, 31 May 2019 15:24:57 +0200 Subject: Add easy-to-use python webserver --- WebInterface/wasm/webhogg/deploy | 5 +-- WebInterface/wasm/webhogg/deploy.py | 73 +++++++++++++++++++++++-------- WebInterface/wasm/webhogg/killpy | 2 + WebInterface/wasm/webhogg/lighttpd.config | 34 -------------- WebInterface/wasm/webhogg/mimes | 1 - 5 files changed, 59 insertions(+), 56 deletions(-) create mode 100755 WebInterface/wasm/webhogg/killpy delete mode 100644 WebInterface/wasm/webhogg/lighttpd.config delete mode 100644 WebInterface/wasm/webhogg/mimes diff --git a/WebInterface/wasm/webhogg/deploy b/WebInterface/wasm/webhogg/deploy index 01bc036..6284564 100755 --- a/WebInterface/wasm/webhogg/deploy +++ b/WebInterface/wasm/webhogg/deploy @@ -1,4 +1,3 @@ #!/bin/sh -#killall darkhttpd -#darkhttpd . --addr 127.0.0.1 --port 8080 --mimetypes mimes -python3 deploy.py +killall python3 +python3 deploy.py -d diff --git a/WebInterface/wasm/webhogg/deploy.py b/WebInterface/wasm/webhogg/deploy.py index 21d9a5e..278becd 100755 --- a/WebInterface/wasm/webhogg/deploy.py +++ b/WebInterface/wasm/webhogg/deploy.py @@ -2,10 +2,8 @@ from socket import socket, SOL_SOCKET, SO_REUSEADDR -ws = socket() -ws.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) -ws.bind(('localhost', 8080)) -ws.listen() +ADD_HEADERS = 'Content-Security-Policy: worker-src localhost:*' +ADD_HEADERS = "Content-Security-Policy: script-src 'inline' *; worker-src *" class Client: def __init__(self, sock, addr): @@ -19,24 +17,63 @@ class Client: 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 + return method, loc, attrs, ver 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) + print(f'request {loc}') + if loc.startswith('/'): + loc = loc[1:] + if not loc: + loc = 'index.html' + try: + if loc == 'favicon.ico': + raise FileNotFoundError + f = open(loc, 'rb') + c = f.read() + f.close() + print(f'successfully requested {loc}') + if loc.endswith('.js'): + mime = 'application/javascript' + elif loc.endswith('.html'): + mime = 'text/html' + elif loc.endswith('.wasm'): + mime = 'application/wasm' + else: + mime = 'text/plain' + packet = f'HTTP/1.1 200 Success\r\nContent-Length: {len(c)}\r\nContent-Type: {mime}\r\n{ADD_HEADERS}\r\n\r\n'.encode('utf-8') + c + self.sock.send(packet) + except FileNotFoundError: + print(f'error request {loc}') + self.sock.send(f'HTTP/1.1 404 Not Found\r\nContent-Length: 0\r\nContent-Type: text/plain\r\n\r\n'.encode('utf-8')) def run(self): - method, loc, attrs = self.rec() - self.sen(loc, ver) + while True: + method, loc, attrs, ver = self.rec() + self.sen(loc, ver) -clients = [] +def run_server(): + ws = socket() + ws.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) + ws.bind(('localhost', 8080)) + ws.listen() -while True: - c, a = ws.accept() - print(f'{a[0]}:{a[1]} connected') - client = Client(c, a) - clients.append(clients) - client.run() + clients = [] + + while True: + c, a = ws.accept() + print(f'{a[0]}:{a[1]} connected') + client = Client(c, a) + clients.append(clients) + client.run() + + +if __name__ == '__main__': + from sys import argv + if len(argv) > 1 and argv[1] in ('-d', '--daemon'): + from os import getcwd + from daemon import DaemonContext + with DaemonContext(working_directory=getcwd()): + run_server() + else: + run_server() diff --git a/WebInterface/wasm/webhogg/killpy b/WebInterface/wasm/webhogg/killpy new file mode 100755 index 0000000..5e2b9bc --- /dev/null +++ b/WebInterface/wasm/webhogg/killpy @@ -0,0 +1,2 @@ +#!/bin/sh +killall python3 diff --git a/WebInterface/wasm/webhogg/lighttpd.config b/WebInterface/wasm/webhogg/lighttpd.config deleted file mode 100644 index 4072b30..0000000 --- a/WebInterface/wasm/webhogg/lighttpd.config +++ /dev/null @@ -1,34 +0,0 @@ -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/mimes b/WebInterface/wasm/webhogg/mimes deleted file mode 100644 index 007445d..0000000 --- a/WebInterface/wasm/webhogg/mimes +++ /dev/null @@ -1 +0,0 @@ -application/wasm wasm -- cgit v1.2.3-54-g00ecf From 4cdb0d88a065df2456b3e12389836eebc9b2fa4a Mon Sep 17 00:00:00 2001 From: Dennis Kobert Date: Fri, 31 May 2019 16:40:00 +0200 Subject: Fix issues in Collide --- game_server/src/collide.rs | 63 ++++++++++++++++++++++++++++++++++++---------- game_server/src/main.rs | 3 --- game_server/src/maths.rs | 14 +++++------ 3 files changed, 57 insertions(+), 23 deletions(-) diff --git a/game_server/src/collide.rs b/game_server/src/collide.rs index 4169787..4217e7f 100644 --- a/game_server/src/collide.rs +++ b/game_server/src/collide.rs @@ -1,36 +1,73 @@ +use crate::maths::{Vec2, Box, RBox}; + pub trait Collide { fn collides(&self, other: &Rhs) -> bool; } impl Collide for Vec2 { - fn collides(self, other: Self) { + fn collides(&self, other: &Self) -> bool { self == other } } impl Collide for Box { - fn collides(self, other: Vec2) { - self.pos < other < self.pos + self.size + fn collides(&self, other: &Vec2) -> bool { + self.pos < other && other < self.pos + self.size } } impl Collide for Box { - fn collides(self, other: Self) { - self.collides(other.pos) - || other.collides(self.pos) + fn collides(&self, other: &Self) -> bool { + self.collides(other.pos) + || self.collides(other.pos + Vec2{x: other.x, y: 0}) + || self.collides(other.pos + Vec2{x: 0, y: other.y}) + || self.collides(other.pos + other.size) + + || other.collides(self.pos) + || other.collides(self.pos + Vec2{x: self.x, y: 0}) + || other.collides(self.pos + Vec2{x: 0, y: self.y}) + || other.collides(self.pos + self.size) } } impl Collide for RBox { - fn collides(self, other: Vec2) { - - || other.pos < self.pos < other.pos + other.size + fn collides(&self, other: &Vec2) -> bool { + let dx = self.size.x; + let dy = self.size.y; + let len = f32::sqrt(dx*dx+dy*dy); + dx /= len; + dy /= len; + + let dax = other.x - self.p1.x; + let day = other.y - self.p1.y; + + let dot = dax * dx + day * dy; + let px = self.pos.x + dx * dot; + let py = self.pos.y + dy * dot; + + if !(self.pos < px && px < self.pos + self.size) { + return false; + } + + let ddx = other.x-px; + let ddy = other.y-py; + let manhattenDistance = ddx + ddy; + + manhattenDistance < self.w } } -impl Collide for Box { - fn collides(self, other: Self) { - self.pos < other.pos < self.pos + self.size - || other.pos < self.pos < other.pos + other.size +impl Collide for RBox { + fn collides(&self, other: &Box) -> bool { + self.collides(other.pos) + || self.collides(other.pos + Vec2{x: other.x, y: 0}) + || self.collides(other.pos + Vec2{x: 0, y: other.y}) + || self.collides(other.pos + other.size) + + || other.collides(self.pos) + || other.collides(self.pos + Vec2{x: self.x, y: 0}) + || other.collides(self.pos + Vec2{x: 0, y: self.y}) + || other.collides(self.pos + self.size) + } } diff --git a/game_server/src/main.rs b/game_server/src/main.rs index e10fe3c..cfd9787 100644 --- a/game_server/src/main.rs +++ b/game_server/src/main.rs @@ -1,12 +1,9 @@ mod group; mod maths; mod scribble_group; -<<<<<<< Updated upstream -======= mod webhogg_group; mod webhogg_game; mod collide; ->>>>>>> Stashed changes mod lobby; mod server; mod backend_connection; diff --git a/game_server/src/maths.rs b/game_server/src/maths.rs index 8844c6e..a55c5ce 100644 --- a/game_server/src/maths.rs +++ b/game_server/src/maths.rs @@ -93,10 +93,10 @@ impl std::ops::Sub for Box { pub struct RBox { /// Point 1 - pub p1: Vec2, + pub pos: Vec2, /// Point 2 - pub p2: Vec2, - /// Width + pub size: Vec2, + /// Width Attention manhatten distance!!! pub w: f32, } @@ -104,8 +104,8 @@ impl std::ops::Add for RBox { type Output = Self; fn add(self, other: Vec2) -> Self { Self { - p1: self.p1 + other, - p2: self.p2 + other, + pos: self.p1 + other, + size: self.p2 + other, w: self.w, } } @@ -115,8 +115,8 @@ impl std::ops::Sub for RBox { type Output = Self; fn sub(self, other: Vec2) -> Self { Self { - p1: self.p1 + other, - p2: self.p2 + other, + pos: self.p1 + other, + size: self.p2 + other, w: self.w, } } -- cgit v1.2.3-54-g00ecf From 2f7b8cfb0c48b600ebd80bdfb3ef9f04410b0b91 Mon Sep 17 00:00:00 2001 From: Dennis Kobert Date: Fri, 31 May 2019 17:05:22 +0200 Subject: Use references for Colision trait implementations --- game_server/src/collide.rs | 49 +++++++++++++++++++++++----------------------- game_server/src/maths.rs | 12 ++++++------ 2 files changed, 31 insertions(+), 30 deletions(-) diff --git a/game_server/src/collide.rs b/game_server/src/collide.rs index 4217e7f..ac046dd 100644 --- a/game_server/src/collide.rs +++ b/game_server/src/collide.rs @@ -12,40 +12,41 @@ impl Collide for Vec2 { impl Collide for Box { fn collides(&self, other: &Vec2) -> bool { - self.pos < other && other < self.pos + self.size + self.pos < *other && other < &(self.pos + self.size) } } impl Collide for Box { fn collides(&self, other: &Self) -> bool { - self.collides(other.pos) - || self.collides(other.pos + Vec2{x: other.x, y: 0}) - || self.collides(other.pos + Vec2{x: 0, y: other.y}) - || self.collides(other.pos + other.size) + self.collides(&other.pos) + || self.collides(&(other.pos + Vec2{x: other.size.x, y: 0.0})) + || self.collides(&(other.pos + Vec2{x: 0.0, y: other.size.y})) + || self.collides(&(other.pos + other.size)) - || other.collides(self.pos) - || other.collides(self.pos + Vec2{x: self.x, y: 0}) - || other.collides(self.pos + Vec2{x: 0, y: self.y}) - || other.collides(self.pos + self.size) + || other.collides(&(self.pos)) + || other.collides(&(self.pos + Vec2{x: self.size.x, y: 0.0})) + || other.collides(&(self.pos + Vec2{x: 0.0, y: self.size.y})) + || other.collides(&(self.pos + self.size)) } } impl Collide for RBox { fn collides(&self, other: &Vec2) -> bool { - let dx = self.size.x; - let dy = self.size.y; - let len = f32::sqrt(dx*dx+dy*dy); + let mut dx = self.size.x; + let mut dy = self.size.y; + let len = self.size.distance(); dx /= len; dy /= len; - let dax = other.x - self.p1.x; - let day = other.y - self.p1.y; + let dax = other.x - self.pos.x; + let day = other.y - self.pos.y; let dot = dax * dx + day * dy; let px = self.pos.x + dx * dot; let py = self.pos.y + dy * dot; - if !(self.pos < px && px < self.pos + self.size) { + let p = Vec2{x: px, y: py}; + if !(self.pos < p && p < self.pos + self.size) { return false; } @@ -59,15 +60,15 @@ impl Collide for RBox { impl Collide for RBox { fn collides(&self, other: &Box) -> bool { - self.collides(other.pos) - || self.collides(other.pos + Vec2{x: other.x, y: 0}) - || self.collides(other.pos + Vec2{x: 0, y: other.y}) - || self.collides(other.pos + other.size) - - || other.collides(self.pos) - || other.collides(self.pos + Vec2{x: self.x, y: 0}) - || other.collides(self.pos + Vec2{x: 0, y: self.y}) - || other.collides(self.pos + self.size) + self.collides(&other.pos) + || self.collides(&(other.pos + Vec2{x: other.size.x, y: 0.0})) + || self.collides(&(other.pos + Vec2{x: 0.0, y: other.size.y})) + || self.collides(&(other.pos + other.size)) + + || other.collides(&(self.pos)) + || other.collides(&(self.pos + Vec2{x: self.size.x, y: 0.0})) + || other.collides(&(self.pos + Vec2{x: 0.0, y: self.size.y})) + || other.collides(&(self.pos + self.size)) } } diff --git a/game_server/src/maths.rs b/game_server/src/maths.rs index a55c5ce..f5ceab4 100644 --- a/game_server/src/maths.rs +++ b/game_server/src/maths.rs @@ -75,8 +75,8 @@ impl std::ops::Add for Box { type Output = Self; fn add(self, other: Vec2) -> Self { Self { - p1: self.p1 + other, - p2: self.p2 + other, + pos: self.pos + other, + size: self.size + other, } } } @@ -104,8 +104,8 @@ impl std::ops::Add for RBox { type Output = Self; fn add(self, other: Vec2) -> Self { Self { - pos: self.p1 + other, - size: self.p2 + other, + pos: self.pos + other, + size: self.size + other, w: self.w, } } @@ -115,8 +115,8 @@ impl std::ops::Sub for RBox { type Output = Self; fn sub(self, other: Vec2) -> Self { Self { - pos: self.p1 + other, - size: self.p2 + other, + pos: self.pos + other, + size: self.size + other, w: self.w, } } -- cgit v1.2.3-54-g00ecf From e052a0da267ac8594f3b896573a204a739340e54 Mon Sep 17 00:00:00 2001 From: natrixaeria Date: Sat, 1 Jun 2019 01:48:30 +0200 Subject: Create multithreading through web workers --- WebInterface/wasm/webhogg/deploy.py | 26 +++- WebInterface/wasm/webhogg/graphics.js | 113 +++++++++++++- WebInterface/wasm/webhogg/loader.js | 274 +++++++++++++++++++++++++++++++++- WebInterface/wasm/webhogg/src/lib.rs | 3 +- WebInterface/wasm/webhogg/webhogg.js | 15 +- 5 files changed, 407 insertions(+), 24 deletions(-) diff --git a/WebInterface/wasm/webhogg/deploy.py b/WebInterface/wasm/webhogg/deploy.py index 278becd..7bc56ac 100755 --- a/WebInterface/wasm/webhogg/deploy.py +++ b/WebInterface/wasm/webhogg/deploy.py @@ -2,8 +2,20 @@ from socket import socket, SOL_SOCKET, SO_REUSEADDR -ADD_HEADERS = 'Content-Security-Policy: worker-src localhost:*' -ADD_HEADERS = "Content-Security-Policy: script-src 'inline' *; worker-src *" +if False: + CSP = { + 'script-src': ["*", "'unsafe-inline'"], + 'worker-src': ["*", "'unsafe-inline'"], + 'style-src': ["*", "'unsafe-inline'"], + 'default-src': ["*", "'unsafe-inline'"], + } + + ADD_HEADERS = 'Content-Security-Policy: ' + '; '.join( + k + ' ' + ' '.join(v) for k, v in CSP.items()) + # ADD_HEADERS += '\r\n' + ADD_HEADERS.replace('cy: ', 'cy-Report-Only: ') + print(ADD_HEADERS) + ADD_HEADERS = '\r\n' + ADD_HEADERS +ADD_HEADERS = '' class Client: def __init__(self, sock, addr): @@ -40,11 +52,16 @@ class Client: mime = 'application/wasm' else: mime = 'text/plain' - packet = f'HTTP/1.1 200 Success\r\nContent-Length: {len(c)}\r\nContent-Type: {mime}\r\n{ADD_HEADERS}\r\n\r\n'.encode('utf-8') + c + packet = f'HTTP/1.1 200 Success\r\nContent-Length: {len(c)}\r\nContent-Type: {mime}{ADD_HEADERS}\r\n\r\n'.encode('utf-8') + c self.sock.send(packet) except FileNotFoundError: print(f'error request {loc}') self.sock.send(f'HTTP/1.1 404 Not Found\r\nContent-Length: 0\r\nContent-Type: text/plain\r\n\r\n'.encode('utf-8')) + finally: + try: + f.close() + except: + ... def run(self): while True: @@ -71,9 +88,10 @@ def run_server(): if __name__ == '__main__': from sys import argv if len(argv) > 1 and argv[1] in ('-d', '--daemon'): + import sys from os import getcwd from daemon import DaemonContext - with DaemonContext(working_directory=getcwd()): + with DaemonContext(working_directory=getcwd(), stderr=sys.stderr): run_server() else: run_server() diff --git a/WebInterface/wasm/webhogg/graphics.js b/WebInterface/wasm/webhogg/graphics.js index f3bab19..e4759e9 100644 --- a/WebInterface/wasm/webhogg/graphics.js +++ b/WebInterface/wasm/webhogg/graphics.js @@ -1,6 +1,111 @@ -import {default as init_r} from './webhogg.js' -import {init_x} from './webhogg.js' +const __exports = {}; +let wasm; -let module = init_r('./pkg/webhogg_bg.wasm'); +let cachedTextDecoder = new TextDecoder('utf-8'); -init_x(module, 'graphics', null); +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 + +const heap = new Array(32); + +heap.fill(undefined); + +heap.push(undefined, null, true, false); + +let heap_next = heap.length; + +function addHeapObject(obj) { + if (heap_next === heap.length) heap.push(heap.length + 1); + const idx = heap_next; + heap_next = heap[idx]; + + heap[idx] = obj; + return idx; +} +/** +* @param {any} worker +* @returns {void} +*/ +function game_logic_entry(worker) { + return wasm.game_logic_entry(addHeapObject(worker)); +} +__exports.game_logic_entry = game_logic_entry + +/** +* @param {any} worker +* @returns {void} +*/ +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 dropObject(idx) { + if (idx < 36) return; + heap[idx] = heap_next; + heap_next = idx; +} + +function __wbindgen_object_drop_ref(i) { dropObject(i); } +__exports.__wbindgen_object_drop_ref = __wbindgen_object_drop_ref + +const WASM_URL = './pkg/webhogg_bg.wasm'; + +const imports = { './webhogg': __exports }; +let res = WebAssembly.instantiateStreaming(fetch(WASM_URL), imports); + +res.then(result => { + console.log(result); + wasm = result.instance.exports; + wasm.graphics_entry(); +}); + +onmessage = function (e) { + console.log('gooot messaaage', e); +} diff --git a/WebInterface/wasm/webhogg/loader.js b/WebInterface/wasm/webhogg/loader.js index cc66ff6..159dbb9 100644 --- a/WebInterface/wasm/webhogg/loader.js +++ b/WebInterface/wasm/webhogg/loader.js @@ -1,9 +1,273 @@ -import {default as init_r} from './webhogg.js' -import {init_x} from './webhogg.js' +const __exports = {}; +let wasm; -let module = init_r('./pkg/webhogg_bg.wasm'); +let cachedTextDecoder = new TextDecoder('utf-8'); -let graphics = new Worker('./graphics.js') +let cachegetUint8Memory = null; +function getUint8Memory() { + if (cachegetUint8Memory === null || cachegetUint8Memory.buffer !== wasm.memory.buffer) { + cachegetUint8Memory = new Uint8Array(wasm.memory.buffer); + } + return cachegetUint8Memory; +} -init_x(module, 'game logic', graphics); +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 + +const heap = new Array(32); + +heap.fill(undefined); + +heap.push(undefined, null, true, false); + +let heap_next = heap.length; + +function addHeapObject(obj) { + if (heap_next === heap.length) heap.push(heap.length + 1); + const idx = heap_next; + heap_next = heap[idx]; + + heap[idx] = obj; + return idx; +} +/** +* @param {any} worker +* @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() { + return wasm.graphics_entry(); +} +__exports.graphics_entry = graphics_entry + +function getObject(idx) { return heap[idx]; } + +let cachegetUint32Memory = null; +function getUint32Memory() { + if (cachegetUint32Memory === null || cachegetUint32Memory.buffer !== wasm.memory.buffer) { + cachegetUint32Memory = new Uint32Array(wasm.memory.buffer); + } + return cachegetUint32Memory; +} + +function handleError(exnptr, e) { + const view = getUint32Memory(); + view[exnptr / 4] = 1; + view[exnptr / 4 + 1] = addHeapObject(e); +} + +function __widl_f_post_message_Worker(arg0, arg1, exnptr) { + try { + getObject(arg0).postMessage(getObject(arg1)); + } catch (e) { + handleError(exnptr, e); + } +} +__exports.__widl_f_post_message_Worker = __widl_f_post_message_Worker + +function __wbindgen_string_new(p, l) { return addHeapObject(getStringFromWasm(p, l)); } +__exports.__wbindgen_string_new = __wbindgen_string_new + +let WASM_VECTOR_LEN = 0; + +let cachedTextEncoder = new TextEncoder('utf-8'); + +let passStringToWasm; +if (typeof cachedTextEncoder.encodeInto === 'function') { + passStringToWasm = function(arg) { + + + let size = arg.length; + let ptr = wasm.__wbindgen_malloc(size); + let offset = 0; + { + const mem = getUint8Memory(); + for (; offset < arg.length; offset++) { + const code = arg.charCodeAt(offset); + if (code > 0x7F) break; + mem[ptr + offset] = code; + } + } + + if (offset !== arg.length) { + arg = arg.slice(offset); + ptr = wasm.__wbindgen_realloc(ptr, size, size = offset + arg.length * 3); + const view = getUint8Memory().subarray(ptr + offset, ptr + size); + const ret = cachedTextEncoder.encodeInto(arg, view); + + offset += ret.written; + } + WASM_VECTOR_LEN = offset; + return ptr; + }; +} else { + passStringToWasm = function(arg) { + + + let size = arg.length; + let ptr = wasm.__wbindgen_malloc(size); + let offset = 0; + { + const mem = getUint8Memory(); + for (; offset < arg.length; offset++) { + const code = arg.charCodeAt(offset); + if (code > 0x7F) break; + mem[ptr + offset] = code; + } + } + + if (offset !== arg.length) { + const buf = cachedTextEncoder.encode(arg.slice(offset)); + ptr = wasm.__wbindgen_realloc(ptr, size, size = offset + buf.length); + getUint8Memory().set(buf, ptr + offset); + offset += buf.length; + } + WASM_VECTOR_LEN = offset; + return ptr; + }; +} + +function __wbindgen_debug_string(i, len_ptr) { + 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; +} +; +const toString = Object.prototype.toString; +const val = getObject(i); +const debug = debug_str(val); +const ptr = passStringToWasm(debug); +getUint32Memory()[len_ptr / 4] = WASM_VECTOR_LEN; +return ptr; +} +__exports.__wbindgen_debug_string = __wbindgen_debug_string + +function __wbindgen_throw(ptr, len) { + throw new Error(getStringFromWasm(ptr, len)); +} +__exports.__wbindgen_throw = __wbindgen_throw + +function dropObject(idx) { + if (idx < 36) return; + heap[idx] = heap_next; + heap_next = idx; +} + +function __wbindgen_object_drop_ref(i) { dropObject(i); } +__exports.__wbindgen_object_drop_ref = __wbindgen_object_drop_ref + +const WASM_URL = './pkg/webhogg_bg.wasm'; + +const imports = { './webhogg': __exports }; +let res = WebAssembly.instantiateStreaming(fetch(WASM_URL), imports); + +let graphics = new Worker('./graphics.js', {type: 'module', credentials: 'include'}); + +res.then(result => { + console.log(result); + wasm = result.instance.exports; + wasm.game_logic_entry(graphics); +}); diff --git a/WebInterface/wasm/webhogg/src/lib.rs b/WebInterface/wasm/webhogg/src/lib.rs index 4a79a24..5823e72 100644 --- a/WebInterface/wasm/webhogg/src/lib.rs +++ b/WebInterface/wasm/webhogg/src/lib.rs @@ -23,10 +23,11 @@ pub fn game_logic_entry(worker: Worker) { client_logger::init_logger(); info!("game logic initialisation"); + //worker.post_message(&wasm_bindgen::JsValue::from_str("msg frm wasm_gLe")).unwrap(); } #[wasm_bindgen] -pub fn graphics_entry(worker: Worker) { +pub fn graphics_entry() { client_logger::init_logger(); info!("graphics initialisation"); diff --git a/WebInterface/wasm/webhogg/webhogg.js b/WebInterface/wasm/webhogg/webhogg.js index 751ac77..c01d70f 100644 --- a/WebInterface/wasm/webhogg/webhogg.js +++ b/WebInterface/wasm/webhogg/webhogg.js @@ -1,6 +1,4 @@ - const __exports = {}; -let wasm; let cachedTextDecoder = new TextDecoder('utf-8'); @@ -47,9 +45,7 @@ function __wbg_error_56a861ecc80f27e1(arg0, arg1, arg2, arg3, 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)); } @@ -58,8 +54,8 @@ __exports.game_logic_entry = game_logic_entry /** * @returns {void} */ -export function graphics_entry(worker) { - return wasm.graphics_entry(addHeapObject(worker)); +export function graphics_entry() { + return wasm.graphics_entry(); } __exports.graphics_entry = graphics_entry @@ -102,11 +98,10 @@ function init_r(module) { return result; } -function _init_x(result, bx) { +function _init_x(result, worker) { return result.then(({instance, module}) => { wasm = instance.exports; - if (bx == 1) wasm.game_logic_entry(); - else wasm.graphics_entry(); + wasm.game_logic_entry(worker); //init_r.__wbindgen_wasm_module = module; //wasm.__wbindgen_start(); return wasm; -- cgit v1.2.3-54-g00ecf From 2f99c5e8b3cfcba29894505d25d8d6363d92ed3f Mon Sep 17 00:00:00 2001 From: Dennis Kobert Date: Sat, 1 Jun 2019 02:02:10 +0200 Subject: Adress issues specified in pull qeruest --- game_server/src/collide.rs | 24 +++++++++++++----------- game_server/src/maths.rs | 19 +++++++++++++------ 2 files changed, 26 insertions(+), 17 deletions(-) diff --git a/game_server/src/collide.rs b/game_server/src/collide.rs index ac046dd..21ec99c 100644 --- a/game_server/src/collide.rs +++ b/game_server/src/collide.rs @@ -1,4 +1,4 @@ -use crate::maths::{Vec2, Box, RBox}; +use crate::maths::{Vec2, AABox, RBox}; pub trait Collide { fn collides(&self, other: &Rhs) -> bool; @@ -10,13 +10,13 @@ impl Collide for Vec2 { } } -impl Collide for Box { +impl Collide for AABox { fn collides(&self, other: &Vec2) -> bool { self.pos < *other && other < &(self.pos + self.size) } } -impl Collide for Box { +impl Collide for AABox { fn collides(&self, other: &Self) -> bool { self.collides(&other.pos) || self.collides(&(other.pos + Vec2{x: other.size.x, y: 0.0})) @@ -32,18 +32,14 @@ impl Collide for Box { impl Collide for RBox { fn collides(&self, other: &Vec2) -> bool { - let mut dx = self.size.x; - let mut dy = self.size.y; - let len = self.size.distance(); - dx /= len; - dy /= len; + let da = self.size.norm(); let dax = other.x - self.pos.x; let day = other.y - self.pos.y; - let dot = dax * dx + day * dy; + let dot = dax * da.x + day * da.y; let px = self.pos.x + dx * dot; - let py = self.pos.y + dy * dot; + let py = self.pos.y + da.y * dot; let p = Vec2{x: px, y: py}; if !(self.pos < p && p < self.pos + self.size) { @@ -58,7 +54,7 @@ impl Collide for RBox { } } -impl Collide for RBox { +impl Collide for RBox { fn collides(&self, other: &Box) -> bool { self.collides(&other.pos) || self.collides(&(other.pos + Vec2{x: other.size.x, y: 0.0})) @@ -72,3 +68,9 @@ impl Collide for RBox { } } + +impl> Collide for Vec { + fn collides(&self, other: &S) -> bool { + self.iter().any(|x| x.collides(other)) + } +} diff --git a/game_server/src/maths.rs b/game_server/src/maths.rs index f5ceab4..7b844dc 100644 --- a/game_server/src/maths.rs +++ b/game_server/src/maths.rs @@ -63,30 +63,37 @@ impl Vec2 { pub fn distance2(&self) -> f32 { self.x * self.x + self.y * self.y } + + pub fn norm(&self) -> Vec2 { + let len = self.size.distance(); + Vec2 { + x: self.x / len, + y: self.y / len, + } + } } -pub struct Box { +pub struct AABox { pub pos: Vec2, /// the size may not be smaller than zero pub size: Vec2, } -impl std::ops::Add for Box { +impl std::ops::Add for AABox { type Output = Self; fn add(self, other: Vec2) -> Self { Self { pos: self.pos + other, - size: self.size + other, } } } -impl std::ops::Sub for Box { +impl std::ops::Sub for AABox { type Output = Self; fn sub(self, other: Vec2) -> Self { Self { pos: self.pos + other, - size: self.size + other + size: self.size } } } @@ -105,7 +112,7 @@ impl std::ops::Add for RBox { fn add(self, other: Vec2) -> Self { Self { pos: self.pos + other, - size: self.size + other, + size: self.size, w: self.w, } } -- cgit v1.2.3-54-g00ecf From de3d86164acaa9aeb78f28e3201ff1a40b212f04 Mon Sep 17 00:00:00 2001 From: natrixaeria Date: Sat, 1 Jun 2019 02:26:39 +0200 Subject: Communicate from game logic to graphics please run the 'run'-script every time before loading the page --- WebInterface/wasm/webhogg/graphics.js | 175 +++++++++++++++++++++++++++++++++- WebInterface/wasm/webhogg/index.html | 2 +- WebInterface/wasm/webhogg/loader.js | 9 +- WebInterface/wasm/webhogg/run | 3 + WebInterface/wasm/webhogg/src/lib.rs | 5 +- WebInterface/wasm/webhogg/update.py | 29 ++++++ 6 files changed, 212 insertions(+), 11 deletions(-) create mode 100644 WebInterface/wasm/webhogg/update.py diff --git a/WebInterface/wasm/webhogg/graphics.js b/WebInterface/wasm/webhogg/graphics.js index e4759e9..bafae3d 100644 --- a/WebInterface/wasm/webhogg/graphics.js +++ b/WebInterface/wasm/webhogg/graphics.js @@ -73,14 +73,177 @@ function game_logic_entry(worker) { __exports.game_logic_entry = game_logic_entry /** -* @param {any} worker * @returns {void} */ -function graphics_entry(worker) { - return wasm.graphics_entry(addHeapObject(worker)); +function graphics_entry() { + return wasm.graphics_entry(); } __exports.graphics_entry = graphics_entry +function getObject(idx) { return heap[idx]; } + +let cachegetUint32Memory = null; +function getUint32Memory() { + if (cachegetUint32Memory === null || cachegetUint32Memory.buffer !== wasm.memory.buffer) { + cachegetUint32Memory = new Uint32Array(wasm.memory.buffer); + } + return cachegetUint32Memory; +} + +function handleError(exnptr, e) { + const view = getUint32Memory(); + view[exnptr / 4] = 1; + view[exnptr / 4 + 1] = addHeapObject(e); +} + +function __widl_f_post_message_Worker(arg0, arg1, exnptr) { + try { + getObject(arg0).postMessage(getObject(arg1)); + } catch (e) { + handleError(exnptr, e); + } +} +__exports.__widl_f_post_message_Worker = __widl_f_post_message_Worker + +function __wbindgen_string_new(p, l) { return addHeapObject(getStringFromWasm(p, l)); } +__exports.__wbindgen_string_new = __wbindgen_string_new + +let WASM_VECTOR_LEN = 0; + +let cachedTextEncoder = new TextEncoder('utf-8'); + +let passStringToWasm; +if (typeof cachedTextEncoder.encodeInto === 'function') { + passStringToWasm = function(arg) { + + + let size = arg.length; + let ptr = wasm.__wbindgen_malloc(size); + let offset = 0; + { + const mem = getUint8Memory(); + for (; offset < arg.length; offset++) { + const code = arg.charCodeAt(offset); + if (code > 0x7F) break; + mem[ptr + offset] = code; + } + } + + if (offset !== arg.length) { + arg = arg.slice(offset); + ptr = wasm.__wbindgen_realloc(ptr, size, size = offset + arg.length * 3); + const view = getUint8Memory().subarray(ptr + offset, ptr + size); + const ret = cachedTextEncoder.encodeInto(arg, view); + + offset += ret.written; + } + WASM_VECTOR_LEN = offset; + return ptr; + }; +} else { + passStringToWasm = function(arg) { + + + let size = arg.length; + let ptr = wasm.__wbindgen_malloc(size); + let offset = 0; + { + const mem = getUint8Memory(); + for (; offset < arg.length; offset++) { + const code = arg.charCodeAt(offset); + if (code > 0x7F) break; + mem[ptr + offset] = code; + } + } + + if (offset !== arg.length) { + const buf = cachedTextEncoder.encode(arg.slice(offset)); + ptr = wasm.__wbindgen_realloc(ptr, size, size = offset + buf.length); + getUint8Memory().set(buf, ptr + offset); + offset += buf.length; + } + WASM_VECTOR_LEN = offset; + return ptr; + }; +} + +function __wbindgen_debug_string(i, len_ptr) { + 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; +} +; +const toString = Object.prototype.toString; +const val = getObject(i); +const debug = debug_str(val); +const ptr = passStringToWasm(debug); +getUint32Memory()[len_ptr / 4] = WASM_VECTOR_LEN; +return ptr; +} +__exports.__wbindgen_debug_string = __wbindgen_debug_string + function __wbindgen_throw(ptr, len) { throw new Error(getStringFromWasm(ptr, len)); } @@ -95,6 +258,8 @@ function dropObject(idx) { function __wbindgen_object_drop_ref(i) { dropObject(i); } __exports.__wbindgen_object_drop_ref = __wbindgen_object_drop_ref +//!IMPORTANT_STUFF + const WASM_URL = './pkg/webhogg_bg.wasm'; const imports = { './webhogg': __exports }; @@ -103,9 +268,9 @@ let res = WebAssembly.instantiateStreaming(fetch(WASM_URL), imports); res.then(result => { console.log(result); wasm = result.instance.exports; - wasm.graphics_entry(); + graphics_entry(); }); onmessage = function (e) { - console.log('gooot messaaage', e); + console.log('gooot messaaage', e.data); } diff --git a/WebInterface/wasm/webhogg/index.html b/WebInterface/wasm/webhogg/index.html index ce09537..ced7e94 100644 --- a/WebInterface/wasm/webhogg/index.html +++ b/WebInterface/wasm/webhogg/index.html @@ -3,7 +3,7 @@ webhogg - + - - - - - diff --git a/WebInterface/wasm/asm-paint/lighttpd.config b/WebInterface/wasm/asm-paint/lighttpd.config deleted file mode 100644 index 5fae32d..0000000 --- a/WebInterface/wasm/asm-paint/lighttpd.config +++ /dev/null @@ -1,29 +0,0 @@ -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.document-root = "/home/jan/projects/DiscoBot/WebInterface/wasm/asm-paint" -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/x-javascript", - ".jpg" => "image/jpeg", - ".jpeg" => "image/jpeg", - ".gif" => "image/gif", - ".png" => "image/png", - ".wasm" => "application/wasm", - "" => "application/octet-stream" -) diff --git a/WebInterface/wasm/asm-paint/loader.js b/WebInterface/wasm/asm-paint/loader.js deleted file mode 100644 index 4566ee1..0000000 --- a/WebInterface/wasm/asm-paint/loader.js +++ /dev/null @@ -1,2 +0,0 @@ -import {default as init} from './pkg/asm_paint_rs.js' -init('./pkg/asm_paint_rs_bg.wasm'); diff --git a/WebInterface/wasm/asm-paint/run b/WebInterface/wasm/asm-paint/run deleted file mode 100755 index 1da1e35..0000000 --- a/WebInterface/wasm/asm-paint/run +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh - -wasm-pack build --release --target web diff --git a/WebInterface/wasm/asm-paint/src/app.rs b/WebInterface/wasm/asm-paint/src/app.rs deleted file mode 100644 index 005764d..0000000 --- a/WebInterface/wasm/asm-paint/src/app.rs +++ /dev/null @@ -1,19 +0,0 @@ -use crate::site::Site; - -pub struct App { - site: Site, -} - -impl App { - pub fn new() -> Option { - Some(Self { - site: Site::from_current()?, - }) - } - - pub fn run(&mut self) { - let mut canvas = self.site.create_canvas().unwrap(); - canvas.init().unwrap(); - info!("canvas initialisation was succuessfull"); - } -} diff --git a/WebInterface/wasm/asm-paint/src/canvas.rs b/WebInterface/wasm/asm-paint/src/canvas.rs deleted file mode 100644 index 400e258..0000000 --- a/WebInterface/wasm/asm-paint/src/canvas.rs +++ /dev/null @@ -1,39 +0,0 @@ -use web_sys; -use web_sys::{WebGl2RenderingContext}; -use wasm_bindgen::JsCast; -use crate::shader::Shaders; - -pub struct Canvas { - element: web_sys::HtmlCanvasElement, - ctx: WebGl2RenderingContext, - shaders: Shaders, -} - -impl Canvas { - pub fn new(element: web_sys::Element) -> Option { - let element: web_sys::HtmlCanvasElement = - element.dyn_into::() - .ok()?; - debug!("create webgl2 context"); - let ctx = element.get_context("webgl2").ok()?? - .dyn_into::().ok()?; - info!("created webgl2 context successfully"); - Some(Self { - element, ctx, - shaders: Shaders::new(), - }) - } - - pub fn init(&mut self) -> Result<(), ()> { - self.shaders.init(&self.ctx).map_err(|_|())?; - self.ctx.clear_color(1.0, 0.2, 1.0, 1.0); - self.ctx.clear(WebGl2RenderingContext::COLOR_BUFFER_BIT); - Ok(()) - } -} - -impl Drop for Canvas { - fn drop(&mut self) { - self.shaders.remove(&self.ctx); - } -} diff --git a/WebInterface/wasm/asm-paint/src/client_logger.rs b/WebInterface/wasm/asm-paint/src/client_logger.rs deleted file mode 100644 index f71918f..0000000 --- a/WebInterface/wasm/asm-paint/src/client_logger.rs +++ /dev/null @@ -1,46 +0,0 @@ -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/asm-paint/src/lib.rs b/WebInterface/wasm/asm-paint/src/lib.rs deleted file mode 100644 index 6c773c5..0000000 --- a/WebInterface/wasm/asm-paint/src/lib.rs +++ /dev/null @@ -1,20 +0,0 @@ -mod client_logger; -mod shader; -mod canvas; -mod site; -mod app; - -use wasm_bindgen::prelude::*; - -#[macro_use] -extern crate log; - -#[wasm_bindgen(start)] -pub fn entry() { - client_logger::init_logger(); - - info!("begin running wasm application"); - - let mut app = app::App::new().unwrap(); - app.run(); -} diff --git a/WebInterface/wasm/asm-paint/src/shader.rs b/WebInterface/wasm/asm-paint/src/shader.rs deleted file mode 100644 index 3352bcf..0000000 --- a/WebInterface/wasm/asm-paint/src/shader.rs +++ /dev/null @@ -1,97 +0,0 @@ -use web_sys::{WebGlProgram, WebGl2RenderingContext}; - -const VERTEX_SHADER: &str = -r#"#version 300 es -in vec4 pos; -void main() { - gl_Position = pos; -} -"#; - -const FRAGMENT_SHADER: &str = -r#"#version 300 es -precision mediump float; -out vec4 color; - -void main() { - color = vec4(1, 0, 0, 1); -} -"#; - -pub struct Shaders { - program: Option, - pos_loc: i32, -} - -impl Shaders { - pub fn new() -> Self { - Self { - program: None, - pos_loc: -1 - } - } - - fn create_program(&mut self, ctx: &WebGl2RenderingContext) -> Result<(), String> { - self.program = Some(ctx.create_program().ok_or("could not create program id")?); - Ok(()) - } - - fn create_shader(&mut self, ctx: &WebGl2RenderingContext, - shader_type: u32, source: &str) -> Result<(), String> { - let program = self.program.as_ref().ok_or("could not find created program")?; - let shader = ctx.create_shader(shader_type) - .ok_or("could not create shader")?; - ctx.shader_source(&shader, source); - ctx.compile_shader(&shader); - let status = ctx.get_shader_parameter(&shader, WebGl2RenderingContext::COMPILE_STATUS); - if status == wasm_bindgen::JsValue::TRUE { - ctx.attach_shader(program, &shader); - Ok(()) - } else { - Err(format!("\n{}", ctx.get_shader_info_log(&shader).unwrap_or_default())) - } - } - - fn create_vertex_shader(&mut self, ctx: &WebGl2RenderingContext) -> Result<(), String> { - self.create_shader(ctx, WebGl2RenderingContext::VERTEX_SHADER, VERTEX_SHADER) - } - - fn create_fragment_shader(&mut self, ctx: &WebGl2RenderingContext) -> Result<(), String> { - self.create_shader(ctx, WebGl2RenderingContext::FRAGMENT_SHADER, FRAGMENT_SHADER) - } - - fn compile(&mut self, ctx: &WebGl2RenderingContext) -> Result<(), String> { - let program = self.program.as_ref().ok_or("could not find created program")?; - ctx.link_program(program); - let status = ctx.get_program_parameter(program, WebGl2RenderingContext::LINK_STATUS); - if status == wasm_bindgen::JsValue::TRUE { - Ok(()) - } else { - Err(format!("\n{}", ctx.get_program_info_log(program).unwrap_or_default())) - } - } - - pub fn init(&mut self, ctx: &WebGl2RenderingContext) -> Result<(), String> { - debug!("create program"); - self.create_program(ctx) - .map_err(|e| { error!("webgl2 create program: {}", e); e})?; - debug!("create vertex shader"); - self.create_vertex_shader(ctx) - .map_err(|e| { error!("webgl2 create vertex shader: {}", e); e})?; - debug!("create fragment shader"); - self.create_fragment_shader(ctx) - .map_err(|e| { error!("webgl2 create fragment shader: {}", e); e})?; - debug!("compile shader program"); - self.compile(ctx) - .map_err(|e| { error!("webgl2 shader: {}", e); e})?; - let program = self.program.as_ref().ok_or("could not find created program")?; - self.pos_loc = ctx.get_attrib_location(program, "pos"); - trace!("got attrib location 'pos'({})", self.pos_loc); - info!("initialised shader program"); - Ok(()) - } - - pub fn remove(&mut self, ctx: &WebGl2RenderingContext) { - ctx.delete_program(self.program.as_ref()) - } -} diff --git a/WebInterface/wasm/asm-paint/src/site.rs b/WebInterface/wasm/asm-paint/src/site.rs deleted file mode 100644 index 4ae0237..0000000 --- a/WebInterface/wasm/asm-paint/src/site.rs +++ /dev/null @@ -1,28 +0,0 @@ -use web_sys; -use crate::canvas::Canvas; - -pub struct Site { - window: web_sys::Window, - document: web_sys::Document, -} - -impl Site { - pub fn from_current() -> Option { - let window = web_sys::window() - .or_else(|| {error!("unable to query window"); None})?; - let document = window.document() - .or_else(|| {error!("unable to query document"); None})?; - Some(Self { - window, document - }) - } - - pub fn create_canvas(&self) -> Option { - debug!("gain canvas element"); - let element = self.document.get_element_by_id("canvas") - .or_else(|| {error!("could not gain canvas element"); None})?; - Canvas::new(element) - .or_else(|| {error!("could not create a webgl2 canvas. - Your browser doesn't seem to support webgl2"); None}) - } -} diff --git a/WebInterface/wasm/webhogg/Cargo.toml b/WebInterface/wasm/webhogg/Cargo.toml deleted file mode 100644 index 9d6e2ac..0000000 --- a/WebInterface/wasm/webhogg/Cargo.toml +++ /dev/null @@ -1,36 +0,0 @@ -[package] -name = "webhogg" -version = "0.1.0" -authors = [ - "natrixaeria", - "TrueDoctor" -] -edition = "2018" - -[lib] -crate-type = ["cdylib"] - -[dependencies] -js-sys = "0.3" -wasm-bindgen = "0.2" -log = "0.4" -fern = "0.5" - -[dependencies.web-sys] -version = "0.3.22" -features = [ - 'Document', - 'Event', - 'MessageEvent', - 'Element', - 'HtmlCanvasElement', - 'WorkerGlobalScope', - 'DedicatedWorkerGlobalScope', - 'OffscreenCanvas', - 'WebGl2RenderingContext', - 'WebGlShader', - 'WebGlProgram', - 'WebGlBuffer', - 'Window', - 'Worker' -] diff --git a/WebInterface/wasm/webhogg/deploy.py b/WebInterface/wasm/webhogg/deploy.py deleted file mode 100755 index 0655242..0000000 --- a/WebInterface/wasm/webhogg/deploy.py +++ /dev/null @@ -1,137 +0,0 @@ -#!/usr/bin/env python3 - -from threading import Thread -from socket import socket, SOL_SOCKET, SO_REUSEADDR - -def enable_csp(): - global ADD_HEADERS - ALL = ["'self'", "developer.mozilla.org"] - CSP = { - 'script-src': ["'unsafe-inline'", *ALL], - 'worker-src': [*ALL], - 'style-src': ["'unsafe-inline'", *ALL], - 'default-src': [*ALL], - } - - ADD_HEADERS = 'Content-Security-Policy: ' + '; '.join( - k + ' ' + ' '.join(v) for k, v in CSP.items()) - # ADD_HEADERS += '\r\n' + ADD_HEADERS.replace('cy: ', 'cy-Report-Only: ') - print(ADD_HEADERS) - ADD_HEADERS = '\r\n' + ADD_HEADERS - -ADD_HEADERS = '' - -class Client: - def __init__(self, sock, addr): - self.sock, self.addr = sock, addr - self.thread = None - - 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, ver - - def sen(self, loc, ver): - print(f'request {loc}') - closing = False - if loc.startswith('/'): - loc = loc[1:] - if not loc: - loc = 'index.html' - try: - if loc == 'favicon.ico': - raise FileNotFoundError - f = open(loc, 'rb') - c = f.read() - f.close() - print(f'successfully requested {loc}') - if loc.endswith('.js'): - mime = 'application/javascript' - elif loc.endswith('.html'): - mime = 'text/html' - elif loc.endswith('.wasm'): - mime = 'application/wasm' - else: - mime = 'text/plain' - packet = f'HTTP/1.1 200 Success\r\nContent-Length: {len(c)}\r\nContent-Type: {mime}{ADD_HEADERS}\r\n\r\n'.encode('utf-8') + c - pl = len(packet) - if pl != self.sock.send(packet): - self.sock.close() - closing = True - except FileNotFoundError: - print(f'error request {loc}') - self.sock.send(f'HTTP/1.1 404 Not Found\r\nContent-Length: 0\r\nContent-Type: text/plain\r\n\r\n'.encode('utf-8')) - finally: - try: - f.close() - except: - ... - if closing: - return True - - def run(self): - while True: - method, loc, attrs, ver = self.rec() - if self.sen(loc, ver): break - - def run_threaded(self): - self.thread = Thread(target=self.run) - self.thread.start() - - -def run_server(addr, port): - ws = socket() - ws.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) - ws.bind((addr, port)) - ws.listen() - - clients = [] - - while True: - c, a = ws.accept() - print(f'{a[0]}:{a[1]} connected') - client = Client(c, a) - clients.append(clients) - client.run_threaded() - print('lnuertdenuvtdevn') - - -if __name__ == '__main__': - from sys import argv - daemon = False - addr = 'localhost' - flag = None - for arg in argv[1:]: - if flag is not None: - if flag == 'addr': - addr = arg - elif flag == 'port': - port = int(arg) - flag = None - elif arg in ('-d', '--daemon'): - daemon = True - elif arg in ('-a', '--addr', '--address'): - flag = 'addr' - elif arg in ('-p', '--port'): - flag = 'port' - elif arg in ('--csp',): - enable_csp() - else: - print(f'warn: ignore invalid argument "{arg}"') - daemon = len(argv) > 1 and argv[1] in ('-d', '--daemon') - if ':' in addr: - addr, port = addr.split(':') - port = int(port) - if daemon: - import sys - from os import getcwd - from daemon import DaemonContext - with DaemonContext(working_directory=getcwd(), stderr=sys.stderr): - run_server(addr, port) - else: - run_server(addr, port) diff --git a/WebInterface/wasm/webhogg/game_logic.js b/WebInterface/wasm/webhogg/game_logic.js deleted file mode 100644 index fad5d82..0000000 --- a/WebInterface/wasm/webhogg/game_logic.js +++ /dev/null @@ -1,393 +0,0 @@ -const __exports = {}; -let wasm; - -const heap = new Array(32); - -heap.fill(undefined); - -heap.push(undefined, null, true, false); - -let heap_next = heap.length; - -function addHeapObject(obj) { - if (heap_next === heap.length) heap.push(heap.length + 1); - const idx = heap_next; - heap_next = heap[idx]; - - heap[idx] = obj; - return idx; -} -/** -* @param {any} worker -* @returns {void} -*/ -function game_logic_entry(worker) { - return wasm.game_logic_entry(addHeapObject(worker)); -} -__exports.game_logic_entry = game_logic_entry - -/** -* @param {any} worker -* @param {any} ecanvas -* @returns {void} -*/ -function graphics_entry(worker, ecanvas) { - return wasm.graphics_entry(addHeapObject(worker), addHeapObject(ecanvas)); -} -__exports.graphics_entry = graphics_entry - -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 - -function getObject(idx) { return heap[idx]; } - -function __widl_f_set_onmessage_DedicatedWorkerGlobalScope(arg0, arg1) { - getObject(arg0).onmessage = getObject(arg1); -} -__exports.__widl_f_set_onmessage_DedicatedWorkerGlobalScope = __widl_f_set_onmessage_DedicatedWorkerGlobalScope - -function __widl_f_data_MessageEvent(arg0) { - return addHeapObject(getObject(arg0).data); -} -__exports.__widl_f_data_MessageEvent = __widl_f_data_MessageEvent - -function isLikeNone(x) { - return x === undefined || x === null; -} - -let cachegetUint32Memory = null; -function getUint32Memory() { - if (cachegetUint32Memory === null || cachegetUint32Memory.buffer !== wasm.memory.buffer) { - cachegetUint32Memory = new Uint32Array(wasm.memory.buffer); - } - return cachegetUint32Memory; -} - -function handleError(exnptr, e) { - const view = getUint32Memory(); - view[exnptr / 4] = 1; - view[exnptr / 4 + 1] = addHeapObject(e); -} - -function __widl_f_get_context_OffscreenCanvas(arg0, arg1, arg2, exnptr) { - let varg1 = getStringFromWasm(arg1, arg2); - try { - - const val = getObject(arg0).getContext(varg1); - return isLikeNone(val) ? 0 : addHeapObject(val); - - } catch (e) { - handleError(exnptr, e); - } -} -__exports.__widl_f_get_context_OffscreenCanvas = __widl_f_get_context_OffscreenCanvas - -function __widl_instanceof_WebGL2RenderingContext(idx) { return getObject(idx) instanceof WebGL2RenderingContext ? 1 : 0; } -__exports.__widl_instanceof_WebGL2RenderingContext = __widl_instanceof_WebGL2RenderingContext - -function __widl_f_clear_WebGL2RenderingContext(arg0, arg1) { - getObject(arg0).clear(arg1 >>> 0); -} -__exports.__widl_f_clear_WebGL2RenderingContext = __widl_f_clear_WebGL2RenderingContext - -function __widl_f_clear_color_WebGL2RenderingContext(arg0, arg1, arg2, arg3, arg4) { - getObject(arg0).clearColor(arg1, arg2, arg3, arg4); -} -__exports.__widl_f_clear_color_WebGL2RenderingContext = __widl_f_clear_color_WebGL2RenderingContext - -function __widl_f_post_message_Worker(arg0, arg1, exnptr) { - try { - getObject(arg0).postMessage(getObject(arg1)); - } catch (e) { - handleError(exnptr, e); - } -} -__exports.__widl_f_post_message_Worker = __widl_f_post_message_Worker - -function __wbg_new0_b4c0f6100aa61878() { - return addHeapObject(new Date()); -} -__exports.__wbg_new0_b4c0f6100aa61878 = __wbg_new0_b4c0f6100aa61878 - -function __wbg_toISOString_580e1bcc780bf968(arg0) { - return addHeapObject(getObject(arg0).toISOString()); -} -__exports.__wbg_toISOString_580e1bcc780bf968 = __wbg_toISOString_580e1bcc780bf968 - -function __wbg_get_48d637c66043532c(arg0, arg1, exnptr) { - try { - return addHeapObject(Reflect.get(getObject(arg0), getObject(arg1))); - } catch (e) { - handleError(exnptr, e); - } -} -__exports.__wbg_get_48d637c66043532c = __wbg_get_48d637c66043532c - -function __wbindgen_string_new(p, l) { return addHeapObject(getStringFromWasm(p, l)); } -__exports.__wbindgen_string_new = __wbindgen_string_new - -let WASM_VECTOR_LEN = 0; - -let cachedTextEncoder = new TextEncoder('utf-8'); - -let passStringToWasm; -if (typeof cachedTextEncoder.encodeInto === 'function') { - passStringToWasm = function(arg) { - - - let size = arg.length; - let ptr = wasm.__wbindgen_malloc(size); - let offset = 0; - { - const mem = getUint8Memory(); - for (; offset < arg.length; offset++) { - const code = arg.charCodeAt(offset); - if (code > 0x7F) break; - mem[ptr + offset] = code; - } - } - - if (offset !== arg.length) { - arg = arg.slice(offset); - ptr = wasm.__wbindgen_realloc(ptr, size, size = offset + arg.length * 3); - const view = getUint8Memory().subarray(ptr + offset, ptr + size); - const ret = cachedTextEncoder.encodeInto(arg, view); - - offset += ret.written; - } - WASM_VECTOR_LEN = offset; - return ptr; - }; -} else { - passStringToWasm = function(arg) { - - - let size = arg.length; - let ptr = wasm.__wbindgen_malloc(size); - let offset = 0; - { - const mem = getUint8Memory(); - for (; offset < arg.length; offset++) { - const code = arg.charCodeAt(offset); - if (code > 0x7F) break; - mem[ptr + offset] = code; - } - } - - if (offset !== arg.length) { - const buf = cachedTextEncoder.encode(arg.slice(offset)); - ptr = wasm.__wbindgen_realloc(ptr, size, size = offset + buf.length); - getUint8Memory().set(buf, ptr + offset); - offset += buf.length; - } - WASM_VECTOR_LEN = offset; - return ptr; - }; -} - -function __wbindgen_string_get(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; -} -__exports.__wbindgen_string_get = __wbindgen_string_get - -function __wbindgen_debug_string(i, len_ptr) { - 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; -} -; -const toString = Object.prototype.toString; -const val = getObject(i); -const debug = debug_str(val); -const ptr = passStringToWasm(debug); -getUint32Memory()[len_ptr / 4] = WASM_VECTOR_LEN; -return ptr; -} -__exports.__wbindgen_debug_string = __wbindgen_debug_string - -function dropObject(idx) { - if (idx < 36) return; - heap[idx] = heap_next; - heap_next = idx; -} - -function takeObject(idx) { - const ret = getObject(idx); - dropObject(idx); - return ret; -} - -function __wbindgen_cb_drop(i) { - const obj = takeObject(i).original; - if (obj.cnt-- == 1) { - obj.a = 0; - return 1; - } - return 0; -} -__exports.__wbindgen_cb_drop = __wbindgen_cb_drop - -function __wbindgen_throw(ptr, len) { - throw new Error(getStringFromWasm(ptr, len)); -} -__exports.__wbindgen_throw = __wbindgen_throw - -function __wbindgen_closure_wrapper55(a, b, _ignored) { - const f = wasm.__wbg_function_table.get(23); - const d = wasm.__wbg_function_table.get(24); - const cb = function(arg0) { - this.cnt++; - let a = this.a; - this.a = 0; - try { - return f(a, b, addHeapObject(arg0)); - - } finally { - if (--this.cnt === 0) d(a, b); - else this.a = a; - - } - - }; - cb.a = a; - cb.cnt = 1; - let real = cb.bind(cb); - real.original = cb; - return addHeapObject(real); -} -__exports.__wbindgen_closure_wrapper55 = __wbindgen_closure_wrapper55 - -function __wbindgen_object_clone_ref(idx) { - return addHeapObject(getObject(idx)); -} -__exports.__wbindgen_object_clone_ref = __wbindgen_object_clone_ref - -function __wbindgen_object_drop_ref(i) { dropObject(i); } -__exports.__wbindgen_object_drop_ref = __wbindgen_object_drop_ref - -//!IMPORTANT_STUFF -const WASM_URL = './pkg/webhogg_bg.wasm'; - -const imports = { './webhogg': __exports }; - -onmessage = function (e) { - console.log('transport canvas'); - - let res = WebAssembly.instantiateStreaming(fetch(WASM_URL), imports); - - res.then(result => { - wasm = result.instance.exports; - game_logic_entry(graphics); - }); - let graphics = new Worker('./graphics.js', {type: 'module', credentials: 'include'}); - graphics.postMessage(e.data, [e.data.canvas]); -} diff --git a/WebInterface/wasm/webhogg/graphics.js b/WebInterface/wasm/webhogg/graphics.js deleted file mode 100644 index 11ddf89..0000000 --- a/WebInterface/wasm/webhogg/graphics.js +++ /dev/null @@ -1,401 +0,0 @@ -const __exports = {}; -let wasm; - -const heap = new Array(32); - -heap.fill(undefined); - -heap.push(undefined, null, true, false); - -let heap_next = heap.length; - -function addHeapObject(obj) { - if (heap_next === heap.length) heap.push(heap.length + 1); - const idx = heap_next; - heap_next = heap[idx]; - - heap[idx] = obj; - return idx; -} -/** -* @param {any} worker -* @returns {void} -*/ -function game_logic_entry(worker) { - return wasm.game_logic_entry(addHeapObject(worker)); -} -__exports.game_logic_entry = game_logic_entry - -/** -* @param {any} worker -* @param {any} ecanvas -* @returns {void} -*/ -function graphics_entry(worker, ecanvas) { - return wasm.graphics_entry(addHeapObject(worker), addHeapObject(ecanvas)); -} -__exports.graphics_entry = graphics_entry - -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 - -function getObject(idx) { return heap[idx]; } - -function __widl_f_set_onmessage_DedicatedWorkerGlobalScope(arg0, arg1) { - getObject(arg0).onmessage = getObject(arg1); -} -__exports.__widl_f_set_onmessage_DedicatedWorkerGlobalScope = __widl_f_set_onmessage_DedicatedWorkerGlobalScope - -function __widl_f_data_MessageEvent(arg0) { - return addHeapObject(getObject(arg0).data); -} -__exports.__widl_f_data_MessageEvent = __widl_f_data_MessageEvent - -function isLikeNone(x) { - return x === undefined || x === null; -} - -let cachegetUint32Memory = null; -function getUint32Memory() { - if (cachegetUint32Memory === null || cachegetUint32Memory.buffer !== wasm.memory.buffer) { - cachegetUint32Memory = new Uint32Array(wasm.memory.buffer); - } - return cachegetUint32Memory; -} - -function handleError(exnptr, e) { - const view = getUint32Memory(); - view[exnptr / 4] = 1; - view[exnptr / 4 + 1] = addHeapObject(e); -} - -function __widl_f_get_context_OffscreenCanvas(arg0, arg1, arg2, exnptr) { - let varg1 = getStringFromWasm(arg1, arg2); - try { - - const val = getObject(arg0).getContext(varg1); - return isLikeNone(val) ? 0 : addHeapObject(val); - - } catch (e) { - handleError(exnptr, e); - } -} -__exports.__widl_f_get_context_OffscreenCanvas = __widl_f_get_context_OffscreenCanvas - -function __widl_instanceof_WebGL2RenderingContext(idx) { return getObject(idx) instanceof WebGL2RenderingContext ? 1 : 0; } -__exports.__widl_instanceof_WebGL2RenderingContext = __widl_instanceof_WebGL2RenderingContext - -function __widl_f_clear_WebGL2RenderingContext(arg0, arg1) { - getObject(arg0).clear(arg1 >>> 0); -} -__exports.__widl_f_clear_WebGL2RenderingContext = __widl_f_clear_WebGL2RenderingContext - -function __widl_f_clear_color_WebGL2RenderingContext(arg0, arg1, arg2, arg3, arg4) { - getObject(arg0).clearColor(arg1, arg2, arg3, arg4); -} -__exports.__widl_f_clear_color_WebGL2RenderingContext = __widl_f_clear_color_WebGL2RenderingContext - -function __widl_f_post_message_Worker(arg0, arg1, exnptr) { - try { - getObject(arg0).postMessage(getObject(arg1)); - } catch (e) { - handleError(exnptr, e); - } -} -__exports.__widl_f_post_message_Worker = __widl_f_post_message_Worker - -function __wbg_new0_b4c0f6100aa61878() { - return addHeapObject(new Date()); -} -__exports.__wbg_new0_b4c0f6100aa61878 = __wbg_new0_b4c0f6100aa61878 - -function __wbg_toISOString_580e1bcc780bf968(arg0) { - return addHeapObject(getObject(arg0).toISOString()); -} -__exports.__wbg_toISOString_580e1bcc780bf968 = __wbg_toISOString_580e1bcc780bf968 - -function __wbg_get_48d637c66043532c(arg0, arg1, exnptr) { - try { - return addHeapObject(Reflect.get(getObject(arg0), getObject(arg1))); - } catch (e) { - handleError(exnptr, e); - } -} -__exports.__wbg_get_48d637c66043532c = __wbg_get_48d637c66043532c - -function __wbindgen_string_new(p, l) { return addHeapObject(getStringFromWasm(p, l)); } -__exports.__wbindgen_string_new = __wbindgen_string_new - -let WASM_VECTOR_LEN = 0; - -let cachedTextEncoder = new TextEncoder('utf-8'); - -let passStringToWasm; -if (typeof cachedTextEncoder.encodeInto === 'function') { - passStringToWasm = function(arg) { - - - let size = arg.length; - let ptr = wasm.__wbindgen_malloc(size); - let offset = 0; - { - const mem = getUint8Memory(); - for (; offset < arg.length; offset++) { - const code = arg.charCodeAt(offset); - if (code > 0x7F) break; - mem[ptr + offset] = code; - } - } - - if (offset !== arg.length) { - arg = arg.slice(offset); - ptr = wasm.__wbindgen_realloc(ptr, size, size = offset + arg.length * 3); - const view = getUint8Memory().subarray(ptr + offset, ptr + size); - const ret = cachedTextEncoder.encodeInto(arg, view); - - offset += ret.written; - } - WASM_VECTOR_LEN = offset; - return ptr; - }; -} else { - passStringToWasm = function(arg) { - - - let size = arg.length; - let ptr = wasm.__wbindgen_malloc(size); - let offset = 0; - { - const mem = getUint8Memory(); - for (; offset < arg.length; offset++) { - const code = arg.charCodeAt(offset); - if (code > 0x7F) break; - mem[ptr + offset] = code; - } - } - - if (offset !== arg.length) { - const buf = cachedTextEncoder.encode(arg.slice(offset)); - ptr = wasm.__wbindgen_realloc(ptr, size, size = offset + buf.length); - getUint8Memory().set(buf, ptr + offset); - offset += buf.length; - } - WASM_VECTOR_LEN = offset; - return ptr; - }; -} - -function __wbindgen_string_get(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; -} -__exports.__wbindgen_string_get = __wbindgen_string_get - -function __wbindgen_debug_string(i, len_ptr) { - 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; -} -; -const toString = Object.prototype.toString; -const val = getObject(i); -const debug = debug_str(val); -const ptr = passStringToWasm(debug); -getUint32Memory()[len_ptr / 4] = WASM_VECTOR_LEN; -return ptr; -} -__exports.__wbindgen_debug_string = __wbindgen_debug_string - -function dropObject(idx) { - if (idx < 36) return; - heap[idx] = heap_next; - heap_next = idx; -} - -function takeObject(idx) { - const ret = getObject(idx); - dropObject(idx); - return ret; -} - -function __wbindgen_cb_drop(i) { - const obj = takeObject(i).original; - if (obj.cnt-- == 1) { - obj.a = 0; - return 1; - } - return 0; -} -__exports.__wbindgen_cb_drop = __wbindgen_cb_drop - -function __wbindgen_throw(ptr, len) { - throw new Error(getStringFromWasm(ptr, len)); -} -__exports.__wbindgen_throw = __wbindgen_throw - -function __wbindgen_closure_wrapper55(a, b, _ignored) { - const f = wasm.__wbg_function_table.get(23); - const d = wasm.__wbg_function_table.get(24); - const cb = function(arg0) { - this.cnt++; - let a = this.a; - this.a = 0; - try { - return f(a, b, addHeapObject(arg0)); - - } finally { - if (--this.cnt === 0) d(a, b); - else this.a = a; - - } - - }; - cb.a = a; - cb.cnt = 1; - let real = cb.bind(cb); - real.original = cb; - return addHeapObject(real); -} -__exports.__wbindgen_closure_wrapper55 = __wbindgen_closure_wrapper55 - -function __wbindgen_object_clone_ref(idx) { - return addHeapObject(getObject(idx)); -} -__exports.__wbindgen_object_clone_ref = __wbindgen_object_clone_ref - -function __wbindgen_object_drop_ref(i) { dropObject(i); } -__exports.__wbindgen_object_drop_ref = __wbindgen_object_drop_ref - -//!IMPORTANT_STUFF -const WASM_URL = './pkg/webhogg_bg.wasm'; - -const imports = { './webhogg': __exports }; - -let res = WebAssembly.instantiateStreaming(fetch(WASM_URL), imports); - -let first = true; -let msg = null; -onmessage = function (e) { - if (first) { - first = false; - console.log('got context: ', e.data); - msg = e.data; - } -} -while (msg === null) { - console.log('yay'); - res.then(result => { - wasm = result.instance.exports; - console.log('context sndng: ', msg); - graphics_entry(self, msg); - }); - break; -} diff --git a/WebInterface/wasm/webhogg/index.html b/WebInterface/wasm/webhogg/index.html deleted file mode 100644 index ad951a6..0000000 --- a/WebInterface/wasm/webhogg/index.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - webhogg - - - - - - - diff --git a/WebInterface/wasm/webhogg/killpy b/WebInterface/wasm/webhogg/killpy deleted file mode 100755 index 5e2b9bc..0000000 --- a/WebInterface/wasm/webhogg/killpy +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -killall python3 diff --git a/WebInterface/wasm/webhogg/loader.js b/WebInterface/wasm/webhogg/loader.js deleted file mode 100644 index 51c4354..0000000 --- a/WebInterface/wasm/webhogg/loader.js +++ /dev/null @@ -1,9 +0,0 @@ -let canvas = document.getElementById('canvas'); - -let game_logic = new Worker( - './game_logic.js', - {type: 'module', credentials: 'include'} -); - -let ofc = canvas.transferControlToOffscreen(); -game_logic.postMessage({canvas: ofc}, [ofc]); diff --git a/WebInterface/wasm/webhogg/run b/WebInterface/wasm/webhogg/run deleted file mode 100755 index 484835a..0000000 --- a/WebInterface/wasm/webhogg/run +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh - -wasm-pack build --release --target web -python update.py -sh killpy -python3 deploy.py -d -a 0.0.0.0:8080 diff --git a/WebInterface/wasm/webhogg/src/canvas.rs b/WebInterface/wasm/webhogg/src/canvas.rs deleted file mode 100644 index bc694ed..0000000 --- a/WebInterface/wasm/webhogg/src/canvas.rs +++ /dev/null @@ -1,36 +0,0 @@ -use web_sys::WebGl2RenderingContext as WebGl2; -use wasm_bindgen::JsCast; -use crate::webhogg_exception::WebhoggException; -use web_sys::OffscreenCanvas as ECanvas; - -pub struct Canvas { - ctx: WebGl2, -} - -impl Canvas { - pub fn from_existing(canvas: &ECanvas) -> Result { - info!("messages lol"); - let ctx = canvas.get_context("webgl2") - .map_err(|x| WebhoggException::WebGlContextError( - format!("obtained invalid webgl2 context js value: {:?}", x)))? - .ok_or(WebhoggException::WebGlContextError( - "could not obtaine webgl2 context".to_string()))? - .dyn_into::() - .map_err(|_| WebhoggException::WebGlContextError( - "obtained invalid webgl2 context js object".to_string()))?; - info!("successfully obtained webgl2 context"); - ctx.clear_color(0.6, 0.0, 0.6, 1.0); - ctx.clear(WebGl2::COLOR_BUFFER_BIT); - 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 deleted file mode 100644 index f537631..0000000 --- a/WebInterface/wasm/webhogg/src/client_logger.rs +++ /dev/null @@ -1,47 +0,0 @@ -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(), - String::from(js_sys::Date::new_0().to_iso_string()), - 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 deleted file mode 100644 index 6d9fca9..0000000 --- a/WebInterface/wasm/webhogg/src/lib.rs +++ /dev/null @@ -1,44 +0,0 @@ -mod client_logger; -mod webhogg_exception; -mod canvas; - -use wasm_bindgen::prelude::*; -use web_sys::Worker; -use web_sys::OffscreenCanvas as ECanvas; - -#[macro_use] -extern crate log; - -#[wasm_bindgen] -pub fn game_logic_entry(worker: web_sys::Worker) { - client_logger::init_logger(); - - info!("hello from game logic wasm"); - worker.post_message(&wasm_bindgen::JsValue::from_str("premsg frm wasm_gLe")) - .unwrap(); - info!("game logic terminated"); -} - -#[wasm_bindgen] -pub fn graphics_entry(worker: web_sys::DedicatedWorkerGlobalScope, - ecanvas: JsValue) { - client_logger::init_logger(); - - let ecanvas: ECanvas = js_sys::Reflect::get(&ecanvas, - &wasm_bindgen::JsValue::from_str("canvas")) - .map_err(|e| error!("could not load canvas")) - .unwrap().into(); - - info!("hello from graphics wasm {:?}", ecanvas); - let handler = wasm_bindgen::closure::Closure::once_into_js( - (|e: web_sys::MessageEvent| { - info!("things are getting wired: {:?}", e.data()); - })); - worker.set_onmessage(Some(&js_sys::Function::from(handler))); - - let canvas = canvas::Canvas::from_existing(&ecanvas) - .map_err(|e| error!("{}", e)) - .unwrap(); - - info!("graphics terminated"); -} diff --git a/WebInterface/wasm/webhogg/src/webhogg_exception.rs b/WebInterface/wasm/webhogg/src/webhogg_exception.rs deleted file mode 100644 index 46eedd6..0000000 --- a/WebInterface/wasm/webhogg/src/webhogg_exception.rs +++ /dev/null @@ -1,39 +0,0 @@ -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 deleted file mode 100644 index 6f83518..0000000 --- a/WebInterface/wasm/webhogg/target/.rustc_info.json +++ /dev/null @@ -1 +0,0 @@ -{"rustc_fingerprint":5653700290818914945,"outputs":{"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",""],"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"],"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",""]},"successes":{}} \ No newline at end of file diff --git a/WebInterface/wasm/webhogg/update.py b/WebInterface/wasm/webhogg/update.py deleted file mode 100644 index aad9395..0000000 --- a/WebInterface/wasm/webhogg/update.py +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env python - -ISC = '//!IMPORTANT_STUFF' - -def rf(fn): - f = open(fn) - c = f.read() - f.close() - return c - -nc = rf('pkg/webhogg.js') -m1 = rf('game_logic.js') -m2 = rf('graphics.js') - -nc = nc.split('function init(module) {')[0].strip('\n') -nc = nc.replace('export function ', 'function ') -m1 = m1.split('//!IMPORTANT_STUFF')[-1] -m2 = m2.split('//!IMPORTANT_STUFF')[-1] - -nc += '\n' * 2 + ISC - -m1 = nc + m1 -m2 = nc + m2 - -with open('game_logic.js', 'w') as f: - f.write(m1) - -with open('graphics.js', 'w') as f: - f.write(m2) diff --git a/WebInterface/wasm/webhogg/webhogg.js b/WebInterface/wasm/webhogg/webhogg.js deleted file mode 100644 index c01d70f..0000000 --- a/WebInterface/wasm/webhogg/webhogg.js +++ /dev/null @@ -1,112 +0,0 @@ -const __exports = {}; - -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 - -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() { - return wasm.graphics_entry(); -} -__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, worker) { - return result.then(({instance, module}) => { - wasm = instance.exports; - wasm.game_logic_entry(worker); - //init_r.__wbindgen_wasm_module = module; - //wasm.__wbindgen_start(); - return wasm; - }); -} - -export default init_r; -export var init_x = _init_x; diff --git a/webhogg/wasm/Cargo.toml b/webhogg/wasm/Cargo.toml new file mode 100644 index 0000000..79a96f3 --- /dev/null +++ b/webhogg/wasm/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "wasm" +version = "0.1.0" +authors = [ + "natrixaeria", + "TrueDoctor " +] +edition = "2018" +description = "WebAssembly frontend for the webhogg project" + +[dependencies] diff --git a/webhogg/wasm/src/main.rs b/webhogg/wasm/src/main.rs new file mode 100644 index 0000000..e7a11a9 --- /dev/null +++ b/webhogg/wasm/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} -- cgit v1.2.3-54-g00ecf From d8b483d39d1051a94e4f5a955dc19a93629ec894 Mon Sep 17 00:00:00 2001 From: natrixaeria Date: Tue, 11 Jun 2019 20:42:09 +0200 Subject: Create a build script --- webhogg/wasm/Cargo.toml | 2 +- webhogg/wasm/build | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100755 webhogg/wasm/build diff --git a/webhogg/wasm/Cargo.toml b/webhogg/wasm/Cargo.toml index 79a96f3..b01d7e3 100644 --- a/webhogg/wasm/Cargo.toml +++ b/webhogg/wasm/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "wasm" +name = "webhogg-wasm" version = "0.1.0" authors = [ "natrixaeria", diff --git a/webhogg/wasm/build b/webhogg/wasm/build new file mode 100755 index 0000000..a0c4df1 --- /dev/null +++ b/webhogg/wasm/build @@ -0,0 +1,5 @@ +#!/bin/bash + +cargo build --target wasm32-unknown-unknown --release +wasm-bindgen target/wasm32-unknown-unknown/release/webhogg-wasm.wasm --out-dir bin/ --no-typescript --target no-modules --remove-producers-section --remove-name-section +wasm-opt -Oz bin/*.wasm -o bin/*.wasm -- cgit v1.2.3-54-g00ecf From 0876527eafcd7c372873314cc9c7e93cba2991e2 Mon Sep 17 00:00:00 2001 From: natrixaeria Date: Tue, 11 Jun 2019 21:05:15 +0200 Subject: Create a web page --- webhogg/wasm/index.html | 11 +++++++++++ webhogg/wasm/pkg/main.js | 1 + 2 files changed, 12 insertions(+) create mode 100644 webhogg/wasm/index.html create mode 100644 webhogg/wasm/pkg/main.js diff --git a/webhogg/wasm/index.html b/webhogg/wasm/index.html new file mode 100644 index 0000000..eae1cc2 --- /dev/null +++ b/webhogg/wasm/index.html @@ -0,0 +1,11 @@ + + + + + webhogg + + + your browser is incompetent + + + diff --git a/webhogg/wasm/pkg/main.js b/webhogg/wasm/pkg/main.js new file mode 100644 index 0000000..f80fabb --- /dev/null +++ b/webhogg/wasm/pkg/main.js @@ -0,0 +1 @@ +let data = fetch('bin/webhogg-wasm_bg.wasm'); -- cgit v1.2.3-54-g00ecf From 286be2a2fe89927c1a7bb6855b3d001a70dd312d Mon Sep 17 00:00:00 2001 From: natrixaeria Date: Tue, 11 Jun 2019 23:40:24 +0200 Subject: Add workers --- webhogg/wasm/Cargo.toml | 7 +++++++ webhogg/wasm/build | 6 ++++-- webhogg/wasm/pkg/main.js | 10 +++++++++- webhogg/wasm/pkg/worker-graphics.js | 1 + webhogg/wasm/src/lib.rs | 8 ++++++++ webhogg/wasm/src/main.rs | 3 --- 6 files changed, 29 insertions(+), 6 deletions(-) create mode 100644 webhogg/wasm/pkg/worker-graphics.js create mode 100644 webhogg/wasm/src/lib.rs delete mode 100644 webhogg/wasm/src/main.rs diff --git a/webhogg/wasm/Cargo.toml b/webhogg/wasm/Cargo.toml index b01d7e3..7978928 100644 --- a/webhogg/wasm/Cargo.toml +++ b/webhogg/wasm/Cargo.toml @@ -8,4 +8,11 @@ authors = [ edition = "2018" description = "WebAssembly frontend for the webhogg project" +[lib] +crate-type = ["cdylib"] + +[profile.release] +lto = true + [dependencies] +wasm-bindgen = "0.2" diff --git a/webhogg/wasm/build b/webhogg/wasm/build index a0c4df1..e14f004 100755 --- a/webhogg/wasm/build +++ b/webhogg/wasm/build @@ -1,5 +1,7 @@ #!/bin/bash cargo build --target wasm32-unknown-unknown --release -wasm-bindgen target/wasm32-unknown-unknown/release/webhogg-wasm.wasm --out-dir bin/ --no-typescript --target no-modules --remove-producers-section --remove-name-section -wasm-opt -Oz bin/*.wasm -o bin/*.wasm +wasm-bindgen target/wasm32-unknown-unknown/release/webhogg_wasm.wasm --out-dir bin/ --no-typescript --target no-modules --remove-producers-section --remove-name-section +wasm-opt -Oz bin/webhogg_wasm_bg.wasm -o bin/webhogg-wasm.wasm +rm bin/webhogg_wasm_bg.wasm +mv bin/webhogg_wasm.js bin/webhogg-wasm.js diff --git a/webhogg/wasm/pkg/main.js b/webhogg/wasm/pkg/main.js index f80fabb..eec740d 100644 --- a/webhogg/wasm/pkg/main.js +++ b/webhogg/wasm/pkg/main.js @@ -1 +1,9 @@ -let data = fetch('bin/webhogg-wasm_bg.wasm'); +async function main() { + let fetchingSource = fetch('bin/webhogg-wasm.wasm'); + let fetchedSource = await fetchingSource; + let source = await fetchedSource.text(); + //alert(source) + let workerGraphics = new Worker('pkg/worker-graphics.js'); +} + +main(); diff --git a/webhogg/wasm/pkg/worker-graphics.js b/webhogg/wasm/pkg/worker-graphics.js new file mode 100644 index 0000000..8360014 --- /dev/null +++ b/webhogg/wasm/pkg/worker-graphics.js @@ -0,0 +1 @@ +console.log('lelel'); diff --git a/webhogg/wasm/src/lib.rs b/webhogg/wasm/src/lib.rs new file mode 100644 index 0000000..cb334fb --- /dev/null +++ b/webhogg/wasm/src/lib.rs @@ -0,0 +1,8 @@ +use wasm_bindgen::prelude::*; + +#[wasm_bindgen] +pub fn enrty() { +} + +fn main() { +} diff --git a/webhogg/wasm/src/main.rs b/webhogg/wasm/src/main.rs deleted file mode 100644 index e7a11a9..0000000 --- a/webhogg/wasm/src/main.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn main() { - println!("Hello, world!"); -} -- cgit v1.2.3-54-g00ecf