Skip to content

Commit 19ea3c9

Browse files
committed
fixes + docs
1 parent 367e38b commit 19ea3c9

File tree

9 files changed

+184
-140
lines changed

9 files changed

+184
-140
lines changed

assets/tests/add_system/added_systems_run_in_parallel.lua

Lines changed: 35 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -33,29 +33,43 @@ digraph {
3333
node_8 [label="bevy_mod_scripting_core::pipeline::start::filter_script_attachments<bevy_mod_scripting_lua::LuaScriptingPlugin>"];
3434
node_9 [label="bevy_mod_scripting_core::pipeline::start::filter_script_detachments<bevy_mod_scripting_lua::LuaScriptingPlugin>"];
3535
node_10 [label="bevy_mod_scripting_core::pipeline::start::filter_script_modifications<bevy_mod_scripting_lua::LuaScriptingPlugin>"];
36-
node_11 [label="bevy_mod_scripting_core::pipeline::automatic_pipeline_runner<bevy_mod_scripting_lua::LuaScriptingPlugin>"];
37-
node_12 [label="on_test_post_update"];
38-
node_13 [label="custom_system_a"];
39-
node_14 [label="custom_system_b"];
40-
node_15 [label="SystemSet AssetEvents"];
41-
node_16 [label="SystemSet GarbageCollection"];
42-
node_17 [label="SystemSet InitializePhase"];
43-
node_18 [label="SystemSet ScriptSystem(custom_system_a)"];
44-
node_19 [label="SystemSet ScriptSystem(custom_system_b)"];
45-
node_0 -> node_15 [color=red, label="child of", arrowhead=diamond];
46-
node_1 -> node_15 [color=red, label="child of", arrowhead=diamond];
47-
node_2 -> node_15 [color=red, label="child of", arrowhead=diamond];
48-
node_3 -> node_15 [color=red, label="child of", arrowhead=diamond];
49-
node_4 -> node_16 [color=red, label="child of", arrowhead=diamond];
50-
node_13 -> node_18 [color=red, label="child of", arrowhead=diamond];
51-
node_14 -> node_19 [color=red, label="child of", arrowhead=diamond];
36+
node_11 [label="bevy_mod_scripting_core::pipeline::start::process_attachments<bevy_mod_scripting_lua::LuaScriptingPlugin>"];
37+
node_12 [label="bevy_mod_scripting_core::pipeline::start::process_detachments<bevy_mod_scripting_lua::LuaScriptingPlugin>"];
38+
node_13 [label="bevy_mod_scripting_core::pipeline::start::process_asset_modifications<bevy_mod_scripting_lua::LuaScriptingPlugin>"];
39+
node_14 [label="bevy_mod_scripting_core::pipeline::automatic_pipeline_runner<bevy_mod_scripting_lua::LuaScriptingPlugin>"];
40+
node_15 [label="on_test_post_update"];
41+
node_16 [label="custom_system_a"];
42+
node_17 [label="custom_system_b"];
43+
node_18 [label="SystemSet AssetEvents"];
44+
node_19 [label="SystemSet GarbageCollection"];
45+
node_20 [label="SystemSet ListeningPhase"];
46+
node_21 [label="SystemSet MachineStartPhase"];
47+
node_22 [label="SystemSet ScriptSystem(custom_system_a)"];
48+
node_23 [label="SystemSet ScriptSystem(custom_system_b)"];
49+
node_0 -> node_18 [color=red, label="child of", arrowhead=diamond];
50+
node_1 -> node_18 [color=red, label="child of", arrowhead=diamond];
51+
node_2 -> node_18 [color=red, label="child of", arrowhead=diamond];
52+
node_3 -> node_18 [color=red, label="child of", arrowhead=diamond];
53+
node_4 -> node_19 [color=red, label="child of", arrowhead=diamond];
54+
node_8 -> node_20 [color=red, label="child of", arrowhead=diamond];
55+
node_9 -> node_20 [color=red, label="child of", arrowhead=diamond];
56+
node_10 -> node_20 [color=red, label="child of", arrowhead=diamond];
57+
node_11 -> node_21 [color=red, label="child of", arrowhead=diamond];
58+
node_12 -> node_21 [color=red, label="child of", arrowhead=diamond];
59+
node_13 -> node_21 [color=red, label="child of", arrowhead=diamond];
60+
node_16 -> node_22 [color=red, label="child of", arrowhead=diamond];
61+
node_17 -> node_23 [color=red, label="child of", arrowhead=diamond];
5262
node_6 -> node_7 [color=blue, label="runs before", arrowhead=normal];
53-
node_8 -> node_17 [color=blue, label="runs before", arrowhead=normal];
54-
node_9 -> node_17 [color=blue, label="runs before", arrowhead=normal];
55-
node_10 -> node_17 [color=blue, label="runs before", arrowhead=normal];
63+
node_8 -> node_9 [color=blue, label="runs before", arrowhead=normal];
64+
node_8 -> node_9 [color=blue, label="runs before", arrowhead=normal];
65+
node_8 -> node_10 [color=blue, label="runs before", arrowhead=normal];
66+
node_9 -> node_10 [color=blue, label="runs before", arrowhead=normal];
67+
node_11 -> node_12 [color=blue, label="runs before", arrowhead=normal];
5668
node_12 -> node_13 [color=blue, label="runs before", arrowhead=normal];
57-
node_12 -> node_14 [color=blue, label="runs before", arrowhead=normal];
58-
node_17 -> node_11 [color=blue, label="runs before", arrowhead=normal];
69+
node_15 -> node_16 [color=blue, label="runs before", arrowhead=normal];
70+
node_15 -> node_17 [color=blue, label="runs before", arrowhead=normal];
71+
node_20 -> node_21 [color=blue, label="runs before", arrowhead=normal];
72+
node_21 -> node_14 [color=blue, label="runs before", arrowhead=normal];
5973
}
6074
]]
6175
assert_str_eq(dot_graph, expected_dot_graph, "Expected the schedule graph to match the expected graph")

assets/tests/add_system/added_systems_run_in_parallel.rhai

Lines changed: 35 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -32,29 +32,43 @@ digraph {
3232
node_8 [label="bevy_mod_scripting_core::pipeline::start::filter_script_attachments<bevy_mod_scripting_rhai::RhaiScriptingPlugin>"];
3333
node_9 [label="bevy_mod_scripting_core::pipeline::start::filter_script_detachments<bevy_mod_scripting_rhai::RhaiScriptingPlugin>"];
3434
node_10 [label="bevy_mod_scripting_core::pipeline::start::filter_script_modifications<bevy_mod_scripting_rhai::RhaiScriptingPlugin>"];
35-
node_11 [label="bevy_mod_scripting_core::pipeline::automatic_pipeline_runner<bevy_mod_scripting_rhai::RhaiScriptingPlugin>"];
36-
node_12 [label="on_test_post_update"];
37-
node_13 [label="custom_system_a"];
38-
node_14 [label="custom_system_b"];
39-
node_15 [label="SystemSet AssetEvents"];
40-
node_16 [label="SystemSet GarbageCollection"];
41-
node_17 [label="SystemSet InitializePhase"];
42-
node_18 [label="SystemSet ScriptSystem(custom_system_a)"];
43-
node_19 [label="SystemSet ScriptSystem(custom_system_b)"];
44-
node_0 -> node_15 [color=red, label="child of", arrowhead=diamond];
45-
node_1 -> node_15 [color=red, label="child of", arrowhead=diamond];
46-
node_2 -> node_15 [color=red, label="child of", arrowhead=diamond];
47-
node_3 -> node_15 [color=red, label="child of", arrowhead=diamond];
48-
node_4 -> node_16 [color=red, label="child of", arrowhead=diamond];
49-
node_13 -> node_18 [color=red, label="child of", arrowhead=diamond];
50-
node_14 -> node_19 [color=red, label="child of", arrowhead=diamond];
35+
node_11 [label="bevy_mod_scripting_core::pipeline::start::process_attachments<bevy_mod_scripting_rhai::RhaiScriptingPlugin>"];
36+
node_12 [label="bevy_mod_scripting_core::pipeline::start::process_detachments<bevy_mod_scripting_rhai::RhaiScriptingPlugin>"];
37+
node_13 [label="bevy_mod_scripting_core::pipeline::start::process_asset_modifications<bevy_mod_scripting_rhai::RhaiScriptingPlugin>"];
38+
node_14 [label="bevy_mod_scripting_core::pipeline::automatic_pipeline_runner<bevy_mod_scripting_rhai::RhaiScriptingPlugin>"];
39+
node_15 [label="on_test_post_update"];
40+
node_16 [label="custom_system_a"];
41+
node_17 [label="custom_system_b"];
42+
node_18 [label="SystemSet AssetEvents"];
43+
node_19 [label="SystemSet GarbageCollection"];
44+
node_20 [label="SystemSet ListeningPhase"];
45+
node_21 [label="SystemSet MachineStartPhase"];
46+
node_22 [label="SystemSet ScriptSystem(custom_system_a)"];
47+
node_23 [label="SystemSet ScriptSystem(custom_system_b)"];
48+
node_0 -> node_18 [color=red, label="child of", arrowhead=diamond];
49+
node_1 -> node_18 [color=red, label="child of", arrowhead=diamond];
50+
node_2 -> node_18 [color=red, label="child of", arrowhead=diamond];
51+
node_3 -> node_18 [color=red, label="child of", arrowhead=diamond];
52+
node_4 -> node_19 [color=red, label="child of", arrowhead=diamond];
53+
node_8 -> node_20 [color=red, label="child of", arrowhead=diamond];
54+
node_9 -> node_20 [color=red, label="child of", arrowhead=diamond];
55+
node_10 -> node_20 [color=red, label="child of", arrowhead=diamond];
56+
node_11 -> node_21 [color=red, label="child of", arrowhead=diamond];
57+
node_12 -> node_21 [color=red, label="child of", arrowhead=diamond];
58+
node_13 -> node_21 [color=red, label="child of", arrowhead=diamond];
59+
node_16 -> node_22 [color=red, label="child of", arrowhead=diamond];
60+
node_17 -> node_23 [color=red, label="child of", arrowhead=diamond];
5161
node_6 -> node_7 [color=blue, label="runs before", arrowhead=normal];
52-
node_8 -> node_17 [color=blue, label="runs before", arrowhead=normal];
53-
node_9 -> node_17 [color=blue, label="runs before", arrowhead=normal];
54-
node_10 -> node_17 [color=blue, label="runs before", arrowhead=normal];
62+
node_8 -> node_9 [color=blue, label="runs before", arrowhead=normal];
63+
node_8 -> node_9 [color=blue, label="runs before", arrowhead=normal];
64+
node_8 -> node_10 [color=blue, label="runs before", arrowhead=normal];
65+
node_9 -> node_10 [color=blue, label="runs before", arrowhead=normal];
66+
node_11 -> node_12 [color=blue, label="runs before", arrowhead=normal];
5567
node_12 -> node_13 [color=blue, label="runs before", arrowhead=normal];
56-
node_12 -> node_14 [color=blue, label="runs before", arrowhead=normal];
57-
node_17 -> node_11 [color=blue, label="runs before", arrowhead=normal];
68+
node_15 -> node_16 [color=blue, label="runs before", arrowhead=normal];
69+
node_15 -> node_17 [color=blue, label="runs before", arrowhead=normal];
70+
node_20 -> node_21 [color=blue, label="runs before", arrowhead=normal];
71+
node_21 -> node_14 [color=blue, label="runs before", arrowhead=normal];
5872
}`;
5973

6074
assert_str_eq.call(dot_graph, expected_dot_graph, "Expected the schedule graph to match the expected graph");

crates/bevy_mod_scripting_core/src/pipeline/mod.rs

Lines changed: 35 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,10 @@ pub use {machines::*, start::*};
4040
#[derive(SystemSet, Hash, Debug, Clone, Copy, PartialEq, Eq)]
4141
/// System sets allowing for placing hooks at different stages in the loading/unloading process
4242
pub enum PipelineSet {
43-
/// During this phase, various systems listen for
44-
InitializePhase,
45-
/// The phase during which we tick all state machines
46-
TickMachinesPhase,
43+
/// During this phase, various systems listen for events and filter through them to match what the pipeline expects
44+
ListeningPhase,
45+
/// During this phase we convert the filtered events to new machines
46+
MachineStartPhase,
4747
}
4848

4949
/// A pipeline plugin which enables the loading and unloading of scripts in a highly modular way
@@ -214,45 +214,55 @@ impl<P: IntoScriptPluginParams> Plugin for ScriptLoadingPipeline<P> {
214214

215215
active_machines.budget = self.time_budget;
216216

217-
app.init_resource::<RequestProcessingPipelineRun<P>>();
217+
app.configure_sets(
218+
PostUpdate,
219+
PipelineSet::ListeningPhase.before(PipelineSet::MachineStartPhase),
220+
);
218221

222+
// todo: nicer way to order these, ideall .chain() + conditional newtype?
219223
if self.script_component_triggers {
220224
app.add_systems(
221225
PostUpdate,
222-
(
223-
filter_script_attachments::<P>,
224-
filter_script_detachments::<P>,
225-
)
226-
.before(PipelineSet::InitializePhase),
226+
filter_script_attachments::<P>
227+
.in_set(PipelineSet::ListeningPhase)
228+
.before(filter_script_modifications::<P>)
229+
.before(filter_script_detachments::<P>),
230+
);
231+
app.add_systems(
232+
PostUpdate,
233+
filter_script_detachments::<P>
234+
.in_set(PipelineSet::ListeningPhase)
235+
.after(filter_script_attachments::<P>)
236+
.before(filter_script_modifications::<P>),
227237
);
228238
}
229239

230240
if self.hot_loading_asset_triggers {
231241
app.add_systems(
232242
PostUpdate,
233-
(filter_script_modifications::<P>,).before(PipelineSet::InitializePhase),
243+
filter_script_modifications::<P>.in_set(PipelineSet::ListeningPhase),
234244
);
235245
}
236246

237247
app.add_systems(
238248
PostUpdate,
239-
automatic_pipeline_runner::<P>.after(PipelineSet::InitializePhase),
240-
);
241-
242-
let mut schedule = Schedule::new(ScriptProcessingSchedule::<P>(Default::default()));
243-
schedule
244-
.configure_sets(PipelineSet::InitializePhase.before(PipelineSet::TickMachinesPhase));
245-
246-
schedule.add_systems(
247249
(
248250
process_attachments::<P>,
249251
process_detachments::<P>,
250252
process_asset_modifications::<P>,
251253
)
252-
.in_set(PipelineSet::InitializePhase),
254+
.chain()
255+
.in_set(PipelineSet::MachineStartPhase),
253256
);
254257

255-
schedule.add_systems((machine_ticker::<P>).in_set(PipelineSet::TickMachinesPhase));
258+
app.add_systems(
259+
PostUpdate,
260+
automatic_pipeline_runner::<P>.after(PipelineSet::MachineStartPhase),
261+
);
262+
263+
let mut schedule = Schedule::new(ScriptProcessingSchedule::<P>(Default::default()));
264+
265+
schedule.add_systems(machine_ticker::<P>);
256266

257267
app.add_schedule(schedule);
258268
}
@@ -305,43 +315,11 @@ impl<P: IntoScriptPluginParams> Command for RunProcessingPipelineOnce<P> {
305315
}
306316
}
307317

308-
#[derive(Resource)]
309-
/// A resource marker used to notify the processing pipeline to run
310-
pub struct RequestProcessingPipelineRun<P>(PhantomData<fn(P)>, bool);
311-
312-
impl<P> RequestProcessingPipelineRun<P> {
313-
/// Creates a default [`RequestProcessingPipelineRun`] for the plugi
314-
pub fn new() -> Self {
315-
Self(Default::default(), false)
316-
}
317-
318-
/// Returns true if a processing pipeline run was requested, and sets the flag to false again.
319-
pub fn get_and_unset(&mut self) -> bool {
320-
let requested = self.1;
321-
self.1 = false;
322-
requested
323-
}
324-
325-
/// requests a run this frame
326-
pub fn request_run(&mut self) {
327-
self.1 = true;
328-
}
329-
}
330-
331-
impl<P> Default for RequestProcessingPipelineRun<P> {
332-
fn default() -> Self {
333-
Self::new()
334-
}
335-
}
336-
337-
/// A system which runs [`RunProcessingPipelineOnce`] command for the plugin only if [`RequestProcessingPipelineRun`] resource had [`RequestProcessingPipelineRun::request_run`] called on it,
338-
/// and or if there are active machines
318+
/// A system which runs [`RunProcessingPipelineOnce`] command for the plugin only if there are active machines
339319
pub fn automatic_pipeline_runner<P: IntoScriptPluginParams>(world: &mut World) {
340-
let mut res = world.get_resource_or_init::<RequestProcessingPipelineRun<P>>();
341-
if res.get_and_unset()
342-
|| world
343-
.get_resource::<ActiveMachines<P>>()
344-
.is_some_and(|machines| machines.active_machines() > 0)
320+
if world
321+
.get_resource::<ActiveMachines<P>>()
322+
.is_some_and(|machines| machines.active_machines() > 0)
345323
{
346324
RunProcessingPipelineOnce::<P>::new(None).apply(world);
347325
}

crates/bevy_mod_scripting_core/src/pipeline/start.rs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ pub fn filter_script_modifications<P: IntoScriptPluginParams>(
6262
mut events: EventReader<AssetEvent<ScriptAsset>>,
6363
mut filtered: EventWriter<ForPlugin<ScriptAssetModifiedEvent, P>>,
6464
assets: Res<Assets<ScriptAsset>>,
65-
mut requests: ResMut<RequestProcessingPipelineRun<P>>,
6665
) {
6766
let mut batch = events.read().filter_map(|e| {
6867
if let AssetEvent::Modified { id } = e
@@ -76,7 +75,6 @@ pub fn filter_script_modifications<P: IntoScriptPluginParams>(
7675
});
7776

7877
if let Some(next) = batch.next() {
79-
requests.request_run();
8078
filtered.write_batch(std::iter::once(next).chain(batch));
8179
}
8280
}
@@ -85,15 +83,13 @@ pub fn filter_script_modifications<P: IntoScriptPluginParams>(
8583
pub fn filter_script_attachments<P: IntoScriptPluginParams>(
8684
mut events: LoadedWithHandles<ScriptAttachedEvent>,
8785
mut filtered: EventWriter<ForPlugin<ScriptAttachedEvent, P>>,
88-
mut requests: ResMut<RequestProcessingPipelineRun<P>>,
8986
) {
9087
let mut batch = events.get_loaded().map(|(mut a, b)| {
9188
*a.0.script_mut() = b.0;
9289
ForPlugin::new(a)
9390
});
9491

9592
if let Some(next) = batch.next() {
96-
requests.request_run();
9793
filtered.write_batch(std::iter::once(next).chain(batch));
9894
}
9995
}
@@ -103,7 +99,6 @@ pub fn filter_script_detachments<P: IntoScriptPluginParams>(
10399
mut events: EventReader<ScriptDetachedEvent>,
104100
mut filtered: EventWriter<ForPlugin<ScriptDetachedEvent, P>>,
105101
contexts: Res<ScriptContext<P>>,
106-
mut requests: ResMut<RequestProcessingPipelineRun<P>>,
107102
) {
108103
let contexts_guard = contexts.read();
109104
let mut batch = events
@@ -113,7 +108,6 @@ pub fn filter_script_detachments<P: IntoScriptPluginParams>(
113108
.map(ForPlugin::new);
114109

115110
if let Some(next) = batch.next() {
116-
requests.request_run();
117111
filtered.write_batch(std::iter::once(next).chain(batch));
118112
}
119113
}

docs/book.toml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ title = "Bevy Scripting"
77
description = "Documentation for the Bevy Scripting library"
88

99
[output.html]
10-
additional-js = ["multi-code-block.js"]
10+
additional-js = ["multi-code-block.js", "mermaid.min.js", "mermaid-init.js"]
1111
git-repository-url = "https://github.com/makspll/bevy_mod_scripting"
1212
edit-url-template = "https://github.com/makspll/bevy_mod_scripting/edit/main/docs/{path}"
1313

@@ -16,3 +16,6 @@ enable = true
1616
level = 1
1717

1818
[preprocessor.lad-preprocessor]
19+
20+
[preprocessor.mermaid]
21+
command = "mdbook-mermaid"

docs/src/SUMMARY.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@
1212
- [Script Systems](./ScriptSystems/introduction.md)
1313
- [Examples](./Examples/introduction.md)
1414

15+
# Script Pipeline
16+
17+
- [Script Pipeline](./ScriptPipeline/pipeline.md)
18+
1519
# Release Notes
1620

1721
- [Release Notes](./ReleaseNotes/guides.md)
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Script Pipeline
2+
3+
Processing script atachments and detachments is all done by the script pipeline.
4+
5+
In versions prior to `16.0` the pipeline was represented by load unload commands, which atomically processed scripts. Since then the pipeline has been maassively overhauled to allow:
6+
- Customizing callbacks during the process
7+
- Budgeting frame time for the pipeline
8+
- Allowing async steps in the process
9+
10+
The new pipeline works like this:
11+
- A set of systems in `PostUpdate` "filter" incoming `ScriptAttachedEvent` and `ScriptDetachedEvent`'s as well as `ScriptAssetModifiedEvent`'s (some generated from asset events, others from component hooks). The filtered events are wrapped in `ForPlugin<P>(inner)` events based on the language of the underlying event's.
12+
- Then inside the `ScriptProcessingSchedule<P>`

0 commit comments

Comments
 (0)