From 6e3b02082fab86e59d4677ad785bc90fb7bdabf6 Mon Sep 17 00:00:00 2001 From: Peepo-Juice Date: Fri, 7 Mar 2025 11:11:24 -0500 Subject: [PATCH 1/2] [Lua] Fixed shared_context overriding global functions of other scripts --- crates/bevy_mod_scripting_core/src/asset.rs | 9 ++++++ .../bevy_mod_scripting_lua/src/lib.rs | 29 +++++++++++++++++-- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/crates/bevy_mod_scripting_core/src/asset.rs b/crates/bevy_mod_scripting_core/src/asset.rs index a41e911237..6e121b9f12 100644 --- a/crates/bevy_mod_scripting_core/src/asset.rs +++ b/crates/bevy_mod_scripting_core/src/asset.rs @@ -18,6 +18,7 @@ use bevy::{ reflect::TypePath, utils::HashMap, }; +use mlua::Table; use std::borrow::Cow; /// 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 { } } +/// stores environments for each script +#[derive(Default, Debug, Resource)] +pub struct ScriptEnvironmentStore { + /// The map of Script id's to their env + pub map: HashMap, +} + /// 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. #[derive(Default, Debug, Resource)] pub struct ScriptMetadataStore { @@ -349,6 +357,7 @@ pub(crate) fn configure_asset_systems(app: &mut App) -> &mut App { .before(ScriptingSystemSet::ScriptMetadataRemoval), ), ) + .init_resource::() .init_resource::() .init_resource::() .add_event::(); diff --git a/crates/languages/bevy_mod_scripting_lua/src/lib.rs b/crates/languages/bevy_mod_scripting_lua/src/lib.rs index 9d4ccb121d..a7c64a2b37 100644 --- a/crates/languages/bevy_mod_scripting_lua/src/lib.rs +++ b/crates/languages/bevy_mod_scripting_lua/src/lib.rs @@ -5,7 +5,7 @@ use bevy::{ ecs::{entity::Entity, world::World}, }; use bevy_mod_scripting_core::{ - asset::{AssetPathToLanguageMapper, Language}, + asset::{AssetPathToLanguageMapper, Language, ScriptEnvironmentStore}, bindings::{ function::namespace::Namespace, globals::AppScriptGlobalsRegistry, script_value::ScriptValue, ThreadWorldContainer, WorldContainer, @@ -172,11 +172,25 @@ fn load_lua_content_into_context( .iter() .try_for_each(|init| init(script_id, Entity::from_raw(0), context))?; + // isolate the script's globals into an environment + let metatable = context.create_table()?; + metatable.set("__index", context.globals())?; + let env = context.create_table()?; + env.set_metatable(Some(metatable)); + context .load(content) + .set_environment(env.clone()) .exec() .map_err(ScriptError::from_mlua_error)?; + // store the env in the store so we can call BMS event handlers from them + let world = ThreadWorldContainer.try_get_world()?; + world.with_global_access(move |w| { + let map = &mut w.resource_mut::().map; + map.insert(script_id.clone(), env.clone()); + })?; + Ok(()) } @@ -240,7 +254,18 @@ pub fn lua_handler( .iter() .try_for_each(|init| init(script_id, entity, context))?; - let handler: Function = match context.globals().raw_get(callback_label.as_ref()) { + // we need the world to access the ScriptEnvironmentStore + // we will find the environment that belongs to this script to call the function + let world = ThreadWorldContainer.try_get_world()?; + let env = world.with_global_access(|w| { + w.resource::() + .map + .get(script_id) + .unwrap() + .clone() + })?; + + let handler: Function = match env.raw_get(callback_label.as_ref()) { Ok(handler) => handler, // not subscribed to this event type Err(_) => { From 4370b80588f54eb0adcb92174d507c61f4590758 Mon Sep 17 00:00:00 2001 From: Peepo-Juice Date: Fri, 7 Mar 2025 19:00:29 -0500 Subject: [PATCH 2/2] Removed unwrap when searching for script env --- crates/languages/bevy_mod_scripting_lua/src/lib.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/crates/languages/bevy_mod_scripting_lua/src/lib.rs b/crates/languages/bevy_mod_scripting_lua/src/lib.rs index 45add881c3..0f03843b92 100644 --- a/crates/languages/bevy_mod_scripting_lua/src/lib.rs +++ b/crates/languages/bevy_mod_scripting_lua/src/lib.rs @@ -261,11 +261,14 @@ pub fn lua_handler( w.resource::() .map .get(script_id) - .unwrap() - .clone() + .ok_or(ScriptError::new(format!( + "Could not find environment for script with ScriptId: {}", + script_id + ))) + .cloned() })?; - let handler: Function = match env.raw_get(callback_label.as_ref()) { + let handler: Function = match env?.raw_get(callback_label.as_ref()) { Ok(handler) => handler, // not subscribed to this event type Err(_) => {