Skip to content

Commit a3bccba

Browse files
zwazelmakspll
andauthored
Fix removal of script contexts (#81)
* mmm * same behaviour as for lua * some printing * setup an example that demonstrates the issue * fixed the bug lol * if a function isnt found, dont scream in the console * Update multiple_events_rhai.rhai * fix clippy? * using the ScriptLoaded event * filter so we only get entities that still have to call "on_init" * this shows the problem * on_test is called on 1 entity, all others are removed * aaa * giving script id instead of enttiy id * Revert "giving script id instead of enttiy id" This reverts commit ab5062a. * that should be fixed. but funny enough, a script still somehow exists. * Revert "Revert "giving script id instead of enttiy id"" This reverts commit 13df73f. * this fixes the bug. * removed "on_test" * Update bevy_mod_scripting_core/src/systems.rs Co-authored-by: Maksymilian Mozolewski <makspl17@gmail.com> * applied suggestions / fixed errors --------- Co-authored-by: Maksymilian Mozolewski <makspl17@gmail.com>
1 parent 32eba12 commit a3bccba

File tree

3 files changed

+44
-23
lines changed

3 files changed

+44
-23
lines changed

assets/scripts/multiple_events_rhai.rhai

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,6 @@ fn on_init(name) {
44

55
fn on_update(name, delta) {
66
print(`Hello World! From "${name}" in Update: ${delta}`);
7+
8+
world.despawn_recursive(entity);
79
}

bevy_mod_scripting_core/src/systems.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,11 +95,20 @@ pub fn script_remove_synchronizer<H: ScriptHost>(
9595
mut query: RemovedComponents<ScriptCollection<H::ScriptAsset>>,
9696
mut contexts: ResMut<ScriptContexts<H::ScriptContext>>,
9797
) {
98-
query.iter().for_each(|v| {
98+
for v in query.iter() {
9999
// we know that this entity used to have a script component
100100
// ergo a script context must exist in ctxts, remove all scripts on the entity
101-
contexts.remove_context(v.index());
102-
})
101+
let script_ids = contexts
102+
.context_entities
103+
.iter()
104+
.filter_map(|(script_id, (entity, ..))| {
105+
(entity.index() == v.index()).then_some(*script_id)
106+
})
107+
.collect::<Vec<_>>();
108+
for script_id in script_ids {
109+
contexts.remove_context(script_id);
110+
}
111+
}
103112
}
104113

105114
/// Reloads hot-reloaded scripts, or loads missing contexts for scripts which were added but not loaded

examples/rhai/multiple_events_rhai.rs

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use bevy::{prelude::*, reflect::Reflect};
22
use bevy_mod_scripting_core::{
3+
event::ScriptLoaded,
34
prelude::{APIProvider, PriorityEventWriter, Recipients, Script, ScriptCollection},
45
AddScriptApiProvider, AddScriptHost, AddScriptHostHandler, ScriptingPlugin,
56
};
@@ -17,7 +18,7 @@ fn main() {
1718
.add_systems(Update, (call_init, call_update))
1819
.add_script_host::<RhaiScriptHost<ScriptArgs>>(PostUpdate)
1920
.add_api_provider::<RhaiScriptHost<ScriptArgs>>(Box::new(RhaiBevyAPIProvider))
20-
.add_script_handler::<RhaiScriptHost<ScriptArgs>, 0, 1>(PostUpdate)
21+
.add_script_handler::<RhaiScriptHost<ScriptArgs>, 0, 2>(PostUpdate)
2122
.run();
2223
}
2324

@@ -106,28 +107,37 @@ fn call_update(
106107

107108
fn call_init(
108109
mut events: PriorityEventWriter<RhaiEvent<ScriptArgs>>,
109-
mut commands: Commands,
110+
mut loaded_scripts: EventReader<ScriptLoaded>,
110111
entity_query: Query<
111112
(Entity, Option<&Name>, Option<&ScriptCollection<RhaiFile>>),
112-
Added<NewlyAddedEntityCallInit>,
113+
With<NewlyAddedEntityCallInit>,
113114
>,
115+
mut commands: Commands,
114116
) {
115-
entity_query.for_each(|(entity, name, scripts)| {
116-
if scripts.is_some() {
117-
events.send(
118-
RhaiEvent {
119-
hook_name: "on_init".to_owned(),
120-
args: ScriptArgs {
121-
delta_time: None,
122-
entity_name: name.map(|n| n.to_string()),
123-
},
124-
recipients: Recipients::Entity(entity),
125-
},
126-
0,
127-
);
128-
commands.entity(entity).remove::<NewlyAddedEntityCallInit>();
129-
} else {
130-
commands.entity(entity).remove::<NewlyAddedEntityCallInit>();
117+
// Call init on all entities that have a script that was just loaded, and remove the Marker component, so that Update can be called
118+
'outer: for loaded_script in loaded_scripts.iter() {
119+
for (entity, name, scripts) in entity_query.iter() {
120+
if let Some(scripts) = scripts {
121+
if scripts.scripts.iter().any(|s| s.id() == loaded_script.sid) {
122+
events.send(
123+
RhaiEvent {
124+
hook_name: "on_init".to_owned(),
125+
args: ScriptArgs {
126+
entity_name: name.map(|n| n.to_string()),
127+
..Default::default()
128+
},
129+
recipients: Recipients::ScriptID(loaded_script.sid),
130+
},
131+
0,
132+
);
133+
134+
commands.entity(entity).remove::<NewlyAddedEntityCallInit>();
135+
continue 'outer;
136+
}
137+
} else {
138+
commands.entity(entity).remove::<NewlyAddedEntityCallInit>();
139+
continue 'outer;
140+
}
131141
}
132-
});
142+
}
133143
}

0 commit comments

Comments
 (0)