forked from StrafesNET/strafe-project
roblox_emulator: nil instances
This commit is contained in:
@@ -7,21 +7,30 @@ fn static_ustr(s:&'static str)->rbx_dom_weak::Ustr{
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ServicesError{
|
||||
Workspace,
|
||||
WorkspaceNotFound,
|
||||
}
|
||||
|
||||
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())
|
||||
);
|
||||
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(),
|
||||
game,
|
||||
workspace,
|
||||
nil,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -34,7 +43,6 @@ pub struct Context{
|
||||
|
||||
impl Context{
|
||||
pub fn from_place(mut dom:WeakDom)->Result<Context,ServicesError>{
|
||||
// TODO: create nil instances
|
||||
let services=Services::get_or_create_services(&mut dom)?;
|
||||
Ok(Self{dom,services})
|
||||
}
|
||||
@@ -77,6 +85,12 @@ impl Context{
|
||||
.with_property("Terrain",terrain_bldr.referent())
|
||||
.with_child(terrain_bldr)
|
||||
);
|
||||
|
||||
//transfer original root instances into workspace
|
||||
for instance in children{
|
||||
dom.transfer_within(instance,workspace);
|
||||
}
|
||||
|
||||
{
|
||||
//Lowercase and upper case workspace property!
|
||||
let game=dom.root_mut();
|
||||
@@ -84,14 +98,15 @@ 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"));
|
||||
|
||||
//transfer original root instances into workspace
|
||||
for instance in children{
|
||||
dom.transfer_within(instance,workspace);
|
||||
}
|
||||
// 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};
|
||||
let services=Services{game,workspace,nil};
|
||||
Self{dom,services}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,9 +22,8 @@ pub fn set_globals(lua:&mlua::Lua,globals:&mlua::Table)->Result<(),mlua::Error>{
|
||||
instance_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.ok_or_else(||mlua::Error::runtime("Nil Parent not yet supported"))?;
|
||||
let parent=parent.unwrap_or(Instance::nil());
|
||||
dom_mut(lua,|dom|{
|
||||
//TODO: Nil instances
|
||||
Ok(Instance::new(dom.insert(parent.referent,InstanceBuilder::new(class_name_str))))
|
||||
})
|
||||
})?
|
||||
@@ -99,6 +98,18 @@ impl Instance{
|
||||
pub const fn new(referent:Ref)->Self{
|
||||
Self{referent}
|
||||
}
|
||||
pub fn maybe_nil(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()
|
||||
}
|
||||
}
|
||||
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"))
|
||||
}
|
||||
@@ -113,11 +124,11 @@ impl mlua::UserData for Instance{
|
||||
fields.add_field_method_get("Parent",|lua,this|{
|
||||
dom_mut(lua,|dom|{
|
||||
let instance=this.get(dom)?;
|
||||
Ok(Instance::new(instance.parent()))
|
||||
Ok(Instance::maybe_nil(instance.parent()))
|
||||
})
|
||||
});
|
||||
fields.add_field_method_set("Parent",|lua,this,val:Option<Instance>|{
|
||||
let parent=val.ok_or_else(||mlua::Error::runtime("Nil Parent not yet supported"))?;
|
||||
let parent=val.unwrap_or(Instance::nil());
|
||||
dom_mut(lua,|dom|{
|
||||
dom.transfer_within(this.referent,parent.referent);
|
||||
Ok(())
|
||||
@@ -207,7 +218,7 @@ impl mlua::UserData for Instance{
|
||||
);
|
||||
methods.add_method("Destroy",|lua,this,()|
|
||||
dom_mut(lua,|dom|{
|
||||
dom.destroy(this.referent);
|
||||
dom.transfer_within(this.referent,Instance::nil().referent);
|
||||
Ok(())
|
||||
})
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user