Context::get_or_create_service

This commit is contained in:
Quaternions 2024-10-14 12:15:39 -07:00
parent cfa24c98a6
commit 0aed94568e

View File

@ -46,9 +46,23 @@ impl Context{
self.superclass_iter("LuaSourceContainer").map(crate::runner::instance::Instance::new).collect() self.superclass_iter("LuaSourceContainer").map(crate::runner::instance::Instance::new).collect()
} }
fn get_service(&self,service:&str)->Option<Ref>{
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<Services>{ pub fn find_services(&self)->Option<Services>{
//nil instances isn't real, it doesn't exist in real roblox places Some(Services{
None workspace:self.get_service("Workspace")?,
nil:self.get_service("Nil")?,
game:self.dom.root_ref(),
})
} }
pub fn convert_into_place(&mut self)->Services{ pub fn convert_into_place(&mut self)->Services{
//snapshot root instances //snapshot root instances
@ -56,13 +70,15 @@ impl Context{
//insert services //insert services
let game=self.dom.root_ref(); let game=self.dom.root_ref();
let workspace=self.get_or_create_service("Workspace",|context|{
let terrain_bldr=InstanceBuilder::new("Terrain"); let terrain_bldr=InstanceBuilder::new("Terrain");
let workspace=self.dom.insert(game, context.dom.insert(game,
InstanceBuilder::new("Workspace") InstanceBuilder::new("Workspace")
//Set Workspace.Terrain property equal to Terrain //Set Workspace.Terrain property equal to Terrain
.with_property("Terrain",terrain_bldr.referent()) .with_property("Terrain",terrain_bldr.referent())
.with_child(terrain_bldr) .with_child(terrain_bldr)
); )
});
{ {
//Lowercase and upper case workspace property! //Lowercase and upper case workspace property!
let game=self.dom.root_mut(); let game=self.dom.root_mut();
@ -73,11 +89,13 @@ impl Context{
// Special nonexistent class that holds instances parented to nil, // Special nonexistent class that holds instances parented to nil,
// which can still be referenced by scripts. // which can still be referenced by scripts.
// Using a sentinel value as a ref because global variables are hard. // Using a sentinel value as a ref because global variables are hard.
let nil=self.dom.insert( let nil=self.get_or_create_service("Nil",|context|
context.dom.insert(
game,InstanceBuilder::new("Nil") game,InstanceBuilder::new("Nil")
.with_referent( .with_referent(
<Ref as std::str::FromStr>::from_str("ffffffffffffffffffffffffffffffff").unwrap() <Ref as std::str::FromStr>::from_str("ffffffffffffffffffffffffffffffff").unwrap()
) )
)
); );
//transfer original root instances into workspace //transfer original root instances into workspace