summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLLLL Colonq <llll@colonq>2024-12-28 22:14:15 -0500
committerLLLL Colonq <llll@colonq>2024-12-28 22:14:15 -0500
commit2f30c4d25f3e01fb4fc8089134a610195f1cdb13 (patch)
tree673ecf44eab08f94343e471c8608336d7c3f60d5
parent18534b14ec9fc83a12affe8ac3350f1f414d004e (diff)
Networking
-rw-r--r--.dir-locals.el4
-rw-r--r--.envrc2
-rw-r--r--.gitignore1
-rw-r--r--Cargo.toml2
-rw-r--r--flake.lock120
-rw-r--r--flake.nix139
-rw-r--r--nix/flake.lock27
-rw-r--r--nix/flake.nix37
-rw-r--r--src/lib.rs1
-rw-r--r--src/net.rs1
-rw-r--r--src/net/client.rs67
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")))))))
diff --git a/.envrc b/.envrc
index 7efd1f8..c4b17d7 100644
--- a/.envrc
+++ b/.envrc
@@ -1 +1 @@
-use_flake path:nix
+use_flake
diff --git a/.gitignore b/.gitignore
index 0c257a3..caf058f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
+/.direnv
/target
/.cargo
/dist \ No newline at end of file
diff --git a/Cargo.toml b/Cargo.toml
index 1f5db5a..94f4dd5 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -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
- # ]
- # }";
- };
- };
-}
diff --git a/src/lib.rs b/src/lib.rs
index d0fdfc0..b8ebde2 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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);
+ }
+ },
+ }
+ }
+ }
+}