use crate::context::Context; use super::vector3::Vector3; use super::cframe::CFrame; pub struct Runner{ lua:mlua::Lua, } #[derive(Debug)] pub enum Error{ Lua(mlua::Error), Script(crate::script::Error), /// If the lua.remove_app_data function fails RemoveAppData, } impl Error{ pub fn print(self){ match self{ Self::Lua(mlua::Error::RuntimeError(s))=>{ println!("lua error: {s}"); }, other=>println!("{:?}",other), } } } fn init(lua:&mlua::Lua)->mlua::Result<()>{ lua.sandbox(true)?; //global environment let globals=lua.globals(); //Vector3 { let vector3_table=lua.create_table()?; //Vector3.new vector3_table.raw_set("new", lua.create_function(|ctx,(x,y,z):(f32,f32,f32)| Ok(ctx.create_userdata(Vector3::new(x,y,z))) )? )?; globals.set("Vector3",vector3_table)?; } //CFrame { let cframe_table=lua.create_table()?; //CFrame.new cframe_table.raw_set("new", lua.create_function(|ctx,(x,y,z):(f32,f32,f32)| Ok(ctx.create_userdata(CFrame::new(x,y,z))) )? )?; //CFrame.Angles cframe_table.raw_set("Angles", lua.create_function(|ctx,(x,y,z):(f32,f32,f32)| Ok(ctx.create_userdata(CFrame::angles(x,y,z))) )? )?; globals.set("CFrame",cframe_table)?; } Ok(()) } impl Runner{ pub fn new()->mlua::Result{ let runner=Self{ lua:mlua::Lua::new(), }; init(&runner.lua)?; Ok(runner) } pub fn run_script(&self,script:crate::script::Script,context:&mut Context)->Result<(),Error>{ let yoink=script.name_source(context); //this makes set_app_data shut up about the lifetime self.lua.set_app_data::<&'static mut rbx_dom_weak::WeakDom>(unsafe{core::mem::transmute(&mut context.dom)}); let (name,source)=yoink.map_err(Error::Script)?; self.lua.globals().set("script",super::instance::Instance::from(script)).map_err(Error::Lua)?; self.lua.load(source) .set_name(name) .exec().map_err(Error::Lua)?; self.lua.remove_app_data::<&'static mut rbx_dom_weak::WeakDom>(); Ok(()) } }