Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion crates/bevy_mod_scripting_bindings/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -577,7 +577,7 @@ impl DisplayWithTypeInfo for InteropError {
} => {
write!(
f,
"Error {} in function {} on {}: {}",
"Error {}\n in function {} on {}:\n {}",
context
.clone()
.unwrap_or(FunctionCallContext::new(Language::Unknown)),
Expand Down
16 changes: 13 additions & 3 deletions crates/bevy_mod_scripting_bindings/src/function/script_function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,18 @@ impl std::fmt::Display for FunctionCallContext {
f.write_str("in language: ")?;
self.language.fmt(f)?;
if let Some(context) = &self.location_context {
if let Some(script_name) = &context.script_name {
f.write_str(", in script: ")?;
script_name.fmt(f)?;
}

f.write_str(", at line: ")?;
context.line.fmt(f)?;
f.write_str(", at column: ")?;
context.col.fmt(f)?;

if let Some(col) = &context.col {
f.write_str(", at column: ")?;
col.fmt(f)?;
}
}
Ok(())
}
Expand All @@ -66,10 +74,12 @@ impl std::fmt::Display for FunctionCallContext {
#[debug_with_type_info(bms_display_path = "bevy_mod_scripting_display")]
/// Describes a location within a script
pub struct LocationContext {
/// The name of the script the function call originates from
pub script_name: Option<String>,
/// The line number
pub line: u32,
/// The column number
pub col: u32,
pub col: Option<u32>,
}

impl FunctionCallContext {
Expand Down
8 changes: 5 additions & 3 deletions crates/bevy_mod_scripting_core/src/pipeline/machines.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,9 +229,10 @@ impl<P: IntoScriptPluginParams> ScriptMachine<P> {
match &mut self.internal_state {
MachineExecutionState::Initialized(machine_state) => {
debug!(
"State '{}' entered. For script: {}",
"State '{}' entered. For script: {}, {:?}",
machine_state.state_name(),
self.context.attachment
self.context.attachment,
self.context.attachment.script(),
);

if let Some(listeners) = listeners.get(&machine_state.as_ref().type_id()) {
Expand Down Expand Up @@ -517,7 +518,8 @@ impl<P: IntoScriptPluginParams> MachineState<P> for ContextAssigned<P> {
let contexts = world.get_resource_or_init::<ScriptContext<P>>();
let mut contexts_guard = contexts.write();

match contexts_guard.insert(attachment.clone(), self.context.clone()) {
// drop any strong handles
match contexts_guard.insert(attachment.clone().into_weak(), self.context.clone()) {
Ok(_) => {}
Err(_) => {
drop(contexts_guard);
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_mod_scripting_core/src/pipeline/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ use crate::{
OnLoadedListener, OnReloadedListener, OnUnloadedForReloadListener,
OnUnloadedForUnloadListener,
},
script::{ScriptContext, ScriptId},
script::ScriptContext,
};

mod hooks;
Expand Down
22 changes: 11 additions & 11 deletions crates/bevy_mod_scripting_core/src/pipeline/start.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,10 @@ impl StrongScriptHandle {
handle: Handle<ScriptAsset>,
assets: &mut Assets<ScriptAsset>,
) -> Option<Self> {
assets.get_strong_handle(handle.id()).map(Self)
}

/// Upgrades an asset Id pointing to a script to a strong handle if the asset hasn't been dropped
pub fn upgrade(id: ScriptId, assets: &mut Assets<ScriptAsset>) -> Option<Self> {
assets.get_strong_handle(id).map(Self)
match handle {
s @ Handle::Strong(_) => Some(Self(s)),
_ => assets.get_strong_handle(handle.id()).map(Self),
}
}

/// Returns a reference to the strong handle inside
Expand Down Expand Up @@ -122,12 +120,14 @@ pub fn process_attachments<P: IntoScriptPluginParams>(
let contexts = contexts.read();
events.read().for_each(|wrapper| {
let attachment_event = wrapper.event();
let id = attachment_event.0.script().id();
let context = Context {
let id = attachment_event.0.script();
let mut context = Context {
attachment: attachment_event.0.clone(),
blackboard: Default::default(),
};
if let Some(strong_handle) = StrongScriptHandle::upgrade(id, &mut assets) {
if let Some(strong_handle) = StrongScriptHandle::from_assets(id, &mut assets) {
// we want the loading process to have access to asset paths, we will weaken the handle at the end.
*context.attachment.script_mut() = strong_handle.0.clone();
let content = strong_handle.get(&assets);
if let Some(existing_context) = contexts.get_context(&attachment_event.0) {
machines.queue_machine(
Expand Down Expand Up @@ -193,8 +193,8 @@ pub fn process_asset_modifications<P: IntoScriptPluginParams>(
affected_attachments
.into_iter()
.for_each(|(attachment, existing_context)| {
let id = attachment.script().id();
if let Some(strong_handle) = StrongScriptHandle::upgrade(id, &mut assets) {
let id = attachment.script();
if let Some(strong_handle) = StrongScriptHandle::from_assets(id, &mut assets) {
let content = strong_handle.get(&assets);
machines.queue_machine(
Context {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use bevy_mod_scripting_bindings::{
use bevy_platform::collections::HashMap;
use mlua::{FromLua, IntoLua, Value, Variadic};

use crate::IntoMluaError;
use crate::{IntoMluaError, LuaContextAppData};

use super::reference::LuaReflectReference;

Expand Down Expand Up @@ -142,10 +142,16 @@ impl IntoLua for LuaScriptValue {
ScriptValue::Error(script_error) => return Err(mlua::Error::external(script_error)),
ScriptValue::Function(function) => lua
.create_function(move |lua, args: Variadic<LuaScriptValue>| {
let loc = lua.inspect_stack(1).map(|debug| LocationContext {
line: debug.curr_line().try_into().unwrap_or_default(),
col: 0,
});
let loc = {
profiling::scope!("function call context");
lua.inspect_stack(1).map(|debug| LocationContext {
line: debug.curr_line().try_into().unwrap_or_default(),
col: None,
script_name: lua.app_data_ref::<LuaContextAppData>().and_then(|v| {
v.last_loaded_script_name.as_ref().map(|n| n.to_string())
}),
})
};
let out = function
.call(
args.into_iter().map(Into::into),
Expand All @@ -158,10 +164,16 @@ impl IntoLua for LuaScriptValue {
.into_lua(lua)?,
ScriptValue::FunctionMut(function) => lua
.create_function(move |lua, args: Variadic<LuaScriptValue>| {
let loc = lua.inspect_stack(0).map(|debug| LocationContext {
line: debug.curr_line() as u32,
col: 0,
});
let loc = {
profiling::scope!("function call context");
lua.inspect_stack(1).map(|debug| LocationContext {
line: debug.curr_line().try_into().unwrap_or_default(),
col: None,
script_name: lua.app_data_ref::<LuaContextAppData>().and_then(|v| {
v.last_loaded_script_name.as_ref().map(|n| n.to_string())
}),
})
};
let out = function
.call(
args.into_iter().map(Into::into),
Expand Down
12 changes: 12 additions & 0 deletions crates/languages/bevy_mod_scripting_lua/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use ::{
bevy_ecs::{entity::Entity, world::World},
};
use bevy_app::App;
use bevy_asset::AssetPath;
use bevy_ecs::world::{Mut, WorldId};
use bevy_log::trace;
use bevy_mod_scripting_asset::{Language, ScriptAsset};
Expand Down Expand Up @@ -275,6 +276,13 @@ fn load_lua_content_into_context(
Ok(())
}

/// App data which can be retrieved via [`mlua::Lua::app_data_ref`], containing some metadata about scripts present
#[derive(Default, Debug)]
pub struct LuaContextAppData {
/// the asset path of the script loaded last if this is a shared context, or the only script if it's not.
pub last_loaded_script_name: Option<AssetPath<'static>>,
}

#[profiling::function]
/// Load a lua context from a script
pub fn lua_context_load(
Expand All @@ -287,6 +295,10 @@ pub fn lua_context_load(
#[cfg(not(feature = "unsafe_lua_modules"))]
let mut context = LuaContext(Lua::new());

context.set_app_data(LuaContextAppData {
last_loaded_script_name: context_key.script().path().cloned(),
});

load_lua_content_into_context(&mut context, context_key, content, world_id)?;
Ok(context)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ use bevy_mod_scripting_core::{
handler::event_handler,
script::{ContextPolicy, ScriptComponent, ScriptContext},
};
use bevy_mod_scripting_display::DisplayProxy;
use bevy_mod_scripting_script::ScriptAttachment;
use test_utils::test_data::setup_integration_test;

Expand Down Expand Up @@ -593,7 +594,7 @@ impl ScenarioStep {
return Err(anyhow!("Failed to load script: {e}"));
}

info!("Script '{}' loaded successfully", script.id());
info!("Script '{}' loaded successfully", script.display());
}
ScenarioStep::SetupHandler { schedule, label } => {
match label.to_string().as_str() {
Expand Down Expand Up @@ -629,7 +630,10 @@ impl ScenarioStep {
.id();

context.entities.insert(name.to_string(), entity);
info!("Spawned entity '{entity}' with script '{}'", script.id());
info!(
"Spawned entity '{entity}' with script '{}'",
script.display()
);
}
ScenarioStep::EmitScriptCallbackEvent { event } => {
app.world_mut().send_event(event.clone());
Expand Down
Loading