use crate::context::Context; use super::vector3::Vector3; use super::cframe::CFrame; pub struct Runner{ lua:mlua::Lua, } #[derive(Debug)] pub enum Error{ Lua{ source:String, error:mlua::Error }, Script(super::instance::GetScriptError), /// If the lua.remove_app_data function fails RemoveAppData, } impl Error{ pub fn print(self){ match self{ Self::Lua{source,error:mlua::Error::RuntimeError(s)}=>{ println!("lua error: {s}\nsource:{source}"); }, 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:super::instance::Script,context:&mut Context)->Result<(),Error>{ let (name,source)=script.get_name_source(context).map_err(Error::Script)?; self.lua.globals().set("script",script).map_err(|error|Error::Lua{source:source.clone(),error})?; //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 r=self.lua.load(source.as_str()) .set_name(name) .exec().map_err(|error|Error::Lua{source,error}); self.lua.remove_app_data::<&'static mut rbx_dom_weak::WeakDom>(); r?; Ok(()) } }