1
1
use std:: {
2
2
collections:: HashMap ,
3
+ fmt:: Display ,
3
4
fs:: { self , File } ,
4
5
io:: Write ,
5
6
path:: { Path , PathBuf } ,
@@ -8,7 +9,7 @@ use std::{
8
9
time:: { Duration , Instant } ,
9
10
} ;
10
11
11
- use clap:: Parser ;
12
+ use clap:: { error :: ErrorKind , CommandFactory , Parser , ValueEnum } ;
12
13
use pbr:: ProgressBar ;
13
14
use toml_edit:: Document ;
14
15
use xshell:: { cmd, Shell } ;
@@ -21,6 +22,13 @@ struct Args {
21
22
22
23
#[ command( subcommand) ]
23
24
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 > ,
24
32
}
25
33
26
34
#[ derive( clap:: Subcommand , Debug ) ]
@@ -44,9 +52,13 @@ enum Action {
44
52
#[ arg( long) ]
45
53
/// Path to the folder where the content should be created
46
54
content_folder : String ,
55
+
56
+ #[ arg( value_enum, long, default_value_t = WebApi :: Webgl2 ) ]
57
+ /// Which API to use for rendering
58
+ api : WebApi ,
47
59
} ,
48
- /// BUild the examples in wasm / WebGPU
49
- BuildWebGPUExamples {
60
+ /// Build the examples in wasm
61
+ BuildWasmExamples {
50
62
#[ arg( long) ]
51
63
/// Path to the folder where the content should be created
52
64
content_folder : String ,
@@ -58,12 +70,40 @@ enum Action {
58
70
#[ arg( long) ]
59
71
/// Optimize the wasm file for size with wasm-opt
60
72
optimize_size : bool ,
73
+
74
+ #[ arg( value_enum, long) ]
75
+ /// Which API to use for rendering
76
+ api : WebApi ,
61
77
} ,
62
78
}
63
79
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
+
64
95
fn main ( ) {
65
96
let cli = Args :: parse ( ) ;
66
97
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
+
67
107
let profile = cli. profile ;
68
108
69
109
match cli. action {
@@ -106,7 +146,16 @@ fn main() {
106
146
}
107
147
}
108
148
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 ( ) {
110
159
let sh = Shell :: new ( ) . unwrap ( ) ;
111
160
let example = & to_run. technical_name ;
112
161
let extra_parameters = extra_parameters. clone ( ) ;
@@ -143,7 +192,9 @@ fn main() {
143
192
println ! ( "took {duration:?}" ) ;
144
193
145
194
thread:: sleep ( Duration :: from_secs ( 1 ) ) ;
195
+ pb. inc ( ) ;
146
196
}
197
+ pb. finish_print ( "done" ) ;
147
198
if failed_examples. is_empty ( ) {
148
199
println ! ( "All examples passed!" ) ;
149
200
} else {
@@ -157,27 +208,46 @@ fn main() {
157
208
exit ( 1 ) ;
158
209
}
159
210
}
160
- Action :: BuildWebsiteList { content_folder } => {
211
+ Action :: BuildWebsiteList {
212
+ content_folder,
213
+ api,
214
+ } => {
161
215
let examples_to_run = parse_examples ( ) ;
162
216
163
217
let root_path = Path :: new ( & content_folder) ;
164
218
165
219
let _ = fs:: create_dir_all ( root_path) ;
166
220
167
221
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
+ "+++
171
226
title = \" Bevy Examples in WebGPU\"
172
227
template = \" examples-webgpu.html\"
173
228
sort_by = \" weight\"
174
229
175
230
[extra]
176
231
header_message = \" Examples (WebGPU)\"
177
232
+++"
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
+ }
181
251
182
252
let mut categories = HashMap :: new ( ) ;
183
253
for to_show in examples_to_run {
@@ -217,43 +287,61 @@ weight = {}
217
287
format ! (
218
288
"+++
219
289
title = \" {}\"
220
- template = \" example-webgpu .html\"
290
+ template = \" example{} .html\"
221
291
weight = {}
222
292
description = \" {}\"
223
293
224
294
[extra]
225
295
technical_name = \" {}\"
226
- link = \" {}/{}\"
296
+ link = \" /examples{}/ {}/{}\"
227
297
image = \" ../static/screenshots/{}/{}.png\"
228
- code_path = \" content/examples-webgpu /{}\"
298
+ code_path = \" content/examples{} /{}\"
229
299
github_code_path = \" {}\"
230
- header_message = \" Examples (WebGPU )\"
300
+ header_message = \" Examples ({} )\"
231
301
+++" ,
232
302
to_show. name,
303
+ match api {
304
+ WebApi :: Webgpu => "-webgpu" ,
305
+ WebApi :: Webgl2 => "" ,
306
+ } ,
233
307
categories. get( & to_show. category) . unwrap( ) ,
234
308
to_show. description. replace( '"' , "'" ) ,
235
309
& to_show. technical_name. replace( '_' , "-" ) ,
310
+ match api {
311
+ WebApi :: Webgpu => "-webgpu" ,
312
+ WebApi :: Webgl2 => "" ,
313
+ } ,
236
314
& to_show. category,
237
315
& to_show. technical_name. replace( '_' , "-" ) ,
238
316
& to_show. category,
239
317
& to_show. technical_name,
318
+ match api {
319
+ WebApi :: Webgpu => "-webgpu" ,
320
+ WebApi :: Webgl2 => "" ,
321
+ } ,
240
322
code_path
241
323
. components( )
242
324
. skip( 1 )
243
325
. collect:: <PathBuf >( )
244
326
. display( ) ,
245
327
& to_show. path,
328
+ match api {
329
+ WebApi :: Webgpu => "WebGPU" ,
330
+ WebApi :: Webgl2 => "WebGL2" ,
331
+ } ,
246
332
)
247
333
. as_bytes ( ) ,
248
334
)
249
335
. unwrap ( ) ;
250
336
}
251
337
}
252
- Action :: BuildWebGPUExamples {
338
+ Action :: BuildWasmExamples {
253
339
content_folder,
254
340
website_hacks,
255
341
optimize_size,
342
+ api,
256
343
} => {
344
+ let api = format ! ( "{}" , api) ;
257
345
let examples_to_build = parse_examples ( ) ;
258
346
259
347
let root_path = Path :: new ( & content_folder) ;
@@ -282,30 +370,29 @@ header_message = \"Examples (WebGPU)\"
282
370
cmd ! ( sh, "sed -i.bak 's/asset_folder: \" assets\" /asset_folder: \" \\ /assets\\ /examples\\ /\" /' crates/bevy_asset/src/lib.rs" ) . run ( ) . unwrap ( ) ;
283
371
}
284
372
285
- let mut pb = ProgressBar :: new (
373
+ let work_to_do = || {
286
374
examples_to_build
287
375
. iter ( )
288
376
. 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
+ } ;
295
380
381
+ let mut pb = ProgressBar :: new ( work_to_do ( ) . count ( ) as u64 ) ;
382
+ for to_build in work_to_do ( ) {
296
383
let sh = Shell :: new ( ) . unwrap ( ) ;
297
384
let example = & to_build. technical_name ;
298
385
if optimize_size {
299
386
cmd ! (
300
387
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"
302
389
)
303
390
. run ( )
304
391
. unwrap ( ) ;
305
392
} else {
306
393
cmd ! (
307
394
sh,
308
- "cargo run -p build-wasm-example -- --api webgpu {example}"
395
+ "cargo run -p build-wasm-example -- --api {api} {example}"
309
396
)
310
397
. run ( )
311
398
. unwrap ( ) ;
0 commit comments