use crate::context::Context; pub struct Runner{ lua:mlua::Lua, } #[derive(Debug)] pub enum Error{ Lua{ source:String, error:mlua::Error }, RustLua(mlua::Error), Script(super::instance::GetScriptError), } impl std::fmt::Display for Error{ fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{ match self{ Self::Lua{source,error:mlua::Error::RuntimeError(s)}=>write!(f,"lua error: {s}\nsource:{source}"), Self::RustLua(mlua::Error::RuntimeError(s))=>write!(f,"rust-side lua error: {s}"), other=>write!(f,"{other:?}"), } } } fn init(lua:&mlua::Lua)->mlua::Result<()>{ lua.sandbox(true)?; //global environment let globals=lua.globals(); super::vector3::set_globals(lua,&globals)?; super::cframe::set_globals(lua,&globals)?; Ok(()) } impl Runner{ pub fn new()->Result{ let runner=Self{ lua:mlua::Lua::new(), }; init(&runner.lua).map_err(Error::RustLua)?; 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::RustLua)?; //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(()) } }