Skip to content

Commit 950b41b

Browse files
committed
it works!
1 parent 5012e72 commit 950b41b

File tree

3 files changed

+72
-17
lines changed

3 files changed

+72
-17
lines changed

crates/bevy_mod_scripting_core/src/extractors.rs

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,20 +75,23 @@ unsafe impl<T: Resource + Default> SystemParam for ResScope<'_, T> {
7575
type Item<'world, 'state> = ResScope<'state, T>;
7676

7777
fn init_state(
78-
world: &mut World,
78+
_world: &mut World,
7979
system_meta: &mut bevy::ecs::system::SystemMeta,
8080
) -> Self::State {
8181
system_meta.set_has_deferred();
82-
(world.remove_resource().unwrap_or_default(), false)
82+
(T::default(), false)
8383
}
8484

8585
unsafe fn get_param<'world, 'state>(
8686
state: &'state mut Self::State,
8787
_system_meta: &bevy::ecs::system::SystemMeta,
88-
_world: bevy::ecs::world::unsafe_world_cell::UnsafeWorldCell<'world>,
88+
world: bevy::ecs::world::unsafe_world_cell::UnsafeWorldCell<'world>,
8989
_change_tick: bevy::ecs::component::Tick,
9090
) -> Self::Item<'world, 'state> {
9191
state.1 = true;
92+
if let Some(mut r) = world.get_resource_mut::<T>() {
93+
std::mem::swap(&mut state.0, &mut r);
94+
}
9295
ResScope(&mut state.0)
9396
}
9497

@@ -104,7 +107,7 @@ unsafe impl<T: Resource + Default> SystemParam for ResScope<'_, T> {
104107
}
105108
}
106109

107-
/// A version of [`EventReader`] which behaves with the same semantics as [`ResScope`].
110+
/// A version of [`bevy::ecs::event::EventReader`] which behaves just like [`ResScope`].
108111
#[derive(SystemParam)]
109112
pub struct EventReaderScope<'s, T: Event> {
110113
events: ResScope<'s, Events<T>>,
@@ -359,6 +362,7 @@ mod test {
359362
component::Component,
360363
event::{Event, EventReader},
361364
system::{Query, ResMut, Resource},
365+
world::FromWorld,
362366
},
363367
};
364368
use test_utils::make_test_plugin;
@@ -448,4 +452,15 @@ mod test {
448452
// check the resources are re-inserted
449453
assert!(app.world().contains_resource::<Res>());
450454
}
455+
456+
#[test]
457+
pub fn rescope_does_not_remove_until_system_call() {
458+
let mut world = World::new();
459+
world.insert_resource(Res);
460+
461+
// this will call init, and that should't remove the resource
462+
assert!(world.contains_resource::<Res>());
463+
SystemState::<ResScope<Res>>::from_world(&mut world);
464+
assert!(world.contains_resource::<Res>());
465+
}
451466
}

crates/bevy_mod_scripting_core/src/handler.rs

Lines changed: 52 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use bevy::{
1919
system::{Local, Resource, SystemState},
2020
world::{Mut, World},
2121
},
22-
log::trace_once,
22+
log::{self, trace_once},
2323
prelude::{Events, Ref},
2424
};
2525

@@ -108,13 +108,11 @@ macro_rules! push_err_and_continue {
108108
/// If any of the resources required for the handler are missing, the system will log this issue and do nothing.
109109
pub fn event_handler<L: IntoCallbackLabel, P: IntoScriptPluginParams>(
110110
world: &mut World,
111-
mut state: Local<
112-
SystemState<(
113-
Local<QueryState<(Entity, Ref<ScriptComponent>)>>,
114-
EventReaderScope<ScriptCallbackEvent>,
115-
WithWorldGuard<HandlerContext<P>>,
116-
)>,
117-
>,
111+
state: &mut SystemState<(
112+
Local<QueryState<(Entity, Ref<ScriptComponent>)>>,
113+
EventReaderScope<ScriptCallbackEvent>,
114+
WithWorldGuard<HandlerContext<P>>,
115+
)>,
118116
) {
119117
// we wrap the inner event handler, so that we can immediately re-insert all the resources back.
120118
// otherwise this would happen in the next schedule
@@ -132,6 +130,12 @@ fn event_handler_inner<L: IntoCallbackLabel, P: IntoScriptPluginParams>(
132130
mut handler_ctxt: WithWorldGuard<HandlerContext<P>>,
133131
) {
134132
let (guard, handler_ctxt) = handler_ctxt.get_mut();
133+
// bevy::log::debug!(
134+
// "{}: scripts:{} contexts:{}",
135+
// P::LANGUAGE,
136+
// handler_ctxt.scripts.scripts.len(),
137+
// handler_ctxt.script_contexts.contexts.len()
138+
// );
135139
let mut errors = Vec::default();
136140

137141
let events = script_events.read().cloned().collect::<Vec<_>>();
@@ -183,15 +187,17 @@ fn event_handler_inner<L: IntoCallbackLabel, P: IntoScriptPluginParams>(
183187
{
184188
continue
185189
}
186-
_ => (),
190+
_ => {}
187191
}
188192

189-
match handler_ctxt.call::<L>(
193+
let call_result = handler_ctxt.call::<L>(
190194
script_id.clone(),
191195
*entity,
192196
event.args.clone(),
193197
guard.clone(),
194-
) {
198+
);
199+
200+
match call_result {
195201
Ok(_) => {}
196202
Err(e) => {
197203
match e.downcast_interop_inner() {
@@ -249,7 +255,12 @@ pub fn handle_script_errors<I: Iterator<Item = ScriptError> + Clone>(world: Worl
249255
mod test {
250256
use std::{borrow::Cow, collections::HashMap};
251257

252-
use bevy::app::{App, Update};
258+
use bevy::{
259+
app::{App, Update},
260+
asset::AssetPlugin,
261+
diagnostic::DiagnosticsPlugin,
262+
ecs::world::FromWorld,
263+
};
253264
use test_utils::make_test_plugin;
254265

255266
use crate::{
@@ -545,4 +556,33 @@ mod test {
545556
]
546557
);
547558
}
559+
560+
#[test]
561+
fn event_handler_reinserts_resources() {
562+
let mut app = App::new();
563+
app.add_plugins((
564+
AssetPlugin::default(),
565+
DiagnosticsPlugin,
566+
TestPlugin::default(),
567+
));
568+
569+
assert!(app
570+
.world()
571+
.get_resource::<Events<ScriptCallbackEvent>>()
572+
.is_some());
573+
574+
let mut local = SystemState::from_world(app.world_mut());
575+
576+
assert!(!app
577+
.world()
578+
.get_resource::<Events<ScriptCallbackEvent>>()
579+
.is_some());
580+
581+
event_handler::<OnTestCallback, TestPlugin>(app.world_mut(), &mut local);
582+
583+
assert!(app
584+
.world()
585+
.get_resource::<Events<ScriptCallbackEvent>>()
586+
.is_some());
587+
}
548588
}

examples/game_of_life.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ pub enum GameOfLifeCommand {
111111
/// Stop the game of life by dropping a handle to the game_of_life script
112112
Stop,
113113
}
114-
114+
use bevy_mod_scripting_core::ConfigureScriptPlugin;
115115
// ------------- GAME OF LIFE
116116
fn game_of_life_app(app: &mut App) -> &mut App {
117117
app.insert_resource(Time::<Fixed>::from_seconds(UPDATE_FREQUENCY.into()))

0 commit comments

Comments
 (0)