From 742b371059aa2fbe3dc76b612ff9362e3ce5f3df Mon Sep 17 00:00:00 2001 From: mosure Date: Mon, 15 Jan 2024 02:55:48 -0600 Subject: [PATCH] feat: bevy_args resource parsing plugin --- .cargo/config.toml | 17 ++++ .devcontainer/Dockerfile | 20 +++++ .devcontainer/devcontainer.json | 33 ++++++++ .devcontainer/docker-compose.yaml | 10 +++ .gitattributes | 8 ++ .github/dependabot.yml | 14 ++++ .github/workflows/test.yml | 43 ++++++++++ .github/workflows/todo_tracker.yml | 24 ++++++ .gitignore | 16 ++++ .../bevy_gaussian_splatting.code-workspace | 13 +++ .vscode/launch.json | 73 +++++++++++++++++ .vscode/settings.json | 5 ++ Cargo.toml | 80 +++++++++++++++++++ README.md | 56 +++++++++++++ examples/minimal.rs | 64 +++++++++++++++ src/lib.rs | 57 +++++++++++++ src/macro.rs | 0 www/README.md | 15 ++++ www/index.html | 23 ++++++ 19 files changed, 571 insertions(+) create mode 100644 .cargo/config.toml create mode 100644 .devcontainer/Dockerfile create mode 100644 .devcontainer/devcontainer.json create mode 100644 .devcontainer/docker-compose.yaml create mode 100644 .gitattributes create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/test.yml create mode 100644 .github/workflows/todo_tracker.yml create mode 100644 .gitignore create mode 100644 .vscode/bevy_gaussian_splatting.code-workspace create mode 100644 .vscode/launch.json create mode 100644 .vscode/settings.json create mode 100644 Cargo.toml create mode 100644 examples/minimal.rs create mode 100644 src/lib.rs create mode 100644 src/macro.rs create mode 100644 www/README.md create mode 100644 www/index.html diff --git a/.cargo/config.toml b/.cargo/config.toml new file mode 100644 index 0000000..ad43947 --- /dev/null +++ b/.cargo/config.toml @@ -0,0 +1,17 @@ +# alternatively, `export CARGO_TARGET_WASM32_UNKNOWN_UNKNOWN_RUNNER=wasm-server-runner` + +[target.wasm32-unknown-unknown] +runner = "wasm-server-runner" +rustflags = [ + "--cfg=web_sys_unstable_apis", + # "-C", + # "target-feature=+atomics,+bulk-memory,+mutable-globals", # for wasm-bindgen-rayon +] + + +# fix spurious network error on windows +# [source.crates-io] +# registry = "https://github.com/rust-lang/crates.io-index" + +[http] +proxy = "" diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 0000000..725c1cb --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,20 @@ +FROM mcr.microsoft.com/devcontainers/rust:0-1 + +WORKDIR /workspace + +RUN apt-get update && DEBIAN_FRONTEND="noninteractive" apt-get install -y \ + build-essential \ + libpulse-dev \ + libdbus-1-dev \ + libudev-dev \ + libssl-dev \ + xorg \ + openbox \ + alsa-tools \ + librust-alsa-sys-dev \ + && rm -rf /var/lib/apt/lists/* + +RUN rustup target install wasm32-unknown-unknown + +RUN cargo install flamegraph +RUN cargo install wasm-server-runner diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..3a1380e --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,33 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the +// README at: https://github.com/devcontainers/templates/tree/main/src/rust +{ + "dockerComposeFile": ["docker-compose.yaml"], + "workspaceFolder": "/workspace", + "remoteUser": "vscode", + "shutdownAction": "stopCompose", + "service": "devcontainer", + + "features": { + "ghcr.io/devcontainers/features/common-utils:2": { + "installZsh": "true", + "username": "vscode", + "userUid": "1000", + "userGid": "1000", + "upgradePackages": "true" + }, + "ghcr.io/devcontainers/features/rust:1": "latest", + "ghcr.io/devcontainers-contrib/features/zsh-plugins:0": { + "plugins": "history history-substring-search" + } + }, + "customizations": { + "vscode": { + "settings": {}, + "extensions": [ + "rust-lang.rust-analyzer", + "serayuzgur.crates", + "vadimcn.vscode-lldb" + ] + } + } +} diff --git a/.devcontainer/docker-compose.yaml b/.devcontainer/docker-compose.yaml new file mode 100644 index 0000000..18b700b --- /dev/null +++ b/.devcontainer/docker-compose.yaml @@ -0,0 +1,10 @@ +services: + devcontainer: + build: + context: . + dockerfile: ./Dockerfile + volumes: + - type: bind + source: .. + target: /workspace + command: sleep infinity diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..43fc914 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,8 @@ +* text=auto eol=lf +*.{cmd,[cC][mM][dD]} text eol=crlf +*.{bat,[bB][aA][tT]} text eol=crlf +*.sh text eol=lf +*.conf text eol=lf + +*.ply binary +*.splat binary diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..5755d69 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,14 @@ +# Please see the documentation for all configuration options: +# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates + +version: 2 +updates: + - package-ecosystem: "cargo" + directory: "/" + schedule: + interval: "weekly" + ignore: + # These are peer deps of Cargo and should not be automatically bumped + - dependency-name: "semver" + - dependency-name: "crates-io" + rebase-strategy: "disabled" diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..845ff11 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,43 @@ +name: test + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +env: + CARGO_TERM_COLOR: always + RUST_BACKTRACE: 1 + +jobs: + build: + + strategy: + fail-fast: false + matrix: + os: [windows-latest, macos-latest] + rust-toolchain: + - nightly + + runs-on: ${{ matrix.os }} + timeout-minutes: 120 + + steps: + - uses: actions/checkout@v3 + + - name: Setup ${{ matrix.rust-toolchain }} rust toolchain with caching + uses: brndnmtthws/rust-action@v1 + with: + toolchain: ${{ matrix.rust-toolchain }} + components: rustfmt, clippy + enable-sccache: "true" + + - name: build + run: cargo build --example=minimal + + - name: build (web) + run: cargo build --example=minimal --target wasm32-unknown-unknown --release + + - name: lint + run: cargo clippy -- -Dwarnings diff --git a/.github/workflows/todo_tracker.yml b/.github/workflows/todo_tracker.yml new file mode 100644 index 0000000..a3b1eb6 --- /dev/null +++ b/.github/workflows/todo_tracker.yml @@ -0,0 +1,24 @@ + +name: 'todo tracker' + +on: + push: + branches: [ main ] + +jobs: + build: + permissions: + issues: write + + name: todo_tracker + runs-on: [ubuntu-latest] + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: "TODO to Issue" + uses: "alstr/todo-to-issue-action@v4" + id: "todo" + with: + AUTO_ASSIGN: true diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..520f614 --- /dev/null +++ b/.gitignore @@ -0,0 +1,16 @@ +debug/ +target/ +vendor/ +out/ +Cargo.lock +**/*.rs.bk +*.pdb + +*.py + +*.ply +*.gcloud + +.DS_Store + +www/assets/ diff --git a/.vscode/bevy_gaussian_splatting.code-workspace b/.vscode/bevy_gaussian_splatting.code-workspace new file mode 100644 index 0000000..fbf610a --- /dev/null +++ b/.vscode/bevy_gaussian_splatting.code-workspace @@ -0,0 +1,13 @@ +{ + "folders": [ + { + "path": "../" + }, + { + "path": "../../bevy" + } + ], + "settings": { + "liveServer.settings.multiRootWorkspaceName": "bevy_gaussian_splatting" + } +} \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..e58836f --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,73 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "lldb", + "request": "launch", + "name": "Debug unit tests in library 'bevy_gaussian_splatting'", + "cargo": { + "args": [ + "test", + "--no-run", + "--lib", + "--package=bevy_gaussian_splatting" + ], + "filter": { + "name": "bevy_gaussian_splatting", + "kind": "lib" + } + }, + "args": [], + "cwd": "${workspaceFolder}", + "env": { + "CARGO_MANIFEST_DIR": "${workspaceFolder}", + } + }, + { + "type": "lldb", + "request": "launch", + "name": "Debug executable 'viewer'", + "cargo": { + "args": [ + "build", + "--bin=viewer", + "--package=bevy_gaussian_splatting" + ], + "filter": { + "name": "viewer", + "kind": "bin" + } + }, + "args": [], + "cwd": "${workspaceFolder}", + "env": { + "CARGO_MANIFEST_DIR": "${workspaceFolder}", + } + }, + { + "type": "lldb", + "request": "launch", + "name": "Debug unit tests in executable 'viewer'", + "cargo": { + "args": [ + "test", + "--no-run", + "--bin=viewer", + "--package=bevy_gaussian_splatting" + ], + "filter": { + "name": "viewer", + "kind": "bin" + } + }, + "args": [], + "cwd": "${workspaceFolder}", + "env": { + "CARGO_MANIFEST_DIR": "${workspaceFolder}", + } + } + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..352a626 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "rust-analyzer.linkedProjects": [ + "./Cargo.toml" + ] +} \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..d3e7bc9 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,80 @@ +[package] +name = "bevy_args" +description = "bevy plugin to parse command line arguments and URL query parameters" +version = "2.0.2" +edition = "2021" +authors = ["mosure "] +license = "MIT" +keywords = [ + "bevy", + "args", + "command-line-arguments", + "query-parameters", +] +homepage = "https://github.com/mosure/bevy_args" +repository = "https://github.com/mosure/bevy_args" +readme = "README.md" +exclude = [ + ".devcontainer", + ".github", + "docs", + "dist", + "build", + "assets", + "credits", +] + + +[dependencies] +clap = { version = "4.4", features = ["derive"] } +serde = "1.0" +serde_qs = "0.12" + + +[dependencies.bevy] +version = "0.12" +default-features = false + + +[target.'cfg(target_arch = "wasm32")'.dependencies] +console_error_panic_hook = "0.1" +wasm-bindgen = "0.2" + + +[dependencies.web-sys] +version = "0.3" +features = [ + 'Document', + 'Element', + 'HtmlElement', + 'Location', + 'Node', + 'Window', +] + + +[profile.dev.package."*"] +opt-level = 3 + +[profile.dev] +opt-level = 1 + +[profile.release] +lto = "thin" +codegen-units = 1 +opt-level = 3 + +[profile.wasm-release] +inherits = "release" +opt-level = "z" +lto = "fat" +codegen-units = 1 + + +[lib] +path = "src/lib.rs" + + +[examples] +name = "minimal" +path = "examples/minimal.rs" diff --git a/README.md b/README.md index fc1fd01..e1d76ce 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,58 @@ # bevy_args bevy plugin to parse command line arguments and URL query parameters + + +## command line arguments +`cargo run --example=minimal -- --my_string hello --my_int 42 --my_bool` + +## URL query parameters +`http://localhost:8080/?my_string=hello&my_int=42&my_bool=true` + + +## minimal example + +```rust +use bevy_args::BevyArgsPlugin; + + +#[derive( + Default, + Debug, + Resource, + Serialize, + Deserialize, + Parser, +)] +#[command(about = "a minimal example of bevy_args", version, long_about = None)] +pub struct MinimalArgs { + #[arg(long, default_value = "hello")] + pub my_string: String, + + #[arg(long, default_value = "42")] + pub my_int: i32, + + #[arg(long)] + pub my_bool: bool, +} + + +pub fn main() { + let mut app = App::new(); + + app.add_plugins(BevyArgsPlugin::::default()); + app.add_systems(Startup, print_minimal_args); + + app.run(); +} + +fn print_minimal_args(args: Res) { + println!("{:?}", *args); +} +``` + + +## compatible bevy versions + +| `bevy_args` | `bevy` | +| :-- | :-- | +| `1.0` | `0.12` | diff --git a/examples/minimal.rs b/examples/minimal.rs new file mode 100644 index 0000000..f165530 --- /dev/null +++ b/examples/minimal.rs @@ -0,0 +1,64 @@ +use bevy::prelude::*; +use clap::Parser; +use serde::{ + Deserialize, + Serialize, +}; + +#[cfg(target_arch = "wasm32")] +use wasm_bindgen::prelude::*; + +use bevy_args::BevyArgsPlugin; + + +#[cfg(target_arch = "wasm32")] +#[wasm_bindgen] +extern "C" { + #[wasm_bindgen(js_namespace = console)] + fn log(s: &str); +} + + +#[derive( + Default, + Debug, + Resource, + Serialize, + Deserialize, + Parser, +)] +#[command(about = "a minimal example of bevy_args", version, long_about = None)] +pub struct MinimalArgs { + #[arg(long, default_value = "hello")] + #[serde(default)] + pub my_string: String, + + #[arg(long, default_value = "42")] + #[serde(default)] + pub my_int: i32, + + #[arg(long)] + #[serde(default)] + pub my_bool: bool, +} + + +pub fn main() { + #[cfg(target_arch = "wasm32")] + console_error_panic_hook::set_once(); + + let mut app = App::new(); + + app.add_plugins(BevyArgsPlugin::::default()); + app.add_systems(Startup, print_minimal_args); + + app.run(); +} + +fn print_minimal_args(args: Res) { + #[cfg(target_arch = "wasm32")] + log(format!("{:?}", *args).as_str()); + + #[cfg(not(target_arch = "wasm32"))] + println!("{:?}", *args); +} diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..a4c112e --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,57 @@ +use std::marker::PhantomData; + +#[cfg(target_arch = "wasm32")] +use std::collections::HashMap; + +use bevy::prelude::*; +use clap::Parser; +use serde::{ + Deserialize, + Serialize, +}; + +#[cfg(target_arch = "wasm32")] +use serde_qs::from_str; +#[cfg(target_arch = "wasm32")] +use wasm_bindgen::prelude::*; + + +pub struct BevyArgsPlugin { + phantom: PhantomData R>, +} +impl Default for BevyArgsPlugin { + fn default() -> Self { + Self { + phantom: PhantomData, + } + } +} + +impl Deserialize<'a>> Plugin for BevyArgsPlugin { + fn build(&self, app: &mut App) { + app.insert_resource(R::default()); + + app.add_systems(PreStartup, parse_args::); + } +} + + +fn parse_args Deserialize<'a>>( + mut args: ResMut, +) { + #[cfg(target_arch = "wasm32")] + { + let window = web_sys::window().unwrap(); + let location = window.location(); + let search = location.search().unwrap(); + + let query_string = search.trim_start_matches('?'); + + *args = from_str(query_string).unwrap(); + } + + #[cfg(not(target_arch = "wasm32"))] + { + *args = R::parse(); + } +} diff --git a/src/macro.rs b/src/macro.rs new file mode 100644 index 0000000..e69de29 diff --git a/www/README.md b/www/README.md new file mode 100644 index 0000000..6bb7ad6 --- /dev/null +++ b/www/README.md @@ -0,0 +1,15 @@ +# bevy_gaussian_splatting for web + +## wasm support + +to build wasm run: + +```bash +cargo build --example=minimal --target wasm32-unknown-unknown --release +``` + +to generate bindings: +> `wasm-bindgen --out-dir ./www/out/ --target web ./target/wasm32-unknown-unknown/release/examples/minimal.wasm` + + +open a live server of `index.html` and append args: `?my_string=hello_world` diff --git a/www/index.html b/www/index.html new file mode 100644 index 0000000..cb745cb --- /dev/null +++ b/www/index.html @@ -0,0 +1,23 @@ + + + + bevy_args + + + + +