Skip to content

Commit ff89968

Browse files
authored
example showcase - pagination and can build for WebGL2 (#9168)
# Objective - Building all examples at once in CI takes too long - Tool can only build for WebGPU ## Solution - Add pagination to commands - Add option to build examples for WebGL2 - Add option to build Zola files for WebGL2
1 parent 9ad546e commit ff89968

File tree

2 files changed

+118
-31
lines changed

2 files changed

+118
-31
lines changed

tools/build-wasm-example/src/main.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use clap::{Parser, ValueEnum};
44
use xshell::{cmd, Shell};
55

66
#[derive(Debug, Copy, Clone, ValueEnum)]
7-
enum Api {
7+
enum WebApi {
88
Webgl2,
99
Webgpu,
1010
}
@@ -26,9 +26,9 @@ struct Args {
2626
/// Stop after this number of frames
2727
frames: Option<usize>,
2828

29-
#[arg(value_enum, short, long, default_value_t = Api::Webgl2)]
29+
#[arg(value_enum, short, long, default_value_t = WebApi::Webgl2)]
3030
/// Browser API to use for rendering
31-
api: Api,
31+
api: WebApi,
3232

3333
#[arg(short, long)]
3434
/// Optimize the wasm file for size with wasm-opt
@@ -50,8 +50,8 @@ fn main() {
5050
}
5151

5252
match cli.api {
53-
Api::Webgl2 => (),
54-
Api::Webgpu => {
53+
WebApi::Webgl2 => (),
54+
WebApi::Webgpu => {
5555
features.push("animation");
5656
features.push("bevy_asset");
5757
features.push("bevy_audio");
@@ -95,7 +95,7 @@ fn main() {
9595
sh,
9696
"cargo build {parameters...} --profile release --target wasm32-unknown-unknown --example {example}"
9797
);
98-
if matches!(cli.api, Api::Webgpu) {
98+
if matches!(cli.api, WebApi::Webgpu) {
9999
cmd = cmd.env("RUSTFLAGS", "--cfg=web_sys_unstable_apis");
100100
}
101101
cmd.run().expect("Error building example");

tools/example-showcase/src/main.rs

Lines changed: 112 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use std::{
22
collections::HashMap,
3+
fmt::Display,
34
fs::{self, File},
45
io::Write,
56
path::{Path, PathBuf},
@@ -8,7 +9,7 @@ use std::{
89
time::{Duration, Instant},
910
};
1011

11-
use clap::Parser;
12+
use clap::{error::ErrorKind, CommandFactory, Parser, ValueEnum};
1213
use pbr::ProgressBar;
1314
use toml_edit::Document;
1415
use xshell::{cmd, Shell};
@@ -21,6 +22,13 @@ struct Args {
2122

2223
#[command(subcommand)]
2324
action: Action,
25+
#[arg(long)]
26+
/// Pagination control - page number. To use with --per-page
27+
page: Option<usize>,
28+
29+
#[arg(long)]
30+
/// Pagination control - number of examples per page. To use with --page
31+
per_page: Option<usize>,
2432
}
2533

2634
#[derive(clap::Subcommand, Debug)]
@@ -44,9 +52,13 @@ enum Action {
4452
#[arg(long)]
4553
/// Path to the folder where the content should be created
4654
content_folder: String,
55+
56+
#[arg(value_enum, long, default_value_t = WebApi::Webgl2)]
57+
/// Which API to use for rendering
58+
api: WebApi,
4759
},
48-
/// BUild the examples in wasm / WebGPU
49-
BuildWebGPUExamples {
60+
/// Build the examples in wasm
61+
BuildWasmExamples {
5062
#[arg(long)]
5163
/// Path to the folder where the content should be created
5264
content_folder: String,
@@ -58,12 +70,40 @@ enum Action {
5870
#[arg(long)]
5971
/// Optimize the wasm file for size with wasm-opt
6072
optimize_size: bool,
73+
74+
#[arg(value_enum, long)]
75+
/// Which API to use for rendering
76+
api: WebApi,
6177
},
6278
}
6379

80+
#[derive(Debug, Copy, Clone, ValueEnum)]
81+
enum WebApi {
82+
Webgl2,
83+
Webgpu,
84+
}
85+
86+
impl Display for WebApi {
87+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
88+
match self {
89+
WebApi::Webgl2 => write!(f, "webgl2"),
90+
WebApi::Webgpu => write!(f, "webgpu"),
91+
}
92+
}
93+
}
94+
6495
fn main() {
6596
let cli = Args::parse();
6697

98+
if cli.page.is_none() != cli.per_page.is_none() {
99+
let mut cmd = Args::command();
100+
cmd.error(
101+
ErrorKind::MissingRequiredArgument,
102+
"page and per-page must be used together",
103+
)
104+
.exit();
105+
}
106+
67107
let profile = cli.profile;
68108

69109
match cli.action {
@@ -106,7 +146,16 @@ fn main() {
106146
}
107147
}
108148

109-
for to_run in examples_to_run {
149+
let work_to_do = || {
150+
examples_to_run
151+
.iter()
152+
.skip(cli.page.unwrap_or(0) * cli.per_page.unwrap_or(0))
153+
.take(cli.per_page.unwrap_or(usize::MAX))
154+
};
155+
156+
let mut pb = ProgressBar::new(work_to_do().count() as u64);
157+
158+
for to_run in work_to_do() {
110159
let sh = Shell::new().unwrap();
111160
let example = &to_run.technical_name;
112161
let extra_parameters = extra_parameters.clone();
@@ -143,7 +192,9 @@ fn main() {
143192
println!("took {duration:?}");
144193

145194
thread::sleep(Duration::from_secs(1));
195+
pb.inc();
146196
}
197+
pb.finish_print("done");
147198
if failed_examples.is_empty() {
148199
println!("All examples passed!");
149200
} else {
@@ -157,27 +208,46 @@ fn main() {
157208
exit(1);
158209
}
159210
}
160-
Action::BuildWebsiteList { content_folder } => {
211+
Action::BuildWebsiteList {
212+
content_folder,
213+
api,
214+
} => {
161215
let examples_to_run = parse_examples();
162216

163217
let root_path = Path::new(&content_folder);
164218

165219
let _ = fs::create_dir_all(root_path);
166220

167221
let mut index = File::create(root_path.join("_index.md")).unwrap();
168-
index
169-
.write_all(
170-
"+++
222+
if matches!(api, WebApi::Webgpu) {
223+
index
224+
.write_all(
225+
"+++
171226
title = \"Bevy Examples in WebGPU\"
172227
template = \"examples-webgpu.html\"
173228
sort_by = \"weight\"
174229
175230
[extra]
176231
header_message = \"Examples (WebGPU)\"
177232
+++"
178-
.as_bytes(),
179-
)
180-
.unwrap();
233+
.as_bytes(),
234+
)
235+
.unwrap();
236+
} else {
237+
index
238+
.write_all(
239+
"+++
240+
title = \"Bevy Examples in WebGL2\"
241+
template = \"examples.html\"
242+
sort_by = \"weight\"
243+
244+
[extra]
245+
header_message = \"Examples (WebGL2)\"
246+
+++"
247+
.as_bytes(),
248+
)
249+
.unwrap();
250+
}
181251

182252
let mut categories = HashMap::new();
183253
for to_show in examples_to_run {
@@ -217,43 +287,61 @@ weight = {}
217287
format!(
218288
"+++
219289
title = \"{}\"
220-
template = \"example-webgpu.html\"
290+
template = \"example{}.html\"
221291
weight = {}
222292
description = \"{}\"
223293
224294
[extra]
225295
technical_name = \"{}\"
226-
link = \"{}/{}\"
296+
link = \"/examples{}/{}/{}\"
227297
image = \"../static/screenshots/{}/{}.png\"
228-
code_path = \"content/examples-webgpu/{}\"
298+
code_path = \"content/examples{}/{}\"
229299
github_code_path = \"{}\"
230-
header_message = \"Examples (WebGPU)\"
300+
header_message = \"Examples ({})\"
231301
+++",
232302
to_show.name,
303+
match api {
304+
WebApi::Webgpu => "-webgpu",
305+
WebApi::Webgl2 => "",
306+
},
233307
categories.get(&to_show.category).unwrap(),
234308
to_show.description.replace('"', "'"),
235309
&to_show.technical_name.replace('_', "-"),
310+
match api {
311+
WebApi::Webgpu => "-webgpu",
312+
WebApi::Webgl2 => "",
313+
},
236314
&to_show.category,
237315
&to_show.technical_name.replace('_', "-"),
238316
&to_show.category,
239317
&to_show.technical_name,
318+
match api {
319+
WebApi::Webgpu => "-webgpu",
320+
WebApi::Webgl2 => "",
321+
},
240322
code_path
241323
.components()
242324
.skip(1)
243325
.collect::<PathBuf>()
244326
.display(),
245327
&to_show.path,
328+
match api {
329+
WebApi::Webgpu => "WebGPU",
330+
WebApi::Webgl2 => "WebGL2",
331+
},
246332
)
247333
.as_bytes(),
248334
)
249335
.unwrap();
250336
}
251337
}
252-
Action::BuildWebGPUExamples {
338+
Action::BuildWasmExamples {
253339
content_folder,
254340
website_hacks,
255341
optimize_size,
342+
api,
256343
} => {
344+
let api = format!("{}", api);
257345
let examples_to_build = parse_examples();
258346

259347
let root_path = Path::new(&content_folder);
@@ -282,30 +370,29 @@ header_message = \"Examples (WebGPU)\"
282370
cmd!(sh, "sed -i.bak 's/asset_folder: \"assets\"/asset_folder: \"\\/assets\\/examples\\/\"/' crates/bevy_asset/src/lib.rs").run().unwrap();
283371
}
284372

285-
let mut pb = ProgressBar::new(
373+
let work_to_do = || {
286374
examples_to_build
287375
.iter()
288376
.filter(|to_build| to_build.wasm)
289-
.count() as u64,
290-
);
291-
for to_build in examples_to_build {
292-
if !to_build.wasm {
293-
continue;
294-
}
377+
.skip(cli.page.unwrap_or(0) * cli.per_page.unwrap_or(0))
378+
.take(cli.per_page.unwrap_or(usize::MAX))
379+
};
295380

381+
let mut pb = ProgressBar::new(work_to_do().count() as u64);
382+
for to_build in work_to_do() {
296383
let sh = Shell::new().unwrap();
297384
let example = &to_build.technical_name;
298385
if optimize_size {
299386
cmd!(
300387
sh,
301-
"cargo run -p build-wasm-example -- --api webgpu {example} --optimize-size"
388+
"cargo run -p build-wasm-example -- --api {api} {example} --optimize-size"
302389
)
303390
.run()
304391
.unwrap();
305392
} else {
306393
cmd!(
307394
sh,
308-
"cargo run -p build-wasm-example -- --api webgpu {example}"
395+
"cargo run -p build-wasm-example -- --api {api} {example}"
309396
)
310397
.run()
311398
.unwrap();

0 commit comments

Comments
 (0)