diff --git a/src/context.rs b/src/context.rs index 3f2541f..52e1c6a 100644 --- a/src/context.rs +++ b/src/context.rs @@ -46,9 +46,23 @@ impl Context{ self.superclass_iter("LuaSourceContainer").map(crate::runner::instance::Instance::new).collect() } + fn get_service(&self,service:&str)->Option{ + self.dom.root().children().iter().find(|&&r| + self.dom.get_by_ref(r).is_some_and(|instance|instance.class==service) + ).copied() + } + fn get_or_create_service(&mut self,service:&str,mut create:impl FnMut(&mut Context)->Ref)->Ref{ + match self.get_service(service){ + Some(referent)=>referent, + None=>create(self), + } + } pub fn find_services(&self)->Option{ - //nil instances isn't real, it doesn't exist in real roblox places - None + Some(Services{ + workspace:self.get_service("Workspace")?, + nil:self.get_service("Nil")?, + game:self.dom.root_ref(), + }) } pub fn convert_into_place(&mut self)->Services{ //snapshot root instances @@ -56,13 +70,15 @@ impl Context{ //insert services let game=self.dom.root_ref(); - let terrain_bldr=InstanceBuilder::new("Terrain"); - let workspace=self.dom.insert(game, - InstanceBuilder::new("Workspace") - //Set Workspace.Terrain property equal to Terrain - .with_property("Terrain",terrain_bldr.referent()) - .with_child(terrain_bldr) - ); + let workspace=self.get_or_create_service("Workspace",|context|{ + let terrain_bldr=InstanceBuilder::new("Terrain"); + context.dom.insert(game, + InstanceBuilder::new("Workspace") + //Set Workspace.Terrain property equal to Terrain + .with_property("Terrain",terrain_bldr.referent()) + .with_child(terrain_bldr) + ) + }); { //Lowercase and upper case workspace property! let game=self.dom.root_mut(); @@ -73,10 +89,12 @@ impl Context{ // Special nonexistent class that holds instances parented to nil, // which can still be referenced by scripts. // Using a sentinel value as a ref because global variables are hard. - let nil=self.dom.insert( - game,InstanceBuilder::new("Nil") - .with_referent( - ::from_str("ffffffffffffffffffffffffffffffff").unwrap() + let nil=self.get_or_create_service("Nil",|context| + context.dom.insert( + game,InstanceBuilder::new("Nil") + .with_referent( + ::from_str("ffffffffffffffffffffffffffffffff").unwrap() + ) ) );