diff options
| author | LLLL Colonq <llll@colonq> | 2024-12-28 22:14:15 -0500 |
|---|---|---|
| committer | LLLL Colonq <llll@colonq> | 2024-12-28 22:14:15 -0500 |
| commit | 2f30c4d25f3e01fb4fc8089134a610195f1cdb13 (patch) | |
| tree | 673ecf44eab08f94343e471c8608336d7c3f60d5 | |
| parent | 18534b14ec9fc83a12affe8ac3350f1f414d004e (diff) | |
Networking
| -rw-r--r-- | .dir-locals.el | 4 | ||||
| -rw-r--r-- | .envrc | 2 | ||||
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | Cargo.toml | 2 | ||||
| -rw-r--r-- | flake.lock | 120 | ||||
| -rw-r--r-- | flake.nix | 139 | ||||
| -rw-r--r-- | nix/flake.lock | 27 | ||||
| -rw-r--r-- | nix/flake.nix | 37 | ||||
| -rw-r--r-- | src/lib.rs | 1 | ||||
| -rw-r--r-- | src/net.rs | 1 | ||||
| -rw-r--r-- | src/net/client.rs | 67 |
11 files changed, 333 insertions, 68 deletions
diff --git a/.dir-locals.el b/.dir-locals.el index 23a499f..e3e9c3b 100644 --- a/.dir-locals.el +++ b/.dir-locals.el @@ -1,2 +1,2 @@ -;; ((rust-mode . ((eglot-workspace-configuration . (:rust-analyzer (:cargo (:target "wasm32-unknown-unknown"))))))) -((rust-mode . ((eglot-workspace-configuration . (:rust-analyzer (:cargo (:target "x86_64-unknown-linux-gnu"))))))) +((rust-mode . ((eglot-workspace-configuration . (:rust-analyzer (:cargo (:target "wasm32-unknown-unknown"))))))) +;; ((rust-mode . ((eglot-workspace-configuration . (:rust-analyzer (:cargo (:target "x86_64-unknown-linux-gnu"))))))) @@ -1 +1 @@ -use_flake path:nix +use_flake @@ -1,3 +1,4 @@ +/.direnv /target /.cargo /dist
\ No newline at end of file @@ -37,7 +37,7 @@ tracing-wasm = "*" # trace performance in browser wasm-bindgen = "*" # interface with javascript wasm-bindgen-futures = "*" # interface with async javascript js-sys = "*" # browser APIs to interact with JS runtime (e.g. run WASM) -web-sys = { version = "*", features = ["Document", "Window", "Element", "HtmlCanvasElement", "WebGl2RenderingContext", "Headers", "Request", "RequestInit", "RequestMode", "Response", "Performance", "PerformanceTiming", "AudioContext", "AudioNode", "AudioDestinationNode", "AudioBuffer", "AudioBufferSourceNode"] } +web-sys = { version = "*", features = ["Document", "Window", "Element", "HtmlCanvasElement", "WebGl2RenderingContext", "Headers", "Request", "RequestInit", "RequestMode", "Response", "Performance", "PerformanceTiming", "AudioContext", "AudioNode", "AudioDestinationNode", "AudioBuffer", "AudioBufferSourceNode", "BinaryType", "Blob", "CloseEvent", "ErrorEvent", "FileReader", "MessageEvent", "ProgressEvent", "WebSocket"] } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] env_logger = "*" diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..978376b --- /dev/null +++ b/flake.lock @@ -0,0 +1,120 @@ +{ + "nodes": { + "crane": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1719249093, + "narHash": "sha256-0q1haa3sw6GbmJ+WhogMnducZGjEaCa/iR6hF2vq80I=", + "owner": "ipetkov", + "repo": "crane", + "rev": "9791c77eb7e98b8d8ac5b0305d47282f994411ca", + "type": "github" + }, + "original": { + "owner": "ipetkov", + "repo": "crane", + "type": "github" + } + }, + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1710146030, + "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1719285171, + "narHash": "sha256-kOUKtKfYEh8h8goL/P6lKF4Jb0sXnEkFyEganzdTGvo=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "cfb89a95f19bea461fc37228dc4d07b22fe617c2", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-for-wasm-bindgen": { + "locked": { + "lastModified": 1691495139, + "narHash": "sha256-+zZIRTtXlA8gN8HPzczphPnB9L+yYpidBmFxKqWQy+A=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "4e6868b1aa3766ab1de169922bb3826143941973", + "type": "github" + }, + "original": { + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "4e6868b1aa3766ab1de169922bb3826143941973", + "type": "github" + } + }, + "root": { + "inputs": { + "crane": "crane", + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs", + "nixpkgs-for-wasm-bindgen": "nixpkgs-for-wasm-bindgen", + "rust-overlay": "rust-overlay" + } + }, + "rust-overlay": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1719281921, + "narHash": "sha256-LIBMfhM9pMOlEvBI757GOK5l0R58SRi6YpwfYMbf4yc=", + "owner": "oxalica", + "repo": "rust-overlay", + "rev": "b6032d3a404d8a52ecfc8571ff0c26dfbe221d07", + "type": "github" + }, + "original": { + "owner": "oxalica", + "repo": "rust-overlay", + "type": "github" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..1546244 --- /dev/null +++ b/flake.nix @@ -0,0 +1,139 @@ +{ + description = "Build a cargo project"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; + + # The version of wasm-bindgen-cli needs to match the version in Cargo.lock + # Update this to include the version you need + nixpkgs-for-wasm-bindgen.url = "github:NixOS/nixpkgs/4e6868b1aa3766ab1de169922bb3826143941973"; + + crane = { + url = "github:ipetkov/crane"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + + flake-utils.url = "github:numtide/flake-utils"; + + rust-overlay = { + url = "github:oxalica/rust-overlay"; + inputs = { + nixpkgs.follows = "nixpkgs"; + flake-utils.follows = "flake-utils"; + }; + }; + }; + + outputs = { self, nixpkgs, crane, flake-utils, rust-overlay, nixpkgs-for-wasm-bindgen, ... }: + flake-utils.lib.eachDefaultSystem (system: + let + pkgs = import nixpkgs { + inherit system; + overlays = [ (import rust-overlay) ]; + }; + + inherit (pkgs) lib; + + rustToolchain = pkgs.rust-bin.stable.latest.default.override { + # Set the build targets supported by the toolchain, + # wasm32-unknown-unknown is required for trunk + targets = [ "wasm32-unknown-unknown" ]; + }; + craneLib = ((crane.mkLib pkgs).overrideToolchain rustToolchain).overrideScope (_final: _prev: { + # The version of wasm-bindgen-cli needs to match the version in Cargo.lock. You + # can unpin this if your nixpkgs commit contains the appropriate wasm-bindgen-cli version + inherit (import nixpkgs-for-wasm-bindgen { inherit system; }) wasm-bindgen-cli; + }); + + # When filtering sources, we want to allow assets other than .rs files + src = lib.cleanSourceWith { + src = ./.; # The original, unfiltered source + filter = path: type: + (lib.hasSuffix "\.html" path) || + (lib.hasSuffix "\.scss" path) || + # Example of a folder for images, icons, etc + (lib.hasInfix "/assets/" path) || + # Default filter from crane (allow .rs files) + (craneLib.filterCargoSources path type) + ; + }; + + # Common arguments can be set here to avoid repeating them later + commonArgs = { + inherit src; + strictDeps = true; + # We must force the target, otherwise cargo will attempt to use your native target + CARGO_BUILD_TARGET = "wasm32-unknown-unknown"; + + buildInputs = [ + # Add additional build inputs here + ] ++ lib.optionals pkgs.stdenv.isDarwin [ + # Additional darwin specific inputs can be set here + pkgs.libiconv + ]; + }; + + # Build *just* the cargo dependencies, so we can reuse + # all of that work (e.g. via cachix) when running in CI + cargoArtifacts = craneLib.buildDepsOnly (commonArgs // { + # You cannot run cargo test on a wasm build + doCheck = false; + }); + + # Build the actual crate itself, reusing the dependency + # artifacts from above. + # This derivation is a directory you can put on a webserver. + teleia = craneLib.buildTrunkPackage (commonArgs // { + inherit cargoArtifacts; + # The version of wasm-bindgen-cli here must match the one from Cargo.lock. + wasm-bindgen-cli = pkgs.wasm-bindgen-cli.override { + version = "0.2.90"; + hash = "sha256-X8+DVX7dmKh7BgXqP7Fp0smhup5OO8eWEhn26ODYbkQ="; + cargoHash = "sha256-ckJxAR20GuVGstzXzIj1M0WBFj5eJjrO2/DRMUK5dwM="; + }; + }); + in + { + checks = { + # Build the crate as part of `nix flake check` for convenience + inherit teleia; + + # Run clippy (and deny all warnings) on the crate source, + # again, reusing the dependency artifacts from above. + # + # Note that this is done as a separate derivation so that + # we can block the CI if there are issues here, but not + # prevent downstream consumers from building our crate by itself. + teleia-clippy = craneLib.cargoClippy (commonArgs // { + inherit cargoArtifacts; + cargoClippyExtraArgs = "--all-targets -- --deny warnings"; + }); + + # Check formatting + teleia-fmt = craneLib.cargoFmt { + inherit src; + }; + }; + + packages.default = teleia; + + devShells.default = craneLib.devShell { + # Inherit inputs from checks. + checks = self.checks.${system}; + + # Additional dev-shell environment variables can be set directly + # MY_CUSTOM_DEVELOPMENT_VAR = "something else"; + + # Extra inputs can be added here; cargo and rustc are provided by default. + packages = [ + pkgs.trunk + pkgs.rust-analyzer + pkgs.pkg-config + pkgs.openssl.dev + pkgs.SDL2 + pkgs.glxinfo + pkgs.alsa-lib + ]; + }; + }); +} diff --git a/nix/flake.lock b/nix/flake.lock deleted file mode 100644 index 780a8b9..0000000 --- a/nix/flake.lock +++ /dev/null @@ -1,27 +0,0 @@ -{ - "nodes": { - "nixpkgs": { - "locked": { - "lastModified": 1729788628, - "narHash": "sha256-3suayUinicnvE/4shMZwp9FHT5izUM8gMpdEO/NHBTo=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "63487b2f26fa065cfeeaa47dddb08e2856ba53e8", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixpkgs-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "root": { - "inputs": { - "nixpkgs": "nixpkgs" - } - } - }, - "root": "root", - "version": 7 -} diff --git a/nix/flake.nix b/nix/flake.nix deleted file mode 100644 index ed649a8..0000000 --- a/nix/flake.nix +++ /dev/null @@ -1,37 +0,0 @@ -{ - inputs = { - nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; - }; - - outputs = { self, nixpkgs, ... }@inputs: - let - system = "x86_64-linux"; - pkgs = nixpkgs.legacyPackages.${system}; - in { - devShells.x86_64-linux.default = pkgs.mkShell { - buildInputs = [ - pkgs.pkg-config - pkgs.llvm - pkgs.clang - pkgs.llvmPackages.libclang - pkgs.openssl - pkgs.pkg-config - pkgs.SDL2 - pkgs.glxinfo - pkgs.alsa-lib - ]; - # LD_LIBRARY_PATH = "$LD_LIBRARY_PATH:${ - # with pkgs; - # pkgs.lib.makeLibraryPath [ - # libGL - # xorg.libX11 - # xorg.libXcursor - # xorg.libXi - # libxkbcommon - # xorg.libxcb - # libglvnd - # ] - # }"; - }; - }; -} @@ -9,6 +9,7 @@ pub mod texture; pub mod font; pub mod shadow; pub mod audio; +pub mod net; #[cfg(target_arch = "wasm32")] use winit::platform::web::EventLoopExtWebSys; diff --git a/src/net.rs b/src/net.rs new file mode 100644 index 0000000..b9babe5 --- /dev/null +++ b/src/net.rs @@ -0,0 +1 @@ +pub mod client; diff --git a/src/net/client.rs b/src/net/client.rs new file mode 100644 index 0000000..d9936e5 --- /dev/null +++ b/src/net/client.rs @@ -0,0 +1,67 @@ +use std::{collections::VecDeque, sync::{Arc, Mutex}}; + +use wasm_bindgen::prelude::*; + +#[derive(Debug)] +pub enum Message { + Binary(Vec<u8>), + Text(String), +} + +impl Message { + pub fn from_messageevent(e: web_sys::MessageEvent) -> Self { + if let Ok(abuf) = e.data().dyn_into::<js_sys::ArrayBuffer>() { + let array = js_sys::Uint8Array::new(&abuf).to_vec(); + Message::Binary(array) + } else if let Ok(txt) = e.data().dyn_into::<js_sys::JsString>() { + Message::Text(txt.into()) + } else { + panic!("received weird websocked message: {:?}", e); + } + } +} + +pub struct Client { + pub ws: Option<web_sys::WebSocket>, + pub messages: Arc<Mutex<VecDeque<Message>>>, +} + +impl Client { + pub fn new() -> Self { + Self { + ws: None, + messages: Arc::new(Mutex::new(VecDeque::new())), + } + } + pub fn connect(&mut self, url: &str) { + let ws = web_sys::WebSocket::new(url).expect("failed to open websocket"); + let messages_ref = self.messages.clone(); + let cb: Closure<dyn Fn(web_sys::MessageEvent)> = Closure::new(move |e: web_sys::MessageEvent| { + let msg = Message::from_messageevent(e); + log::info!("incoming: {:?}", msg); + messages_ref.lock().unwrap().push_back(msg); + }); + ws.set_onmessage(Some(cb.as_ref().unchecked_ref())); + cb.forget(); + self.ws = Some(ws); + } + pub fn poll(&mut self) -> Option<Message> { + self.messages.lock().unwrap().pop_front() + } + pub fn send(&self, msg: Message) { + if let Some(ws) = &self.ws { + match msg { + Message::Text(txt) => { + if let Err(e) = ws.send_with_str(&txt) { + log::warn!("failed to send string: {:?}", e); + } + }, + Message::Binary(bytes) => { + if let Err(e) = ws.send_with_u8_array(&bytes) { + log::warn!("failed to send bytes: {:?}", e); + } + }, + } + } + } +} |
