Skip to content

Commit 7cda178

Browse files
committed
feature: Add on_script_reloaded callback.
1 parent c2087b1 commit 7cda178

File tree

3 files changed

+61
-4
lines changed

3 files changed

+61
-4
lines changed

crates/bevy_mod_scripting_core/src/commands.rs

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use crate::{
66
context::ContextBuilder,
77
error::{InteropError, ScriptError},
88
event::{
9-
CallbackLabel, IntoCallbackLabel, OnScriptLoaded, OnScriptUnloaded,
9+
CallbackLabel, IntoCallbackLabel, OnScriptLoaded, OnScriptUnloaded, OnScriptReloaded,
1010
ScriptCallbackResponseEvent,
1111
},
1212
extractors::{with_handler_system_state, HandlerContext},
@@ -150,6 +150,7 @@ impl<P: IntoScriptPluginParams> CreateOrUpdateScript<P> {
150150
#[profiling::all_functions]
151151
impl<P: IntoScriptPluginParams> Command for CreateOrUpdateScript<P> {
152152
fn apply(self, world: &mut bevy::prelude::World) {
153+
let mut reload_state = None;
153154
let success = with_handler_system_state(
154155
world,
155156
|guard, handler_ctxt: &mut HandlerContext<P>| {
@@ -194,6 +195,28 @@ impl<P: IntoScriptPluginParams> Command for CreateOrUpdateScript<P> {
194195
// it can potentially be loaded but without a successful script reload but that
195196
// leaves us in an okay state
196197
handler_ctxt.scripts.scripts.insert(self.id.clone(), script);
198+
} else {
199+
match handler_ctxt.call_dynamic_label(
200+
&OnScriptReloaded::into_callback_label(),
201+
&self.id,
202+
Entity::from_raw(0),
203+
vec![ScriptValue::Bool(true)],
204+
guard.clone(),
205+
) {
206+
Ok(state) => {
207+
reload_state = Some(state);
208+
}
209+
Err(err) => {
210+
handle_script_errors(
211+
guard.clone(),
212+
vec![err
213+
.with_script(self.id.clone())
214+
.with_context(P::LANGUAGE)
215+
.with_context("saving reload state")]
216+
.into_iter(),
217+
);
218+
}
219+
}
197220
}
198221
bevy::log::debug!("{}: reloading script with id: {}", P::LANGUAGE, self.id);
199222
self.reload_context(guard.clone(), handler_ctxt)
@@ -235,14 +258,25 @@ impl<P: IntoScriptPluginParams> Command for CreateOrUpdateScript<P> {
235258
// immediately run command for callback, but only if loading went fine
236259
if success {
237260
RunScriptCallback::<P>::new(
238-
self.id,
261+
self.id.clone(),
239262
Entity::from_raw(0),
240263
OnScriptLoaded::into_callback_label(),
241264
vec![],
242265
false,
243266
)
244-
.apply(world)
267+
.apply(world);
268+
269+
if let Some(state) = reload_state {
270+
RunScriptCallback::<P>::new(
271+
self.id,
272+
Entity::from_raw(0),
273+
OnScriptReloaded::into_callback_label(),
274+
vec![ScriptValue::Bool(false), state],
275+
false,
276+
).apply(world);
277+
}
245278
}
279+
246280
}
247281
}
248282

crates/bevy_mod_scripting_core/src/event.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ macro_rules! callback_labels {
7575
callback_labels!(
7676
OnScriptLoaded => "on_script_loaded",
7777
OnScriptUnloaded => "on_script_unloaded",
78+
OnScriptReloaded => "on_script_reloaded",
7879
);
7980

8081
/// A trait for types that can be converted into a callback label

docs/src/ScriptingReference/core-callbacks.md

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22

33
On top of callbacks which are registered by your application, BMS provides a set of core callbacks which are always available.
44

5-
The two core callbacks are:
5+
The three core callbacks are:
66
- `on_script_loaded`
77
- `on_script_unloaded`
8+
- `on_script_reloaded`
89

910
## `on_script_loaded`
1011

@@ -30,3 +31,24 @@ function on_script_unloaded()
3031
print("Goodbye world")
3132
end
3233
```
34+
35+
## `on_script_reloaded`
36+
37+
This will be called twice: right before and after a script is reloaded.
38+
39+
The first parameter `save` informs you whether it is time to save a value or restore it.
40+
41+
Before the reload, it is called with one argument: `true`. After the script is reloaded, it is called with two parameters: the first is `false` and the second is value returned from before.
42+
43+
```lua
44+
mode = 1
45+
function on_script_reloaded(save, value)
46+
if save then
47+
print("Before I go, take this.")
48+
return mode
49+
else
50+
print("I'm back. Where was I?")
51+
mode = value
52+
end
53+
end
54+
```

0 commit comments

Comments
 (0)