Skip to content

Commit

Permalink
test(examples): 💍 example run in wasm
Browse files Browse the repository at this point in the history
  • Loading branch information
wjian23 authored and rchangelog[bot] committed May 14, 2024
1 parent b406b30 commit 9892ae9
Show file tree
Hide file tree
Showing 33 changed files with 420 additions and 84 deletions.
2 changes: 2 additions & 0 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
[env]
CARGO_WORKSPACE_DIR = {value = "", relative = true}
[alias]
run-wasm = "run --package cli -- run-wasm --template ./cli/template"
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ Please only add new entries below the [Unreleased](#unreleased---releasedate) he
- **dev-helper**: Support specific the comparison of image tests. (#573 @M-Adoo)
- **dev-helper**: If test images differ, both actual and difference images are saved with the expected image. (#573 @M-Adoo)

- **example**: run example in web wasm (#571 @wjian23)

### Documented

- **core**: Explained when to use `unsubscribe` with `watch!`. (#556, @M-Adoo)
Expand Down
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ members = [
"tests",
"dev-helper",
"examples/*",
"cli",
]
resolver = "2"

Expand Down Expand Up @@ -68,7 +69,7 @@ quote = "1.0.16"
rayon = "1.5.1"
rctree = "0.5.0"
rustybuzz = "0.11.0"
rxrust = {version = "1.0.0-beta.6", default-features = false, features = ["futures-scheduler"]}
rxrust = { git ="https://github.com/rxRust/rxRust", default-features = false, features = ["futures-scheduler"]}
scoped_threadpool = "0.1.9"
triomphe = "0.1.11"
serde = "1.0"
Expand Down
11 changes: 11 additions & 0 deletions cli/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[package]
name = "cli"
version = "0.1.0"
edition = "2021"
publish = false

[dependencies]
xshell = "0.2.3"
clap = {version = "4.5.4", features = ["cargo", "derive"] }
anyhow = { version = "1.0" }
fs_extra = "1.3.0"
8 changes: 8 additions & 0 deletions cli/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
## Cli for ribir build
### SubCommand
**run-wasm**: build the example to wasm
1. compile to target wasm32-unknown-unknown
2. use wasm-bindgen to export relative function to js
3. serve the wasm in 127.0.0.1:8000 by simpl-http-server

you can see more usage information by --help.
29 changes: 29 additions & 0 deletions cli/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
mod program_check;
mod run_wasm;

use anyhow::Result;
use clap::ArgMatches;
use run_wasm::run_wasm;

trait CliCommand {
fn name(&self) -> &str;
fn command(&self) -> clap::Command;
fn exec(&self, args: &ArgMatches) -> Result<()>;
}

fn main() {
let mut cli = clap::Command::new("cli").bin_name("cli");

let commands = [run_wasm()];

for cmd in &commands {
cli = cli.subcommand(cmd.command());
}
let matches = cli.get_matches();

if let Some((sub_cmd, matches)) = matches.subcommand() {
if let Some(cmd) = commands.iter().find(|cmd| cmd.name() == sub_cmd) {
let _ = cmd.exec(matches);
}
}
}
36 changes: 36 additions & 0 deletions cli/src/program_check.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/// ** This implementation is base on [https://github.com/gfx-rs/wgpu/blob/trunk/xtask/src/util.rs]!**
use std::{io, process::Command};

pub(crate) struct Program {
pub binary_name: &'static str,
pub crate_name: &'static str,
}

pub(crate) fn check_all_programs(programs: &[Program]) -> anyhow::Result<()> {
let mut failed = Vec::new();
for Program { binary_name, crate_name } in programs {
let mut cmd = Command::new(binary_name);
cmd.arg("--help");
let output = cmd.output();
match output {
Ok(_output) => {
println!("Checking for {binary_name} in PATH: ✅");
}
Err(e) if matches!(e.kind(), io::ErrorKind::NotFound) => {
eprintln!("Checking for {binary_name} in PATH: ❌");
failed.push(*crate_name);
}
Err(e) => {
eprintln!("Checking for {binary_name} in PATH: ❌");
panic!("Unknown IO error: {:?}", e);
}
}
}

if !failed.is_empty() {
eprintln!("Please install them with: cargo install {}", failed.join(" "));
anyhow::bail!("Missing programs in PATH");
}

Ok(())
}
130 changes: 130 additions & 0 deletions cli/src/run_wasm.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
use std::{path::PathBuf, str::FromStr};

use anyhow::Result;
use clap::{command, CommandFactory, FromArgMatches, Parser};

use crate::{
program_check::{check_all_programs, Program},
CliCommand,
};

pub fn run_wasm() -> Box<dyn CliCommand> { Box::new(RunWasm {}) }

struct RunWasm {}

#[derive(Parser, Debug)]
#[command(name = "run-wasm")]
/// run as web wasm
struct Wasm {
/// Package of which to run
#[arg(short, long)]
package: String,

/// Name of output, default to web_wasm
#[arg(short, long)]
name: Option<String>,

/// Direction path to output, default to target/wasm
#[arg(short, long)]
out_dir: Option<PathBuf>,

/// Build release, default build to debug
#[arg(short, long)]
release: bool,

/// Just build the wasm files, don't serve them
#[arg(long, name = "no-server")]
no_server: bool,

/// Template files need to copy to Output dir
#[arg(short, long)]
template: Option<PathBuf>,
}

impl CliCommand for RunWasm {
fn name(&self) -> &str { "run-wasm" }

fn command(&self) -> clap::Command { Wasm::command() }

fn exec(&self, args: &clap::ArgMatches) -> Result<()> {
let args = Wasm::from_arg_matches(args)?;

let mut dependencies =
vec![Program { crate_name: "wasm-bindgen-cli", binary_name: "wasm-bindgen" }];

if !args.no_server {
dependencies
.push(Program { crate_name: "simple-http-server", binary_name: "simple-http-server" });
}
check_all_programs(&dependencies)?;

let root_path = PathBuf::from_str(env!("CARGO_WORKSPACE_DIR"))?;
let package = args.package;
let name = args.name.unwrap_or("web_wasm".to_string());

let out_dir = args
.out_dir
.unwrap_or(PathBuf::from("./target/wasm"));
let output =
if out_dir.is_relative() { root_path.clone().join(&out_dir) } else { out_dir.clone() };

let shell = xshell::Shell::new()?;
let release_flg = if args.release { Some("--release") } else { None };

xshell::cmd!(
shell,
"cargo build -p {package} --lib {release_flg...} --target wasm32-unknown-unknown"
)
.quiet()
.run()?;

shell.change_dir(env!("CARGO_WORKSPACE_DIR"));
let target_path = if args.release {
"target/wasm32-unknown-unknown/release"
} else {
"target/wasm32-unknown-unknown/debug"
};

xshell::cmd!(
shell,
"wasm-bindgen {target_path}/{package}.wasm --target web
--no-typescript --out-dir {output} --out-name {name}"
)
.quiet()
.run()?;

if let Some(mut path) = args.template.clone() {
if path.is_relative() {
path = root_path.clone().join(path);
}
if path.is_dir() {
fs_extra::dir::copy(
&path,
&output,
&fs_extra::dir::CopyOptions::new()
.overwrite(true)
.content_only(true),
)?;
} else {
let file_name = output.clone().join(path.file_name().unwrap());
fs_extra::file::copy(
&path,
file_name,
&fs_extra::file::CopyOptions::new().overwrite(true),
)?;
}
}

if !args.no_server {
shell.change_dir(root_path);
xshell::cmd!(
shell,
"simple-http-server {out_dir} -c wasm,html,js -i --coep --coop --nocache"
)
.quiet()
.run()?;
}

Ok(())
}
}
21 changes: 21 additions & 0 deletions cli/template/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<!DOCTYPE html>
<html>

<head>
<meta charset="UTF-8" />
<title>Ribir</title>
</head>

<body>
<canvas class="ribir_canvas" style="width: 400px;height: 600px;" width="800" height="1200"></canvas>
<script type="module">
import init, { run } from "./web_wasm.js";
async function startup() {
await init();
run();
}
await startup()
</script>
</body>

</html>
4 changes: 0 additions & 4 deletions core/src/animation/stagger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,6 @@
//! };
//! ```
// fixme: rxRust not use std::time::Instant in web
#[cfg(target_family = "wasm")]
use std::time::Instant;

use ribir_algo::Sc;
use ribir_macros::rdl;

Expand Down
8 changes: 8 additions & 0 deletions examples/counter/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,11 @@ ribir_dev_helper = {path = "../../dev-helper"}

[features]
wgpu = ["ribir/wgpu"]

[target.'cfg(target_arch = "wasm32")'.dependencies]
wasm-bindgen = "0.2.92"

[lib]
crate-type = ["cdylib", "rlib"]
path = "src/lib.rs"

4 changes: 4 additions & 0 deletions examples/counter/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,7 @@ You can run with:
``` sh
cargo run -p counter
```
or run in web:
``` sh
cargo run-wasm -p counter
```
9 changes: 9 additions & 0 deletions examples/counter/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,11 @@
mod counter;
pub use counter::counter;
use ribir::prelude::*;

#[cfg_attr(target_arch = "wasm32", wasm_bindgen::prelude::wasm_bindgen)]
pub fn run() {
App::run(counter())
.with_app_theme(material::purple::light())
.with_size(Size::new(300., 150.))
.with_title("Counter ribir");
}
22 changes: 12 additions & 10 deletions examples/counter/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
mod counter;
use counter::counter;
use ribir::prelude::*;
use counter::run;

fn main() { run(); }

fn main() {
App::run(counter())
.with_title("Counter")
.with_app_theme(material::purple::light());
}
#[cfg_attr(target_arch = "wasm32", wasm_bindgen::prelude::wasm_bindgen)]
pub fn bin() {}

#[cfg(test)]
use ribir::core::test_helper::*;
use counter::counter;
#[cfg(test)]
use ribir::material as ribir_material;
use ribir::{
core::test_helper::*,
material as ribir_material,
prelude::{AppCtx, Size},
};
#[cfg(test)]
use ribir_dev_helper::*;

#[cfg(test)]
widget_image_test!(counter, wnd_size = Size::new(400., 600.), comparison = 0.001);
10 changes: 10 additions & 0 deletions examples/messages/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,13 @@ ribir_dev_helper = {path = "../../dev-helper"}

[features]
wgpu = ["ribir/wgpu"]

[target.'cfg(target_arch = "wasm32")'.dependencies]
wasm-bindgen = "0.2.92"

[lib]
crate-type = ["cdylib", "rlib"]
path = "src/lib.rs"

[package.metadata.wasm-pack.profile.release]
wasm-opt = false
5 changes: 5 additions & 0 deletions examples/messages/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,8 @@ You can run with:
``` sh
cargo run -p messages
```

or run in web:
``` sh
cargo run-wasm -p messages
```
9 changes: 9 additions & 0 deletions examples/messages/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,11 @@
mod messages;
pub use messages::messages;
use ribir::prelude::*;

#[cfg_attr(target_arch = "wasm32", wasm_bindgen::prelude::wasm_bindgen)]
pub fn run() {
App::run(messages())
.with_app_theme(material::purple::light())
.with_size(Size::new(400., 600.))
.with_title("Messages");
}
Loading

0 comments on commit 9892ae9

Please sign in to comment.