diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..dc337cc --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,6 @@ +{ + "rust-analyzer.linkedProjects": [ + "crates/bevy-example/Cargo.toml", + "rust/Cargo.toml", + ] +} \ No newline at end of file diff --git a/components/bevy.tsx b/components/bevy.tsx new file mode 100644 index 0000000..9647954 --- /dev/null +++ b/components/bevy.tsx @@ -0,0 +1,17 @@ +import { useEffect } from "react"; +import { run } from "../crates/bevy-example/pkg"; + +const bevyGlobal = {bevy: null}; + +export const BevyExample = (props: {width: number; height: number}) => { + useEffect(() => { + try { + run(props.width, props.height); + } catch (e) { + console.error(e); + } + }, []); + return <>; +}; + +export default BevyExample; diff --git a/components/bevy_dynamic.tsx b/components/bevy_dynamic.tsx new file mode 100644 index 0000000..fa888d1 --- /dev/null +++ b/components/bevy_dynamic.tsx @@ -0,0 +1,3 @@ +import dynamic from "next/dynamic"; + +export const BevyExample = dynamic(() => import("./bevy"), { ssr: false }); diff --git a/crates/bevy-example/.cargo-ok b/crates/bevy-example/.cargo-ok new file mode 100644 index 0000000..e69de29 diff --git a/crates/bevy-example/.cargo/config.toml b/crates/bevy-example/.cargo/config.toml new file mode 100644 index 0000000..f4e8c00 --- /dev/null +++ b/crates/bevy-example/.cargo/config.toml @@ -0,0 +1,2 @@ +[build] +target = "wasm32-unknown-unknown" diff --git a/crates/bevy-example/.gitignore b/crates/bevy-example/.gitignore new file mode 100644 index 0000000..4e30131 --- /dev/null +++ b/crates/bevy-example/.gitignore @@ -0,0 +1,6 @@ +/target +**/*.rs.bk +Cargo.lock +bin/ +pkg/ +wasm-pack.log diff --git a/crates/bevy-example/.travis.yml b/crates/bevy-example/.travis.yml new file mode 100644 index 0000000..7a91325 --- /dev/null +++ b/crates/bevy-example/.travis.yml @@ -0,0 +1,69 @@ +language: rust +sudo: false + +cache: cargo + +matrix: + include: + + # Builds with wasm-pack. + - rust: beta + env: RUST_BACKTRACE=1 + addons: + firefox: latest + chrome: stable + before_script: + - (test -x $HOME/.cargo/bin/cargo-install-update || cargo install cargo-update) + - (test -x $HOME/.cargo/bin/cargo-generate || cargo install --vers "^0.2" cargo-generate) + - cargo install-update -a + - curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh -s -- -f + script: + - cargo generate --git . --name testing + # Having a broken Cargo.toml (in that it has curlies in fields) anywhere + # in any of our parent dirs is problematic. + - mv Cargo.toml Cargo.toml.tmpl + - cd testing + - wasm-pack build + - wasm-pack test --chrome --firefox --headless + + # Builds on nightly. + - rust: nightly + env: RUST_BACKTRACE=1 + before_script: + - (test -x $HOME/.cargo/bin/cargo-install-update || cargo install cargo-update) + - (test -x $HOME/.cargo/bin/cargo-generate || cargo install --vers "^0.2" cargo-generate) + - cargo install-update -a + - rustup target add wasm32-unknown-unknown + script: + - cargo generate --git . --name testing + - mv Cargo.toml Cargo.toml.tmpl + - cd testing + - cargo check + - cargo check --target wasm32-unknown-unknown + - cargo check --no-default-features + - cargo check --target wasm32-unknown-unknown --no-default-features + - cargo check --no-default-features --features console_error_panic_hook + - cargo check --target wasm32-unknown-unknown --no-default-features --features console_error_panic_hook + - cargo check --no-default-features --features "console_error_panic_hook wee_alloc" + - cargo check --target wasm32-unknown-unknown --no-default-features --features "console_error_panic_hook wee_alloc" + + # Builds on beta. + - rust: beta + env: RUST_BACKTRACE=1 + before_script: + - (test -x $HOME/.cargo/bin/cargo-install-update || cargo install cargo-update) + - (test -x $HOME/.cargo/bin/cargo-generate || cargo install --vers "^0.2" cargo-generate) + - cargo install-update -a + - rustup target add wasm32-unknown-unknown + script: + - cargo generate --git . --name testing + - mv Cargo.toml Cargo.toml.tmpl + - cd testing + - cargo check + - cargo check --target wasm32-unknown-unknown + - cargo check --no-default-features + - cargo check --target wasm32-unknown-unknown --no-default-features + - cargo check --no-default-features --features console_error_panic_hook + - cargo check --target wasm32-unknown-unknown --no-default-features --features console_error_panic_hook + # Note: no enabling the `wee_alloc` feature here because it requires + # nightly for now. diff --git a/crates/bevy-example/.vscode/settings.json b/crates/bevy-example/.vscode/settings.json new file mode 100644 index 0000000..865ec57 --- /dev/null +++ b/crates/bevy-example/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + // "rust-analyzer.cargo.target": "wasm32-unknown-unknown", +} diff --git a/crates/bevy-example/Cargo.toml b/crates/bevy-example/Cargo.toml new file mode 100644 index 0000000..a335e1e --- /dev/null +++ b/crates/bevy-example/Cargo.toml @@ -0,0 +1,24 @@ +[package] +name = "bevy-example" +version = "0.1.0" +authors = ["Kevin King <4kevinking@gmail.com>"] +edition = "2021" + +[lib] +crate-type = ["cdylib", "rlib"] + +[features] +default = ["console_error_panic_hook"] + +[dependencies] +wasm-bindgen = "0.2.63" +console_error_panic_hook = { version = "0.1.6", optional = true } +wee_alloc = { version = "0.4.5" } +bevy = "0.6.1" + +[dev-dependencies] +wasm-bindgen-test = "0.3.13" + +[profile.release] +# Tell `rustc` to optimize for small code size. +opt-level = "s" diff --git a/crates/bevy-example/src/lib.rs b/crates/bevy-example/src/lib.rs new file mode 100644 index 0000000..e6f2aeb --- /dev/null +++ b/crates/bevy-example/src/lib.rs @@ -0,0 +1,56 @@ +mod utils; + +use wasm_bindgen::prelude::*; + +// #[global_allocator] +// static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT; + +#[wasm_bindgen] +pub fn greet() {} + +// TODO: send reasonable canvas size to rust +// TODO: debug memory leak (happens at least on windows/FF) -- switching off of wee_alloc may have fixed this? +// TODO: sometimes hit `unreachable error` after window is open for a while, i +// think we need to have actual singleton on react side +use bevy::prelude::*; +#[wasm_bindgen] +pub fn run(width: f32, height: f32) { + App::new() + .insert_resource(WindowDescriptor { + canvas: Some("#bevy-canvas".into()), + width, + height, + ..Default::default() + }) + .add_plugins(DefaultPlugins) + .add_startup_system(setup) + .add_system(tick) + .run(); +} + +#[derive(Component)] +struct CubeTag; + +fn setup(mut commands: Commands) { + commands.spawn_bundle(OrthographicCameraBundle::new_2d()); + commands + .spawn_bundle(SpriteBundle { + sprite: Sprite { + color: Color::rgb(0.25, 0.25, 0.75), + custom_size: Some(Vec2::new(50.0, 50.0)), + ..Default::default() + }, + ..Default::default() + }) + .insert(CubeTag); +} + +fn tick(mut q: Query<(&mut Transform, &CubeTag)>, windows: Res) { + for mut cube in q.iter_mut() { + let pos = &mut cube.0.translation; + let window = windows.get_primary().unwrap(); + let cursor = window.cursor_position().unwrap_or_default(); + pos.x = cursor.x - window.width() / 2.; + pos.y = cursor.y - window.height() / 2.; + } +} diff --git a/crates/bevy-example/src/utils.rs b/crates/bevy-example/src/utils.rs new file mode 100644 index 0000000..b1d7929 --- /dev/null +++ b/crates/bevy-example/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/crates/bevy-example/tests/web.rs b/crates/bevy-example/tests/web.rs new file mode 100644 index 0000000..de5c1da --- /dev/null +++ b/crates/bevy-example/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); +} diff --git a/package.json b/package.json index ac70a5d..d58dea0 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "private": true, "scripts": { "dev": "next dev", - "build": "cd rust && wasm-pack build && cd .. && next build", + "build": "cd rust && wasm-pack build && cd ../crates/bevy-example && wasm-pack build && cd ../.. && next build", "start": "next start", "lint": "next lint", "vercel-build-deps": "curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | bash -s -- -y && export PATH=\"/vercel/.cargo/bin:$PATH\" && wget -O wasm-pack.tar.gz \"https://github.com/rustwasm/wasm-pack/releases/download/v0.10.2/wasm-pack-v0.10.2-x86_64-unknown-linux-musl.tar.gz\" && tar xvf wasm-pack.tar.gz && ls && yarn install" diff --git a/pages/blog/benefits-of-bevy.mdx b/pages/blog/benefits-of-bevy.mdx new file mode 100644 index 0000000..2f8d882 --- /dev/null +++ b/pages/blog/benefits-of-bevy.mdx @@ -0,0 +1,20 @@ +import { MDXProvider } from "@mdx-js/react"; +import { Layout } from "../../components/bloglayout"; +export default ({ children }) => {children}; + +import { BevyExample } from "../../components/bevy_dynamic"; + +export const meta = { + title: "Intro to Bevy", + date: "Feb 19 2022", + draft: true, + subtitle: "yea", +}; + +# {meta.title} + +> {meta.subtitle} + + + +{}