From d5a5b454a4670a72826882c6ce4c87d1f597767c Mon Sep 17 00:00:00 2001 From: LLLL Colonq Date: Sat, 7 Dec 2024 17:25:37 -0500 Subject: Native --- Cargo.lock | 287 ++++++++++++++++++++++++++++++++++++++++++++++++++++----- Cargo.toml | 42 +++------ nix/flake.lock | 27 ++++++ nix/flake.nix | 32 +++++++ src/audio.rs | 66 +++++++++++++ src/context.rs | 36 ++++---- src/lib.rs | 284 ++++++++++++++++++++++++++++++++++++++------------------ src/module.rs | 45 --------- src/request.rs | 20 ---- src/state.rs | 28 +++++- 10 files changed, 638 insertions(+), 229 deletions(-) create mode 100644 nix/flake.lock create mode 100644 nix/flake.nix delete mode 100644 src/module.rs delete mode 100644 src/request.rs diff --git a/Cargo.lock b/Cargo.lock index 4fff158..a7ec47c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -46,6 +46,15 @@ dependencies = [ "zerocopy", ] +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + [[package]] name = "android-activity" version = "0.5.2" @@ -53,7 +62,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee91c0c2905bae44f84bfa4e044536541df26b7703fd0888deeb9060fcc44289" dependencies = [ "android-properties", - "bitflags 2.4.2", + "bitflags 2.6.0", "cc", "cesu8", "jni", @@ -73,6 +82,55 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc7eb209b1518d6bb87b283c20095f5228ecda460da70b44f0802523dea6da04" +[[package]] +name = "anstream" +version = "0.6.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23a1e53f0f5d86382dafe1cf314783b2044280f406e7e1506368220ad11b1338" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8365de52b16c035ff4fcafe0092ba9390540e3e352870ac09933bebcaa2c8c56" + +[[package]] +name = "anstyle-parse" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125" +dependencies = [ + "anstyle", + "windows-sys 0.59.0", +] + [[package]] name = "arrayref" version = "0.3.7" @@ -144,9 +202,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "block-sys" @@ -197,7 +255,7 @@ version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fba7adb4dd5aa98e5553510223000e7148f621165ec5f9acd7113f6ca4995298" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.6.0", "log", "polling", "rustix", @@ -246,12 +304,27 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" +[[package]] +name = "cgl" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ced0551234e87afee12411d535648dd89d2e7f34c78b753395567aff3d447ff" +dependencies = [ + "libc", +] + [[package]] name = "color_quant" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" +[[package]] +name = "colorchoice" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" + [[package]] name = "combine" version = "4.6.6" @@ -433,6 +506,29 @@ dependencies = [ "syn", ] +[[package]] +name = "env_filter" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f2c92ceda6ceec50f43169f9ee8424fe2db276791afde7b2cd8bc084cb376ab" +dependencies = [ + "log", + "regex", +] + +[[package]] +name = "env_logger" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13fa619b91fb2381732789fc5de83b45675e882f66623b7d8cb4f643017018d" +dependencies = [ + "anstream", + "anstyle", + "env_filter", + "humantime", + "log", +] + [[package]] name = "equivalent" version = "1.0.1" @@ -634,6 +730,17 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" +[[package]] +name = "gl_generator" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a95dfc23a2b4a9a2f5ab41d194f8bfda3cabec42af4e39f08c339eb2a0c124d" +dependencies = [ + "khronos_api", + "log", + "xml-rs", +] + [[package]] name = "glam" version = "0.25.0" @@ -652,6 +759,71 @@ dependencies = [ "web-sys", ] +[[package]] +name = "glutin" +version = "0.31.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18fcd4ae4e86d991ad1300b8f57166e5be0c95ef1f63f3f5b827f8a164548746" +dependencies = [ + "bitflags 2.6.0", + "cfg_aliases", + "cgl", + "core-foundation", + "dispatch", + "glutin_egl_sys", + "glutin_glx_sys", + "glutin_wgl_sys", + "icrate", + "libloading", + "objc2", + "once_cell", + "raw-window-handle 0.5.2", + "wayland-sys", + "windows-sys 0.48.0", + "x11-dl", +] + +[[package]] +name = "glutin-winit" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ebcdfba24f73b8412c5181e56f092b5eff16671c514ce896b258a0a64bd7735" +dependencies = [ + "cfg_aliases", + "glutin", + "raw-window-handle 0.5.2", + "winit", +] + +[[package]] +name = "glutin_egl_sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77cc5623f5309ef433c3dd4ca1223195347fe62c413da8e2fdd0eb76db2d9bcd" +dependencies = [ + "gl_generator", + "windows-sys 0.48.0", +] + +[[package]] +name = "glutin_glx_sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a165fd686c10dcc2d45380b35796e577eacfd43d4660ee741ec8ebe2201b3b4f" +dependencies = [ + "gl_generator", + "x11-dl", +] + +[[package]] +name = "glutin_wgl_sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8098adac955faa2d31079b65dc48841251f69efd3ac25477903fc424362ead" +dependencies = [ + "gl_generator", +] + [[package]] name = "h2" version = "0.4.6" @@ -733,6 +905,12 @@ version = "1.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946" +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + [[package]] name = "hyper" version = "1.4.1" @@ -860,6 +1038,12 @@ version = "2.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ddc24109865250148c2e0f3d25d4f0f479571723792d3802153c60922a4fb708" +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + [[package]] name = "itoa" version = "1.0.11" @@ -915,6 +1099,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "khronos_api" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" + [[package]] name = "lazy_static" version = "1.4.0" @@ -940,7 +1130,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2caa5afb8bf9f3a2652760ce7d4f62d21c4d5a423e68466fca30df82f2330164" dependencies = [ "cfg-if", - "windows-targets 0.48.5", + "windows-targets 0.52.6", ] [[package]] @@ -949,7 +1139,7 @@ version = "0.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3af92c55d7d839293953fcd0fda5ecfe93297cfde6ffbdec13b41d99c0ba6607" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.6.0", "libc", "redox_syscall 0.4.1", ] @@ -1042,12 +1232,13 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2076a31b7010b17a38c01907c45b945e8f11495ee4dd588309718901b1f7a5b7" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.6.0", "jni-sys", "log", "ndk-sys", "num_enum", - "raw-window-handle", + "raw-window-handle 0.5.2", + "raw-window-handle 0.6.0", "thiserror", ] @@ -1139,7 +1330,7 @@ version = "0.10.66" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.6.0", "cfg-if", "foreign-types 0.3.2", "libc", @@ -1327,6 +1518,12 @@ dependencies = [ "getrandom", ] +[[package]] +name = "raw-window-handle" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9" + [[package]] name = "raw-window-handle" version = "0.6.0" @@ -1371,6 +1568,35 @@ dependencies = [ "bitflags 1.3.2", ] +[[package]] +name = "regex" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" + [[package]] name = "reqwest" version = "0.12.8" @@ -1441,7 +1667,7 @@ version = "0.38.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.6.0", "errno", "libc", "linux-raw-sys", @@ -1654,7 +1880,7 @@ version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "922fd3eeab3bd820d76537ce8f582b1cf951eceb5475c28500c7457d9d17f53a" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.6.0", "calloop", "calloop-wayland-source", "cursor-icon", @@ -1739,7 +1965,7 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.6.0", "core-foundation", "system-configuration-sys", ] @@ -1763,13 +1989,17 @@ dependencies = [ "console_error_panic_hook", "console_log", "enum-map", + "env_logger", "getrandom", "glam", "glow", + "glutin", + "glutin-winit", "image", "js-sys", "log", "rand", + "raw-window-handle 0.5.2", "reqwest", "serde", "tobj", @@ -2064,6 +2294,12 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + [[package]] name = "vcpkg" version = "0.2.15" @@ -2187,7 +2423,7 @@ version = "0.31.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "82fb96ee935c2cea6668ccb470fb7771f6215d1691746c2d896b447a00ad3f1f" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.6.0", "rustix", "wayland-backend", "wayland-scanner", @@ -2199,7 +2435,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "625c5029dbd43d25e6aa9615e88b829a5cad13b2819c4ae129fdbb7c31ab4c7e" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.6.0", "cursor-icon", "wayland-backend", ] @@ -2221,7 +2457,7 @@ version = "0.31.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f81f365b8b4a97f422ac0e8737c438024b5951734506b0e1d775c73030561f4" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.6.0", "wayland-backend", "wayland-client", "wayland-scanner", @@ -2233,7 +2469,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23803551115ff9ea9bce586860c5c5a971e360825a0309264102a9495a5ff479" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.6.0", "wayland-backend", "wayland-client", "wayland-protocols", @@ -2246,7 +2482,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ad1f61b76b6c2d8742e10f9ba5c3737f6530b4c243132c2a2ccc8aa96fe25cd6" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.6.0", "wayland-backend", "wayland-client", "wayland-protocols", @@ -2579,14 +2815,14 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winit" -version = "0.29.13" +version = "0.29.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b9d7047a2a569d5a81e3be098dcd8153759909b127477f4397e03cf1006d90a" +checksum = "0d59ad965a635657faf09c8f062badd885748428933dad8e8bdd64064d92e5ca" dependencies = [ "ahash", "android-activity", "atomic-waker", - "bitflags 2.4.2", + "bitflags 2.6.0", "bytemuck", "calloop", "cfg_aliases", @@ -2604,7 +2840,8 @@ dependencies = [ "once_cell", "orbclient", "percent-encoding", - "raw-window-handle", + "raw-window-handle 0.5.2", + "raw-window-handle 0.6.0", "redox_syscall 0.3.5", "rustix", "sctk-adwaita", @@ -2678,7 +2915,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d039de8032a9a8856a6be89cea3e5d12fdd82306ab7c94d74e6deab2460651c5" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.6.0", "dlib", "log", "once_cell", @@ -2691,6 +2928,12 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "054a8e68b76250b253f671d1268cb7f1ae089ec35e195b2efb2a4e9a836d0621" +[[package]] +name = "xml-rs" +version = "0.8.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af4e2e2f7cba5a093896c1e150fbfe177d1883e7448200efb81d40b9d339ef26" + [[package]] name = "zerocopy" version = "0.7.32" diff --git a/Cargo.toml b/Cargo.toml index 67ea1f8..3ea5ef3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,6 @@ codegen-units = 1 opt-level = 2 [dependencies] -winit = "*" # windowing and events glow = {version = "*", features = []} # rendering tobj = "*" # model loader # gltf = {version = "*", features = ["extras", "names"]} # model loader @@ -23,37 +22,26 @@ image = "*" # texture loader glam = "*" # linear algebra log = "*" # logging rand = {version = "*", features = ["small_rng"]} # rng -getrandom = {version = "*", features = ["js"]} # rng in the browser serde = {version = "*", features = ["derive"]} # serialization +enum-map = "*" # fast maps with enums as keys +bimap = "*" # bijective maps +reqwest = "*" # http requests +bytes = "*" # bytes for http responses + +[target.'cfg(target_arch = "wasm32")'.dependencies] +winit = "*" # windowing and events +getrandom = {version = "*", features = ["js"]} # rng in the browser console_log = "*" # log to browser console console_error_panic_hook = "*" # log to browser console on panic 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) -enum-map = "*" # fast maps with enums as keys -bimap = "*" # bijective maps -reqwest = "*" # http requests -bytes = "*" # bytes for http responses +web-sys = { version = "*", features = ["Document", "Window", "Element", "HtmlCanvasElement", "WebGl2RenderingContext", "Headers", "Request", "RequestInit", "RequestMode", "Response", "Performance", "PerformanceTiming", "AudioContext", "AudioNode", "AudioDestinationNode", "AudioBuffer", "AudioBufferSourceNode"] } -[dependencies.web-sys] # common browser APIs -version = "*" -features = [ - "Document", - "Window", - "Element", - "HtmlCanvasElement", - "WebGl2RenderingContext", - "Headers", - "Request", - "RequestInit", - "RequestMode", - "Response", - "Performance", - "PerformanceTiming", - "AudioContext", - "AudioNode", - "AudioDestinationNode", - "AudioBuffer", - "AudioBufferSourceNode", -] \ No newline at end of file +[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +env_logger = "*" +winit = { version = "0.29", features = ["x11", "rwh_05"], default-features = false } # windowing and events +raw-window-handle = { version = "0.5" } # get window handle +glutin = { version = "0.31" } # obtain opengl context +glutin-winit = { version = "0.4" } # obtain opengl context \ No newline at end of file diff --git a/nix/flake.lock b/nix/flake.lock new file mode 100644 index 0000000..780a8b9 --- /dev/null +++ b/nix/flake.lock @@ -0,0 +1,27 @@ +{ + "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 new file mode 100644 index 0000000..3f5071a --- /dev/null +++ b/nix/flake.nix @@ -0,0 +1,32 @@ +{ + 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 + ]; + LD_LIBRARY_PATH = "$LD_LIBRARY_PATH:${ + with pkgs; + pkgs.lib.makeLibraryPath [ + libGL + xorg.libX11 + xorg.libXcursor + xorg.libXi + libxkbcommon + xorg.libxcb + ] + }"; + }; + }; +} diff --git a/src/audio.rs b/src/audio.rs index 2b190de..5cbce90 100644 --- a/src/audio.rs +++ b/src/audio.rs @@ -1,9 +1,11 @@ use std::{cell::RefCell, collections::HashMap}; +#[cfg(target_arch = "wasm32")] pub struct Context { pub audio: web_sys::AudioContext, } +#[cfg(target_arch = "wasm32")] impl Context { pub fn new() -> Self { let audio = web_sys::AudioContext::new() @@ -14,11 +16,13 @@ impl Context { } } +#[cfg(target_arch = "wasm32")] pub struct Audio { pub buffer: &'static RefCell>, //pub source: &'static web_sys::AudioBufferSourceNode, } +#[cfg(target_arch = "wasm32")] impl Audio { pub fn new(ctx: &Context, bytes: &[u8]) -> Self { let sbuffer: &_ = Box::leak(Box::new(RefCell::new(None))); @@ -52,6 +56,7 @@ impl Audio { } } +#[cfg(target_arch = "wasm32")] pub struct Assets { pub ctx: Context, @@ -60,6 +65,7 @@ pub struct Assets { pub music_node: Option, } +#[cfg(target_arch = "wasm32")] impl Assets { pub fn new(f : F) -> Self where F: Fn(&Context) -> HashMap { let ctx = Context::new(); @@ -94,3 +100,63 @@ impl Assets { } } } + +#[cfg(not(target_arch = "wasm32"))] +pub struct Context { +} + +#[cfg(not(target_arch = "wasm32"))] +impl Context { + pub fn new() -> Self { + Self { + } + } +} + +#[cfg(not(target_arch = "wasm32"))] +pub struct Audio { +} + +#[cfg(not(target_arch = "wasm32"))] +impl Audio { + pub fn new(ctx: &Context, _bytes: &[u8]) -> Self { + Self { + } + } + + pub fn play(&self, ctx: &Context, looping: Option<(Option, Option)>) { + } +} + +#[cfg(not(target_arch = "wasm32"))] +pub struct Assets { + pub ctx: Context, + pub audio: HashMap, +} + +#[cfg(not(target_arch = "wasm32"))] +impl Assets { + pub fn new(f : F) -> Self where F: Fn(&Context) -> HashMap { + let ctx = Context::new(); + + let audio = f(&ctx); + + Self { + ctx, + audio, + } + } + + pub fn play_sfx(&mut self, name: &str) { + if let Some(a) = self.audio.get(name) { + a.play(&self.ctx, None); + } + } + + pub fn is_music_playing(&self) -> bool { + false + } + + pub fn play_music(&mut self, name: &str, start: Option, end: Option) { + } +} diff --git a/src/context.rs b/src/context.rs index dc1d3a2..c6c68bc 100644 --- a/src/context.rs +++ b/src/context.rs @@ -1,17 +1,15 @@ -use wasm_bindgen::JsCast; -use winit::platform::web::WindowExtWebSys; use glow::HasContext; +#[cfg(target_arch = "wasm32")] +use winit::platform::web::WindowExtWebSys; + +#[cfg(target_arch = "wasm32")] #[link(wasm_import_module = "./helpers.js")] extern { fn js_track_resized_setup(); fn js_poll_resized() -> bool; } -// pub const RENDER_WIDTH: f32 = 640.0; -// pub const RENDER_HEIGHT: f32 = 360.0; -// pub const RENDER_WIDTH: f32 = 320.0; -// pub const RENDER_HEIGHT: f32 = 180.0; pub const RENDER_WIDTH: f32 = 240.0; pub const RENDER_HEIGHT: f32 = 160.0; @@ -32,23 +30,13 @@ pub struct Context { pub window: winit::window::Window, pub gl: glow::Context, pub emptyvao: glow::VertexArray, + + #[cfg(target_arch = "wasm32")] pub performance: web_sys::Performance, } impl Context { - pub fn new(window: winit::window::Window) -> Self { - let gl = web_sys::window() - .and_then(|win| win.document()) - .and_then(|doc| { - let dst = doc.get_element_by_id("teleia-parent")?; - let canvas = web_sys::Element::from(window.canvas().expect("failed to find canvas")); - dst.append_child(&canvas).ok()?; - let c = canvas.dyn_into::().ok()?; - let webgl2_context = c.get_context("webgl2").ok()?? - .dyn_into::().ok()?; - Some(glow::Context::from_webgl2_context(webgl2_context)) - }) - .expect("couldn't add canvas to document"); + pub fn new(window: winit::window::Window, gl: glow::Context) -> Self { unsafe { gl.clear_color(0.1, 0.1, 0.1, 1.0); gl.clear_depth_f32(1.0); @@ -68,17 +56,21 @@ impl Context { gl.create_vertex_array().expect("failed to initialize vao") }; + #[cfg(target_arch = "wasm32")] unsafe { js_track_resized_setup(); } Self { window, gl, emptyvao, + + #[cfg(target_arch = "wasm32")] performance: web_sys::window().expect("failed to find window") .performance().expect("failed to get performance"), } } + #[cfg(target_arch = "wasm32")] pub fn maximize_canvas(&self) { web_sys::window() .and_then(|win| win.document()) @@ -100,12 +92,18 @@ impl Context { .expect("failed to resize canvas"); } + #[cfg(target_arch = "wasm32")] pub fn resize_necessary(&self) -> bool { unsafe { js_poll_resized() } } + #[cfg(not(target_arch = "wasm32"))] + pub fn resize_necessary(&self) -> bool { + false + } + pub fn clear_color(&self, color: glam::Vec4) { unsafe { self.gl.clear_color(color.x, color.y, color.z, color.w); diff --git a/src/lib.rs b/src/lib.rs index 41bfee8..b89b27e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,8 +1,5 @@ -use winit::platform::web::EventLoopExtWebSys; - pub mod utils; pub mod ui; -pub mod request; pub mod context; pub mod state; pub mod framebuffer; @@ -10,9 +7,17 @@ pub mod shader; pub mod mesh; pub mod texture; pub mod font; -pub mod audio; pub mod shadow; -pub mod module; +pub mod audio; + +#[cfg(target_arch = "wasm32")] +use winit::platform::web::EventLoopExtWebSys; + +#[cfg(target_arch = "wasm32")] +use winit::platform::web::WindowExtWebSys; + +#[cfg(target_arch = "wasm32")] +use wasm_bindgen::JsCast; static mut CTX: Option<*const context::Context> = None; static mut ST: Option<*mut state::State> = None; @@ -30,28 +35,186 @@ where } } +pub fn event_loop_body(event: winit::event::Event<()>, elwt: &winit::event_loop::EventLoopWindowTarget<()>) + where G: state::Game + 'static, +{ + contextualize(|ctx, st, game: &mut G| { + match &event { + winit::event::Event::WindowEvent { + event: wev, + window_id, + .. + } => match wev { + winit::event::WindowEvent::CloseRequested + if *window_id == ctx.window.id() => elwt.exit(), + winit::event::WindowEvent::Resized{..} => { + #[cfg(target_arch = "wasm32")] + ctx.maximize_canvas(); + st.handle_resize(&ctx); + }, + winit::event::WindowEvent::Focused(false) => { + st.keys = state::Keys::new(); + }, + winit::event::WindowEvent::CursorMoved { position, ..} => { + st.mouse_moved(&ctx, position.x as f32, position.y as f32, game); + }, + winit::event::WindowEvent::MouseInput { + button, + state, + .. + } => match state { + winit::event::ElementState::Pressed => { + st.mouse_pressed(&ctx, *button, game) + }, + winit::event::ElementState::Released => { + st.mouse_released(&ctx, *button) + }, + } + winit::event::WindowEvent::KeyboardInput { + event: winit::event::KeyEvent { + physical_key: winit::keyboard::PhysicalKey::Code(key), + state, + repeat: false, + .. + }, + .. + } => match state { + winit::event::ElementState::Pressed => { + st.key_pressed(&ctx, *key) + }, + winit::event::ElementState::Released => { + st.key_released(&ctx, *key) + }, + } + _ => {}, + }, + + winit::event::Event::AboutToWait => { + if ctx.resize_necessary() { + #[cfg(target_arch = "wasm32")] + ctx.maximize_canvas(); + st.handle_resize(&ctx); + } + if let Some(f) = &mut st.request { + match std::future::Future::poll(f.as_mut(), &mut st.waker_ctx) { + std::task::Poll::Pending => {}, + std::task::Poll::Ready(res) => { + st.request = None; + match res { + Ok(r) => st.request_returned(&ctx, game, r), + Err(e) => log::warn!("error during HTTP request: {}", e), + } + }, + } + // f.poll(); + } + st.run_update(&ctx, game); + st.run_render(&ctx, game); + ctx.window.request_redraw(); + }, + + _ => {}, + } + }); +} + pub async fn run<'a, F, G, Fut>(gnew: F) where Fut: std::future::Future, G: state::Game + 'static, F: (Fn(&'a context::Context) -> Fut), { - console_log::init_with_level(log::Level::Debug).unwrap(); - console_error_panic_hook::set_once(); - tracing_wasm::set_as_global_default(); + #[cfg(target_arch = "wasm32")] + { + console_log::init_with_level(log::Level::Debug).unwrap(); + console_error_panic_hook::set_once(); + tracing_wasm::set_as_global_default(); + } + #[cfg(not(target_arch = "wasm32"))] + { + env_logger::Builder::new() + .filter(None, log::LevelFilter::Info) + .init(); + } log::info!("hello computer, starting up..."); let event_loop = winit::event_loop::EventLoop::new() .expect("failed to initialize event loop"); - let window = winit::window::WindowBuilder::new() - .with_maximized(true) - .with_decorations(false) - .build(&event_loop) - .expect("failed to initialize window"); + #[cfg(target_arch = "wasm32")] + let (window, gl) = { + let window = winit::window::WindowBuilder::new() + .with_maximized(true) + .with_decorations(false) + .build(&event_loop) + .expect("failed to initialize window"); + let gl = web_sys::window() + .and_then(|win| win.document()) + .and_then(|doc| { + let dst = doc.get_element_by_id("teleia-parent")?; + let canvas = web_sys::Element::from(window.canvas().expect("failed to find canvas")); + dst.append_child(&canvas).ok()?; + let c = canvas.dyn_into::().ok()?; + let webgl2_context = c.get_context("webgl2").ok()?? + .dyn_into::().ok()?; + Some(glow::Context::from_webgl2_context(webgl2_context)) + }) + .expect("couldn't add canvas to document"); + (window, gl) + }; + + #[cfg(not(target_arch = "wasm32"))] + let (window, gl) = { + use glutin::config::GlConfig; + use glutin::context::NotCurrentGlContext; + use glutin::display::{GlDisplay, GetGlDisplay}; + use glutin::surface::GlSurface; + use raw_window_handle::HasRawWindowHandle; + use glutin_winit::GlWindow; + let window_builder = winit::window::WindowBuilder::new() + .with_title("teleia") + .with_maximized(true) + .with_decorations(false); + let template = glutin::config::ConfigTemplateBuilder::new(); + let display_builder = glutin_winit::DisplayBuilder::new().with_window_builder(Some(window_builder)); + let (window, gl_config) = display_builder + .build(&event_loop, template, |configs| { + configs.reduce(|a, c| { + if c.num_samples() > a.num_samples() { c } else { a } + }).expect("failed to obtain select configuration") + }).expect("failed to obtain opengl display"); + let window = window.expect("failed to create window"); + let raw_window_handle = window.raw_window_handle(); + let gl_display = gl_config.display(); + let context_attributes = glutin::context::ContextAttributesBuilder::new() + // .with_context_api(glutin::context::ContextApi::OpenGl(Some(glutin::context::Version { + // major: 3, + // minor: 3, + // }))) + .build(Some(raw_window_handle)); + unsafe { + let not_current_gl_context = gl_display.create_context(&gl_config, &context_attributes) + .expect("failed to obtain opengl context"); + let attrs = window.build_surface_attributes(Default::default()); + let gl_surface = gl_display.create_window_surface(&gl_config, &attrs) + .expect("failed to create opengl surface"); + let gl_context = not_current_gl_context.make_current(&gl_surface) + .expect("failed to set openglt context"); + let gl = glow::Context::from_loader_function_cstr(|s| gl_display.get_proc_address(s)); + gl_surface + .set_swap_interval(&gl_context, glutin::surface::SwapInterval::Wait(std::num::NonZeroU32::new(1).unwrap())) + .expect("failed to set swap interval"); + (window, gl) + } + }; + + let ctx = Box::leak(Box::new(context::Context::new(window, gl))); + + #[cfg(target_arch = "wasm32")] + { + ctx.maximize_canvas(); + } - let ctx = Box::leak(Box::new(context::Context::new(window))); - ctx.maximize_canvas(); let game = Box::leak(Box::new(gnew(ctx).await)); let st = Box::leak(Box::new(state::State::new(&ctx))); // request = Some(Box::new(async { @@ -64,83 +227,20 @@ where G = Some(game as *mut G as *mut std::ffi::c_void); } - event_loop.set_control_flow(winit::event_loop::ControlFlow::Wait); - event_loop.spawn(|event, elwt| { - contextualize(|ctx, st, game: &mut G| { - match &event { - winit::event::Event::WindowEvent { - event: wev, - window_id, - .. - } => match wev { - winit::event::WindowEvent::CloseRequested - if *window_id == ctx.window.id() => elwt.exit(), - winit::event::WindowEvent::Resized{..} => { - ctx.maximize_canvas(); - st.handle_resize(&ctx); - }, - winit::event::WindowEvent::Focused(false) => { - st.keys = state::Keys::new(); - }, - winit::event::WindowEvent::CursorMoved { position, ..} => { - st.mouse_moved(&ctx, position.x as f32, position.y as f32, game); - }, - winit::event::WindowEvent::MouseInput { - button, - state, - .. - } => match state { - winit::event::ElementState::Pressed => { - st.mouse_pressed(&ctx, *button, game) - }, - winit::event::ElementState::Released => { - st.mouse_released(&ctx, *button) - }, - } - winit::event::WindowEvent::KeyboardInput { - event: winit::event::KeyEvent { - physical_key: winit::keyboard::PhysicalKey::Code(key), - state, - repeat: false, - .. - }, - .. - } => match state { - winit::event::ElementState::Pressed => { - st.key_pressed(&ctx, *key) - }, - winit::event::ElementState::Released => { - st.key_released(&ctx, *key) - }, - } - _ => {}, - }, - - winit::event::Event::AboutToWait => { - if ctx.resize_necessary() { - ctx.maximize_canvas(); - st.handle_resize(&ctx); - } - if let Some(f) = &mut st.request { - match std::future::Future::poll(f.as_mut(), &mut st.waker_ctx) { - std::task::Poll::Pending => {}, - std::task::Poll::Ready(res) => { - st.request = None; - match res { - Ok(r) => st.request_returned(&ctx, game, r), - Err(e) => log::warn!("error during HTTP request: {}", e), - } - }, - } - // f.poll(); - } - st.run_update(&ctx, game); - st.run_render(&ctx, game); - ctx.window.request_redraw(); - }, - _ => {}, - } + #[cfg(target_arch = "wasm32")] + { + event_loop.set_control_flow(winit::event_loop::ControlFlow::Wait); + event_loop.spawn(|event, elwt| { + event_loop_body::(event, elwt); }); - }); + } + + #[cfg(not(target_arch = "wasm32"))] + { + event_loop.set_control_flow(winit::event_loop::ControlFlow::Poll); + event_loop.run(|event, elwt| { + event_loop_body::(event, elwt); + }).expect("window closed"); + } } diff --git a/src/module.rs b/src/module.rs deleted file mode 100644 index 1fc4100..0000000 --- a/src/module.rs +++ /dev/null @@ -1,45 +0,0 @@ -use wasm_bindgen::prelude::*; - -#[wasm_bindgen] -pub fn log_info(msg: i8) { - log::info!("{:?}", msg); -} - -#[wasm_bindgen(module="/src/js/module.js")] -extern "C" { - fn js_build_interface() -> js_sys::Object; -} - -pub struct Module { - pub wasm: js_sys::WebAssembly::Instance, -} - -impl Module { - pub async fn new(bytes: &[u8]) -> Option { - let imp = js_build_interface(); - let o = wasm_bindgen_futures::JsFuture::from( - js_sys::WebAssembly::instantiate_buffer(bytes, &imp) - ).await.unwrap(); - let i = js_sys::Reflect::get(&o, &"instance".into()).unwrap(); - if let Ok(wasm) = i.dyn_into::() { - Some(Self { - wasm, - }) - } else { - log::info!("failed 3"); - None - } - } - pub fn call(&self, nm: &str) { - let exp = self.wasm.exports(); - if let Ok(fo) = js_sys::Reflect::get(&exp, &nm.into()) { - if let Ok(func) = fo.dyn_into::() { - let _ = func.call0(&JsValue::undefined()); - } else { - log::warn!("couldn't cast module function: {}", nm); - } - } else { - log::warn!("couldn't find module function: {}", nm); - } - } -} diff --git a/src/request.rs b/src/request.rs deleted file mode 100644 index 7f66f57..0000000 --- a/src/request.rs +++ /dev/null @@ -1,20 +0,0 @@ -use wasm_bindgen::JsCast; - -pub async fn get_store(key: &str) -> Option { - let mut opts = web_sys::RequestInit::new(); - opts.method("GET"); - opts.mode(web_sys::RequestMode::Cors); - - let url = format!("https://colonq.computer/bullfrog/api/get/{}", key); - - let request = web_sys::Request::new_with_str_and_init(&url, &opts).ok()?; - - let window = web_sys::window().unwrap(); - let resp_value = wasm_bindgen_futures::JsFuture::from(window.fetch_with_request(&request)).await.ok()?; - - assert!(resp_value.is_instance_of::()); - let resp: web_sys::Response = resp_value.dyn_into().unwrap(); - - let text = wasm_bindgen_futures::JsFuture::from(resp.text().ok()?).await.ok()?; - text.as_string() -} diff --git a/src/state.rs b/src/state.rs index 8c70c51..c5478a9 100644 --- a/src/state.rs +++ b/src/state.rs @@ -93,9 +93,15 @@ pub struct PointLight { pub attenuation: glam::Vec2, } +#[cfg(target_arch = "wasm32")] +type Timestamp = f64; + +#[cfg(not(target_arch = "wasm32"))] +type Timestamp = std::time::Instant; + pub struct State { pub acc: f64, - pub last: f64, + pub last: Timestamp, pub tick: u64, pub rebinding: Option, @@ -119,10 +125,16 @@ pub struct State { pub log: Vec<(u64, String)>, } -pub fn now(ctx: &context::Context) -> f64 { +#[cfg(target_arch = "wasm32")] +pub fn now(ctx: &context::Context) -> Timestamp { ctx.performance.now() / 1000.0 } +#[cfg(not(target_arch = "wasm32"))] +pub fn now(_ctx: &context::Context) -> Timestamp { + std::time::Instant::now() +} + pub fn default_keybindings() -> BiHashMap { BiHashMap::from_iter(vec![ (winit::keyboard::KeyCode::KeyW, Key::Up), @@ -156,9 +168,12 @@ impl State { let cwaker = Box::leak(Box::new(waker.into())); let waker_ctx = std::task::Context::from_waker(cwaker); + let acc = 0.0; + let last = now(ctx); + Self { - acc: 0.0, - last: now(ctx), + acc, + last, // we initialize the tick to 1000, which allows us to use "0" as the default time for // various animation starts on entities without having them all play at game start tick: 1000, @@ -421,7 +436,12 @@ impl State { pub fn run_update(&mut self, ctx: &context::Context, game: &mut G) where G: Game { let now = now(ctx); + + #[cfg(target_arch = "wasm32")] let diff = now - self.last; + #[cfg(not(target_arch = "wasm32"))] + let diff = now.duration_since(self.last).as_secs_f64(); + self.acc += diff; self.last = now; -- cgit v1.2.3