Skip to content

Commit 6e3b020

Browse files
committed
[Lua] Fixed shared_context overriding global functions of other scripts
1 parent 2255a41 commit 6e3b020

File tree

2 files changed

+36
-2
lines changed
  • crates
    • bevy_mod_scripting_core/src
    • languages/bevy_mod_scripting_lua/src

2 files changed

+36
-2
lines changed

crates/bevy_mod_scripting_core/src/asset.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use bevy::{
1818
reflect::TypePath,
1919
utils::HashMap,
2020
};
21+
use mlua::Table;
2122
use std::borrow::Cow;
2223

2324
/// Represents a scripting language. Languages which compile into another language should use the target language as their language.
@@ -169,6 +170,13 @@ impl Default for AssetPathToLanguageMapper {
169170
}
170171
}
171172

173+
/// stores environments for each script
174+
#[derive(Default, Debug, Resource)]
175+
pub struct ScriptEnvironmentStore {
176+
/// The map of Script id's to their env
177+
pub map: HashMap<ScriptId, Table>,
178+
}
179+
172180
/// A cache of asset id's to their script id's. Necessary since when we drop an asset we won't have the ability to get the path from the asset.
173181
#[derive(Default, Debug, Resource)]
174182
pub struct ScriptMetadataStore {
@@ -349,6 +357,7 @@ pub(crate) fn configure_asset_systems(app: &mut App) -> &mut App {
349357
.before(ScriptingSystemSet::ScriptMetadataRemoval),
350358
),
351359
)
360+
.init_resource::<ScriptEnvironmentStore>()
352361
.init_resource::<ScriptMetadataStore>()
353362
.init_resource::<ScriptAssetSettings>()
354363
.add_event::<ScriptAssetEvent>();

crates/languages/bevy_mod_scripting_lua/src/lib.rs

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use bevy::{
55
ecs::{entity::Entity, world::World},
66
};
77
use bevy_mod_scripting_core::{
8-
asset::{AssetPathToLanguageMapper, Language},
8+
asset::{AssetPathToLanguageMapper, Language, ScriptEnvironmentStore},
99
bindings::{
1010
function::namespace::Namespace, globals::AppScriptGlobalsRegistry,
1111
script_value::ScriptValue, ThreadWorldContainer, WorldContainer,
@@ -172,11 +172,25 @@ fn load_lua_content_into_context(
172172
.iter()
173173
.try_for_each(|init| init(script_id, Entity::from_raw(0), context))?;
174174

175+
// isolate the script's globals into an environment
176+
let metatable = context.create_table()?;
177+
metatable.set("__index", context.globals())?;
178+
let env = context.create_table()?;
179+
env.set_metatable(Some(metatable));
180+
175181
context
176182
.load(content)
183+
.set_environment(env.clone())
177184
.exec()
178185
.map_err(ScriptError::from_mlua_error)?;
179186

187+
// store the env in the store so we can call BMS event handlers from them
188+
let world = ThreadWorldContainer.try_get_world()?;
189+
world.with_global_access(move |w| {
190+
let map = &mut w.resource_mut::<ScriptEnvironmentStore>().map;
191+
map.insert(script_id.clone(), env.clone());
192+
})?;
193+
180194
Ok(())
181195
}
182196

@@ -240,7 +254,18 @@ pub fn lua_handler(
240254
.iter()
241255
.try_for_each(|init| init(script_id, entity, context))?;
242256

243-
let handler: Function = match context.globals().raw_get(callback_label.as_ref()) {
257+
// we need the world to access the ScriptEnvironmentStore
258+
// we will find the environment that belongs to this script to call the function
259+
let world = ThreadWorldContainer.try_get_world()?;
260+
let env = world.with_global_access(|w| {
261+
w.resource::<ScriptEnvironmentStore>()
262+
.map
263+
.get(script_id)
264+
.unwrap()
265+
.clone()
266+
})?;
267+
268+
let handler: Function = match env.raw_get(callback_label.as_ref()) {
244269
Ok(handler) => handler,
245270
// not subscribed to this event type
246271
Err(_) => {

0 commit comments

Comments
 (0)