diff --git a/lib/rbx_loader/src/lib.rs b/lib/rbx_loader/src/lib.rs index 7ee3c46..723f481 100644 --- a/lib/rbx_loader/src/lib.rs +++ b/lib/rbx_loader/src/lib.rs @@ -40,21 +40,19 @@ impl AsRef<WeakDom> for Model{ pub struct Place{ context:Context, - services:roblox_emulator::context::Services, } impl Place{ pub fn new(dom:WeakDom)->Result<Self,roblox_emulator::context::ServicesError>{ - let (context,services)=Context::from_place(dom)?; + let context=Context::from_place(dom)?; Ok(Self{ context, - services, }) } pub fn run_scripts(&mut self){ - let Place{context,services}=self; + let Place{context}=self; let runner=roblox_emulator::runner::Runner::new().unwrap(); let scripts=context.scripts(); - let runnable=runner.runnable_context_with_services(context,services).unwrap(); + let runnable=runner.runnable_context(context).unwrap(); for script in scripts{ if let Err(e)=runnable.run_script(script){ println!("runner error: {e}"); @@ -72,10 +70,9 @@ impl AsRef<WeakDom> for Place{ } impl From<Model> for Place{ fn from(model:Model)->Self{ - let (context,services)=Context::from_model(model.dom); + let context=Context::from_model(model.dom); Self{ context, - services, } } } diff --git a/lib/roblox_emulator/src/context.rs b/lib/roblox_emulator/src/context.rs index 67c0b69..6587e9f 100644 --- a/lib/roblox_emulator/src/context.rs +++ b/lib/roblox_emulator/src/context.rs @@ -10,19 +10,34 @@ pub enum ServicesError{ Workspace, } -#[repr(transparent)] +pub struct Services{ + pub(crate) game:Ref, + pub(crate) workspace:Ref, +} + +impl Services{ + fn get_or_create_services(dom:&mut WeakDom)->Result<Services,ServicesError>{ + Ok(Services{ + workspace:*dom.root().children().iter().find(|&&r| + dom.get_by_ref(r).is_some_and(|instance|instance.class=="Workspace") + ).ok_or(ServicesError::Workspace)?, + game:dom.root_ref(), + }) + } +} + pub struct Context{ pub(crate)dom:WeakDom, + pub(crate)services:Services, } impl Context{ - pub fn from_place(dom:WeakDom)->Result<(Context,Services),ServicesError>{ + pub fn from_place(mut dom:WeakDom)->Result<Context,ServicesError>{ // TODO: create nil instances - let context=Self{dom}; - let services=context.find_services()?; - Ok((context,services)) + let services=Services::get_or_create_services(&mut dom)?; + Ok(Self{dom,services}) } - pub fn script_singleton(source:String)->(Context,crate::runner::instance::Instance,Services){ + pub fn script_singleton(source:String)->(Context,crate::runner::instance::Instance){ let script=InstanceBuilder::new("Script") .with_property("Source",rbx_types::Variant::String(source)); let script_ref=script.referent(); @@ -30,8 +45,8 @@ impl Context{ InstanceBuilder::new("DataModel") .with_child(script) ); - let (context,services)=Self::from_model(dom); - (context,crate::runner::instance::Instance::new(script_ref),services) + let context=Self::from_model(dom); + (context,crate::runner::instance::Instance::new(script_ref)) } /// Creates an iterator over all items of a particular class. pub fn superclass_iter<'a>(&'a self,superclass:&'a str)->impl Iterator<Item=Ref>+'a{ @@ -48,15 +63,7 @@ impl Context{ self.superclass_iter("LuaSourceContainer").map(crate::runner::instance::Instance::new).collect() } - pub fn find_services(&self)->Result<Services,ServicesError>{ - Ok(Services{ - workspace:*self.dom.root().children().iter().find(|&&r| - self.dom.get_by_ref(r).is_some_and(|instance|instance.class=="Workspace") - ).ok_or(ServicesError::Workspace)?, - game:self.dom.root_ref(), - }) - } - pub fn from_model(mut dom:WeakDom)->(Context,Services){ + pub fn from_model(mut dom:WeakDom)->Context{ //snapshot root instances let children=dom.root().children().to_owned(); @@ -83,10 +90,8 @@ impl Context{ dom.transfer_within(instance,workspace); } - ( - Self{dom}, - Services{game,workspace}, - ) + let services=Services{game,workspace}; + Self{dom,services} } } @@ -95,8 +100,3 @@ impl AsRef<WeakDom> for Context{ &self.dom } } - -pub struct Services{ - pub(crate) game:Ref, - pub(crate) workspace:Ref, -} diff --git a/lib/roblox_emulator/src/runner/runner.rs b/lib/roblox_emulator/src/runner/runner.rs index 0d50997..8d5e8aa 100644 --- a/lib/roblox_emulator/src/runner/runner.rs +++ b/lib/roblox_emulator/src/runner/runner.rs @@ -54,14 +54,10 @@ impl Runner{ Ok(runner) } pub fn runnable_context<'a>(self,context:&'a mut Context)->Result<Runnable<'a>,Error>{ - let services=context.find_services().map_err(Error::Services)?; - self.runnable_context_with_services(context,&services) - } - pub fn runnable_context_with_services<'a>(self,context:&'a mut Context,services:&crate::context::Services)->Result<Runnable<'a>,Error>{ { let globals=self.lua.globals(); - globals.set("game",super::instance::Instance::new(services.game)).map_err(Error::RustLua)?; - globals.set("workspace",super::instance::Instance::new(services.workspace)).map_err(Error::RustLua)?; + globals.set("game",super::instance::Instance::new(context.services.game)).map_err(Error::RustLua)?; + globals.set("workspace",super::instance::Instance::new(context.services.workspace)).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)});