rbx_loader: stronger Place & Model types
This commit is contained in:
@@ -5,32 +5,34 @@ fn static_ustr(s:&'static str)->rbx_dom_weak::Ustr{
|
||||
rbx_dom_weak::ustr(s)
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ServicesError{
|
||||
Workspace,
|
||||
}
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct Context{
|
||||
pub(crate)dom:WeakDom,
|
||||
}
|
||||
|
||||
impl Context{
|
||||
pub const fn new(dom:WeakDom)->Self{
|
||||
Self{dom}
|
||||
pub fn from_place(dom:WeakDom)->Result<(Context,Services),ServicesError>{
|
||||
// TODO: create nil instances
|
||||
let context=Self{dom};
|
||||
let services=context.find_services()?;
|
||||
Ok((context,services))
|
||||
}
|
||||
pub fn script_singleton(source:String)->(Context,crate::runner::instance::Instance,Services){
|
||||
let script=InstanceBuilder::new("Script")
|
||||
.with_property("Source",rbx_types::Variant::String(source));
|
||||
let script_ref=script.referent();
|
||||
let mut context=Self::new(WeakDom::new(
|
||||
let dom=WeakDom::new(
|
||||
InstanceBuilder::new("DataModel")
|
||||
.with_child(script)
|
||||
));
|
||||
let services=context.convert_into_place();
|
||||
);
|
||||
let (context,services)=Self::from_model(dom);
|
||||
(context,crate::runner::instance::Instance::new(script_ref),services)
|
||||
}
|
||||
pub fn from_ref(dom:&WeakDom)->&Context{
|
||||
unsafe{&*(dom as *const WeakDom as *const Context)}
|
||||
}
|
||||
pub fn from_mut(dom:&mut WeakDom)->&mut Context{
|
||||
unsafe{&mut *(dom as *mut WeakDom as *mut Context)}
|
||||
}
|
||||
/// 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{
|
||||
let db=rbx_reflection_database::get();
|
||||
@@ -46,22 +48,22 @@ impl Context{
|
||||
self.superclass_iter("LuaSourceContainer").map(crate::runner::instance::Instance::new).collect()
|
||||
}
|
||||
|
||||
pub fn find_services(&self)->Option<Services>{
|
||||
Some(Services{
|
||||
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 convert_into_place(&mut self)->Services{
|
||||
pub fn from_model(mut dom:WeakDom)->(Context,Services){
|
||||
//snapshot root instances
|
||||
let children=self.dom.root().children().to_owned();
|
||||
let children=dom.root().children().to_owned();
|
||||
|
||||
//insert services
|
||||
let game=self.dom.root_ref();
|
||||
let game=dom.root_ref();
|
||||
let terrain_bldr=InstanceBuilder::new("Terrain");
|
||||
let workspace=self.dom.insert(game,
|
||||
let workspace=dom.insert(game,
|
||||
InstanceBuilder::new("Workspace")
|
||||
//Set Workspace.Terrain property equal to Terrain
|
||||
.with_property("Terrain",terrain_bldr.referent())
|
||||
@@ -69,25 +71,32 @@ impl Context{
|
||||
);
|
||||
{
|
||||
//Lowercase and upper case workspace property!
|
||||
let game=self.dom.root_mut();
|
||||
let game=dom.root_mut();
|
||||
// TODO: DELETE THIS!
|
||||
game.properties.insert(static_ustr("workspace"),rbx_types::Variant::Ref(workspace));
|
||||
game.properties.insert(static_ustr("Workspace"),rbx_types::Variant::Ref(workspace));
|
||||
}
|
||||
self.dom.insert(game,InstanceBuilder::new("Lighting"));
|
||||
dom.insert(game,InstanceBuilder::new("Lighting"));
|
||||
|
||||
//transfer original root instances into workspace
|
||||
for instance in children{
|
||||
self.dom.transfer_within(instance,workspace);
|
||||
dom.transfer_within(instance,workspace);
|
||||
}
|
||||
|
||||
Services{
|
||||
game,
|
||||
workspace,
|
||||
}
|
||||
(
|
||||
Self{dom},
|
||||
Services{game,workspace},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<WeakDom> for Context{
|
||||
fn as_ref(&self)->&WeakDom{
|
||||
&self.dom
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Services{
|
||||
pub game:Ref,
|
||||
pub workspace:Ref,
|
||||
pub(crate) game:Ref,
|
||||
pub(crate) workspace:Ref,
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ pub enum Error{
|
||||
error:mlua::Error
|
||||
},
|
||||
RustLua(mlua::Error),
|
||||
NoServices,
|
||||
Services(crate::context::ServicesError),
|
||||
}
|
||||
impl std::fmt::Display for Error{
|
||||
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
|
||||
@@ -54,7 +54,7 @@ impl Runner{
|
||||
Ok(runner)
|
||||
}
|
||||
pub fn runnable_context<'a>(self,context:&'a mut Context)->Result<Runnable<'a>,Error>{
|
||||
let services=context.find_services().ok_or(Error::NoServices)?;
|
||||
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>{
|
||||
|
||||
Reference in New Issue
Block a user