diff --git a/lib/roblox_emulator/src/context.rs b/lib/roblox_emulator/src/context.rs index eaf8360..297b9af 100644 --- a/lib/roblox_emulator/src/context.rs +++ b/lib/roblox_emulator/src/context.rs @@ -13,24 +13,15 @@ pub enum ServicesError{ pub struct Services{ pub(crate) game:Ref, pub(crate) workspace:Ref, - pub(crate) nil:Ref, } impl Services{ - fn get_or_create_services(dom:&mut WeakDom)->Result<Services,ServicesError>{ - let game=dom.root_ref(); - // error if workspace does not exist - let workspace=*dom.root().children().iter().find(|&&r| - dom.get_by_ref(r).is_some_and(|instance|instance.class=="Workspace") - ).ok_or(ServicesError::WorkspaceNotFound)?; - // the root nil instance does not have a parent - let nil=dom.insert(Ref::none(),InstanceBuilder::new("Nil") - .with_referent(<Ref as std::str::FromStr>::from_str("ffffffffffffffffffffffffffffffff").unwrap()) - ); + fn find_services(dom:&WeakDom)->Result<Services,ServicesError>{ Ok(Services{ - game, - workspace, - nil, + workspace:*dom.root().children().iter().find(|&&r| + dom.get_by_ref(r).is_some_and(|instance|instance.class=="Workspace") + ).ok_or(ServicesError::WorkspaceNotFound)?, + game:dom.root_ref(), }) } } @@ -42,8 +33,8 @@ pub struct Context{ } impl Context{ - pub fn from_place(mut dom:WeakDom)->Result<Context,ServicesError>{ - let services=Services::get_or_create_services(&mut dom)?; + pub fn from_place(dom:WeakDom)->Result<Context,ServicesError>{ + let services=Services::find_services(&dom)?; Ok(Self{dom,services}) } pub fn script_singleton(source:String)->(Context,crate::runner::instance::Instance){ @@ -106,15 +97,9 @@ impl Context{ game.properties.insert(static_ustr("workspace"),rbx_types::Variant::Ref(workspace)); game.properties.insert(static_ustr("Workspace"),rbx_types::Variant::Ref(workspace)); } - dom.insert(game,InstanceBuilder::new("Lighting")); - // the root nil instance does not have a parent - let nil=dom.insert(Ref::none(),InstanceBuilder::new("Nil") - .with_referent(<Ref as std::str::FromStr>::from_str("ffffffffffffffffffffffffffffffff").unwrap()) - ); - - let services=Services{game,workspace,nil}; + let services=Services{game,workspace}; Self{dom,services} } } diff --git a/lib/roblox_emulator/src/runner/instance/instance.rs b/lib/roblox_emulator/src/runner/instance/instance.rs index 2bb131c..02d75eb 100644 --- a/lib/roblox_emulator/src/runner/instance/instance.rs +++ b/lib/roblox_emulator/src/runner/instance/instance.rs @@ -22,9 +22,9 @@ pub fn set_globals(lua:&mlua::Lua,globals:&mlua::Table)->Result<(),mlua::Error>{ table.raw_set("new", lua.create_function(|lua,(class_name,parent):(mlua::String,Option<Instance>)|{ let class_name_str=&*class_name.to_str()?; - let parent=parent.unwrap_or(Instance::nil()); + let parent_ref=parent.map_or(Ref::none(),|instance|instance.referent); dom_mut(lua,|dom|{ - Ok(Instance::new_unchecked(dom.insert(parent.referent,InstanceBuilder::new(class_name_str)))) + Ok(Instance::new_unchecked(dom.insert(parent_ref,InstanceBuilder::new(class_name_str)))) }) })? )?; @@ -107,16 +107,7 @@ impl Instance{ Self{referent} } pub fn new(referent:Ref)->Option<Self>{ - match referent=="ffffffffffffffffffffffffffffffff".parse().unwrap(){ - true=>None, - false=>Some(Self{referent}) - } - } - // Using a sentinel value as a ref for nil instances because global variables are hard. - pub fn nil()->Self{ - Self{ - referent:"ffffffffffffffffffffffffffffffff".parse().unwrap() - } + referent.is_some().then_some(Self{referent}) } pub fn get<'a>(&self,dom:&'a WeakDom)->mlua::Result<&'a rbx_dom_weak::Instance>{ dom.get_by_ref(self.referent).ok_or_else(||mlua::Error::runtime("Instance missing")) @@ -137,10 +128,10 @@ impl mlua::UserData for Instance{ } fields.add_field_method_get("parent",get_parent); fields.add_field_method_get("Parent",get_parent); - fn set_parent(lua:&mlua::Lua,this:&mut Instance,val:Option<Instance>)->mlua::Result<()>{ - let parent=val.unwrap_or(Instance::nil()); + fn set_parent(lua:&mlua::Lua,this:&mut Instance,new_parent:Option<Instance>)->mlua::Result<()>{ + let parent_ref=new_parent.map_or(Ref::none(),|instance|instance.referent); dom_mut(lua,|dom|{ - dom.transfer_within(this.referent,parent.referent); + dom.transfer_within(this.referent,parent_ref); Ok(()) }) } @@ -171,7 +162,6 @@ impl mlua::UserData for Instance{ fn clone(lua:&mlua::Lua,this:&Instance,_:())->mlua::Result<Instance>{ dom_mut(lua,|dom|{ let instance_ref=dom.clone_within(this.referent); - dom.transfer_within(instance_ref,Instance::nil().referent); Ok(Instance::new_unchecked(instance_ref)) }) } @@ -271,7 +261,7 @@ impl mlua::UserData for Instance{ methods.add_method("IsA",is_a); methods.add_method("Destroy",|lua,this,()| dom_mut(lua,|dom|{ - dom.transfer_within(this.referent,Instance::nil().referent); + dom.transfer_within(this.referent,Ref::none()); Ok(()) }) );