lyra-engine/lyra-scripting/src/lua/script.rs

79 lines
2.6 KiB
Rust
Raw Normal View History

2024-01-05 01:52:47 +00:00
use std::sync::Mutex;
use elua::{AsLua, StdLibraries, StdLibrary};
use tracing::{debug, trace};
2024-01-05 01:52:47 +00:00
use crate::{ScriptHost, ScriptError, ScriptWorldPtr, ScriptEntity};
2024-01-05 01:52:47 +00:00
#[derive(Default)]
pub struct LuaHost;
fn try_call_lua_function(lua: &elua::State, fn_name: &str) -> Result<(), ScriptError> {
let globals = lua.globals()?;
if globals.has_key(fn_name)? {
let lua_fn = globals.get::<_, elua::Function>(fn_name)?;
lua_fn.exec(())
.map_err(ScriptError::MluaError)?;
2024-01-05 01:52:47 +00:00
}
Ok(())
}
impl ScriptHost for LuaHost {
type ScriptContext = Mutex<elua::State>;
2024-01-05 01:52:47 +00:00
fn load_script(&mut self, script: &[u8], script_data: &crate::ScriptData, providers: &mut crate::ScriptApiProviders<Self>) -> Result<Self::ScriptContext, crate::ScriptError> {
let mut ctx = Mutex::new({
let s = elua::State::new();
s.expose_libraries(&[StdLibrary::Debug, StdLibrary::Package]);
s
});
//Mutex::new(elua::State::new_with_libraries(StdLibraries::all()));
2024-01-05 01:52:47 +00:00
for provider in providers.apis.iter_mut() {
2024-01-17 04:04:17 +00:00
provider.expose_api(script_data, &mut ctx)?;
2024-01-05 01:52:47 +00:00
}
let lua = ctx.lock().unwrap();
lua.load(&script_data.name, script)?
.execute(())
2024-01-05 01:52:47 +00:00
.map_err(|e| ScriptError::MluaError(e))?;
drop(lua);
Ok(ctx)
}
fn setup_script(&mut self, script_data: &crate::ScriptData, ctx: &mut Self::ScriptContext, providers: &mut crate::ScriptApiProviders<Self>) -> Result<(), ScriptError> {
for provider in providers.apis.iter_mut() {
provider.setup_script(script_data, ctx)?;
}
let ctx = ctx.lock().expect("Failure to get Lua ScriptContext");
try_call_lua_function(&ctx, "on_init")?;
2024-01-05 01:52:47 +00:00
Ok(())
}
/// Runs the update step of the lua script.
///
/// It looks for an `update` function with zero parameters in [`the ScriptContext`] and executes it.
fn call_script(&mut self, world: ScriptWorldPtr, script_data: &crate::ScriptData,
ctx: &mut Self::ScriptContext, providers: &mut crate::ScriptApiProviders<Self>,
function_name: &str) -> Result<(), ScriptError> {
2024-01-05 01:52:47 +00:00
for provider in providers.apis.iter_mut() {
provider.update_script_environment(world.clone(), script_data, ctx)?;
}
2024-01-05 01:52:47 +00:00
let ctx = ctx.lock().expect("Failure to get Lua ScriptContext");
let globals = ctx.globals()?;
globals.set("world", world.as_lua(&ctx)?)?;
globals.set("entity", ScriptEntity(script_data.entity).as_lua(&ctx)?)?;
try_call_lua_function(&ctx, function_name)?;
2024-01-05 01:52:47 +00:00
Ok(())
}
}