Create an early scripting engine #2

Merged
SeanOMik merged 42 commits from feature/early-scripting into main 2024-03-03 03:28:57 +00:00
7 changed files with 34 additions and 19 deletions
Showing only changes of commit 94abf2ddf0 - Show all commits

View File

@ -48,7 +48,7 @@ pub trait ScriptApiProvider {
} }
/// Exposes an API in the provided script context. /// Exposes an API in the provided script context.
fn expose_api(&mut self, ctx: &mut Self::ScriptContext) -> Result<(), ScriptError>; fn expose_api(&mut self, data: &ScriptData, ctx: &mut Self::ScriptContext) -> Result<(), ScriptError>;
/// Setup a script right before its 'init' method is called. /// Setup a script right before its 'init' method is called.
fn setup_script(&mut self, data: &ScriptData, ctx: &mut Self::ScriptContext) -> Result<(), ScriptError>; fn setup_script(&mut self, data: &ScriptData, ctx: &mut Self::ScriptContext) -> Result<(), ScriptError>;

View File

@ -5,7 +5,7 @@ pub use dynamic_iter::*;
pub mod world; pub mod world;
use lyra_game::{game::GameStages, plugin::Plugin}; use lyra_game::{game::GameStages, plugin::Plugin};
use lyra_resource::ResourceManager; use lyra_resource::ResourceManager;
use tracing::{debug, error, trace}; use tracing::{debug, error, trace, debug_span};
pub use world::*; pub use world::*;
pub mod script; pub mod script;
@ -214,19 +214,22 @@ pub fn lua_scripts_create_contexts(
entity: en, entity: en,
}; };
let script_name = script.name();
let _span = debug_span!("lua", script = script_name).entered();
if let Some(script_res) = &script.res_handle().try_data_ref() { if let Some(script_res) = &script.res_handle().try_data_ref() {
debug!("Loading script '{}'...", script.name()); debug!("Loading script...");
let mut script_ctx = let mut script_ctx =
host.load_script(&script_res.bytes, &script_data, &mut providers)?; host.load_script(&script_res.bytes, &script_data, &mut providers)?;
trace!("Finished loading script '{}'", script.name()); trace!("Finished loading script");
debug!("Setting up script '{}'...", script.name()); debug!("Setting up script...");
host.setup_script(&script_data, &mut script_ctx, &mut providers)?; host.setup_script(&script_data, &mut script_ctx, &mut providers)?;
trace!("Finished setting up script '{}'...", script.name()); trace!("Finished setting up script");
contexts.add_context(script.id(), script_ctx); contexts.add_context(script.id(), script_ctx);
} else { } else {
trace!("Script '{}' is not loaded yet, skipping for now", script.name()); trace!("Script is not loaded yet, skipping for now");
} }
} }
} }

View File

@ -1,4 +1,4 @@
use crate::{lua::LuaContext, ScriptApiProvider, ScriptWorldPtr, ScriptDynamicBundle}; use crate::{lua::LuaContext, ScriptApiProvider, ScriptWorldPtr, ScriptDynamicBundle, ScriptData};
#[derive(Default)] #[derive(Default)]
pub struct LyraEcsApiProvider; pub struct LyraEcsApiProvider;
@ -6,7 +6,7 @@ pub struct LyraEcsApiProvider;
impl ScriptApiProvider for LyraEcsApiProvider { impl ScriptApiProvider for LyraEcsApiProvider {
type ScriptContext = LuaContext; type ScriptContext = LuaContext;
fn expose_api(&mut self, ctx: &mut Self::ScriptContext) -> Result<(), crate::ScriptError> { fn expose_api(&mut self, data: &ScriptData, ctx: &mut Self::ScriptContext) -> Result<(), crate::ScriptError> {
let ctx = ctx.lock().unwrap(); let ctx = ctx.lock().unwrap();
let globals = ctx.globals(); let globals = ctx.globals();

View File

@ -1,5 +1,6 @@
use lyra_ecs::World; use lyra_ecs::World;
use lyra_game::math; use lyra_game::math;
use crate::ScriptData;
use crate::lua::RegisterLuaType; use crate::lua::RegisterLuaType;
use crate::lua::wrappers::{LuaVec3, LuaTransform}; use crate::lua::wrappers::{LuaVec3, LuaTransform};
@ -16,7 +17,7 @@ impl ScriptApiProvider for LyraMathApiProvider {
world.register_lua_wrapper::<LuaTransform>(); world.register_lua_wrapper::<LuaTransform>();
} }
fn expose_api(&mut self, ctx: &mut Self::ScriptContext) -> Result<(), crate::ScriptError> { fn expose_api(&mut self, data: &ScriptData, ctx: &mut Self::ScriptContext) -> Result<(), crate::ScriptError> {
let ctx = ctx.lock().unwrap(); let ctx = ctx.lock().unwrap();
/* let bytes = include_bytes!("../../../scripts/lua/math/vec3.lua"); /* let bytes = include_bytes!("../../../scripts/lua/math/vec3.lua");

View File

@ -1,5 +1,7 @@
use std::sync::{Mutex, Arc}; use std::sync::{Mutex, Arc};
use tracing::{debug_span, debug, span, Level};
use crate::{ScriptApiProvider, ScriptData}; use crate::{ScriptApiProvider, ScriptData};
/// This Api provider provides some nice utility functions. /// This Api provider provides some nice utility functions.
@ -17,7 +19,7 @@ pub struct UtilityApiProvider;
impl ScriptApiProvider for UtilityApiProvider { impl ScriptApiProvider for UtilityApiProvider {
type ScriptContext = Mutex<mlua::Lua>; type ScriptContext = Mutex<mlua::Lua>;
fn expose_api(&mut self, ctx: &mut Self::ScriptContext) -> Result<(), crate::ScriptError> { fn expose_api(&mut self, data: &ScriptData, ctx: &mut Self::ScriptContext) -> Result<(), crate::ScriptError> {
let ctx = ctx.lock().unwrap(); let ctx = ctx.lock().unwrap();
fn printf(lua: &mlua::Lua, (mut text, formats): (String, mlua::Variadic<mlua::Value>)) -> mlua::Result<()> { fn printf(lua: &mlua::Lua, (mut text, formats): (String, mlua::Variadic<mlua::Value>)) -> mlua::Result<()> {
@ -94,18 +96,27 @@ impl ScriptApiProvider for UtilityApiProvider {
formatted = format!("{}{}", formatted, text); formatted = format!("{}{}", formatted, text);
lua.globals() lua.globals()
.get::<_, mlua::Function>("print") .get::<_, mlua::Function>("print")?
.unwrap() .call::<_, ()>(formatted)?;
.call::<_, ()>(formatted)
.unwrap();
Ok(()) Ok(())
} }
let printf_func = ctx.create_function(printf).unwrap(); let script_name_reg = ctx.create_registry_value(data.name.clone())?;
let printf_func = ctx.create_function(printf)?;
let print_func = ctx.create_function(move |lua, text: String| {
let name = lua.registry_value::<String>(&script_name_reg)?;
let _span = debug_span!("lua", script = &name).entered();
debug!(target: "lyra_scripting::lua", "{}", text);
Ok(())
})?;
let globals = ctx.globals(); let globals = ctx.globals();
globals.set("printf", printf_func).unwrap(); globals.set("printf", printf_func)?;
globals.set("print", print_func)?;
Ok(()) Ok(())
} }

View File

@ -35,7 +35,7 @@ impl ScriptHost for LuaHost {
let mut ctx = Mutex::new(mlua::Lua::new()); let mut ctx = Mutex::new(mlua::Lua::new());
for provider in providers.apis.iter_mut() { for provider in providers.apis.iter_mut() {
provider.expose_api(&mut ctx)?; provider.expose_api(script_data, &mut ctx)?;
} }
let lua = ctx.lock().unwrap(); let lua = ctx.lock().unwrap();

View File

@ -21,7 +21,7 @@ struct PrintfProvider;
impl ScriptApiProvider for PrintfProvider { impl ScriptApiProvider for PrintfProvider {
type ScriptContext = Mutex<mlua::Lua>; type ScriptContext = Mutex<mlua::Lua>;
fn expose_api(&mut self, ctx: &mut Self::ScriptContext) -> Result<(), crate::ScriptError> { fn expose_api(&mut self, script_data: &ScriptData, ctx: &mut Self::ScriptContext) -> Result<(), crate::ScriptError> {
let ctx = ctx.lock().unwrap(); let ctx = ctx.lock().unwrap();
fn printf(lua: &mlua::Lua, (mut text, formats): (String, mlua::Variadic<mlua::Value>)) -> mlua::Result<()> { fn printf(lua: &mlua::Lua, (mut text, formats): (String, mlua::Variadic<mlua::Value>)) -> mlua::Result<()> {