From 8ab910e18f6e2ea4a9eba747d1882b3e098c57af Mon Sep 17 00:00:00 2001 From: Quaternions <krakow20@gmail.com> Date: Sat, 3 May 2025 22:11:58 -0700 Subject: [PATCH] wip: hash_str --- lib/rbx_loader/src/lib.rs | 14 ++--- lib/rbx_loader/src/loader.rs | 11 ++-- lib/rbx_loader/src/rbx.rs | 53 +++++++++---------- lib/roblox_emulator/src/context.rs | 47 ++++++++-------- lib/roblox_emulator/src/lib.rs | 1 - lib/roblox_emulator/src/runner/enum.rs | 16 +++--- .../src/runner/instance/instance.rs | 41 +++++++------- lib/roblox_emulator/src/runner/runner.rs | 6 +-- lib/roblox_emulator/src/util.rs | 3 -- 9 files changed, 90 insertions(+), 102 deletions(-) delete mode 100644 lib/roblox_emulator/src/util.rs diff --git a/lib/rbx_loader/src/lib.rs b/lib/rbx_loader/src/lib.rs index 723f481..993d453 100644 --- a/lib/rbx_loader/src/lib.rs +++ b/lib/rbx_loader/src/lib.rs @@ -21,19 +21,19 @@ pub mod data{ } } -pub struct Model{ - dom:WeakDom, +pub struct Model<'a>{ + dom:WeakDom<'a>, } -impl Model{ - fn new(dom:WeakDom)->Self{ +impl<'a> Model<'a>{ + fn new(dom:WeakDom<'a>)->Self{ Self{dom} } pub fn to_snf(&self,failure_mode:LoadFailureMode)->Result<strafesnet_common::map::CompleteMap,LoadError>{ to_snf(self,failure_mode) } } -impl AsRef<WeakDom> for Model{ - fn as_ref(&self)->&WeakDom{ +impl<'a> AsRef<WeakDom<'a>> for Model<'a>{ + fn as_ref(&self)->&WeakDom<'a>{ &self.dom } } @@ -95,7 +95,7 @@ pub fn read<R:Read>(input:R)->Result<Model,ReadError>{ let mut buf=std::io::BufReader::new(input); let peek=std::io::BufRead::fill_buf(&mut buf).map_err(ReadError::Io)?; match peek.get(0..8){ - Some(b"<roblox!")=>rbx_binary::from_reader(buf).map(Model::new).map_err(ReadError::RbxBinary), + Some(b"<roblox!")=>rbx_binary::from_reader_default(buf).map(Model::new).map_err(ReadError::RbxBinary), Some(b"<roblox ")=>rbx_xml::from_reader_default(buf).map(Model::new).map_err(ReadError::RbxXml), _=>Err(ReadError::UnknownFileFormat), } diff --git a/lib/rbx_loader/src/loader.rs b/lib/rbx_loader/src/loader.rs index 9096c46..f04d633 100644 --- a/lib/rbx_loader/src/loader.rs +++ b/lib/rbx_loader/src/loader.rs @@ -6,10 +6,7 @@ use strafesnet_deferred_loader::{loader::Loader,texture::Texture}; use crate::data::RobloxMeshBytes; use crate::rbx::RobloxPartDescription; -// disallow non-static lifetimes -fn static_ustr(s:&'static str)->rbx_dom_weak::Ustr{ - rbx_dom_weak::ustr(s) -} +use rbx_dom_weak::hstr; fn read_entire_file(path:impl AsRef<std::path::Path>)->Result<Vec<u8>,std::io::Error>{ let mut file=std::fs::File::open(path)?; @@ -168,7 +165,7 @@ impl Loader for MeshLoader{ let RobloxAssetId(asset_id)=index.content.parse()?; let file_name=format!("unions/{}",asset_id); let data=read_entire_file(file_name)?; - let dom=rbx_binary::from_reader(std::io::Cursor::new(data))?; + let dom=rbx_binary::from_reader_default(data.as_slice())?; let &[referent]=dom.root().children()else{ return Err(MeshError::OneChildPolicy); }; @@ -176,12 +173,12 @@ impl Loader for MeshLoader{ return Err(MeshError::MissingInstance); }; if physics_data.is_empty(){ - if let Some(rbx_dom_weak::types::Variant::BinaryString(data))=instance.properties.get(&static_ustr("PhysicsData")){ + if let Some(rbx_dom_weak::types::Variant::BinaryString(data))=instance.properties.get(hstr!("PhysicsData")){ physics_data=data.as_ref(); } } if mesh_data.is_empty(){ - if let Some(rbx_dom_weak::types::Variant::BinaryString(data))=instance.properties.get(&static_ustr("MeshData")){ + if let Some(rbx_dom_weak::types::Variant::BinaryString(data))=instance.properties.get(hstr!("MeshData")){ mesh_data=data.as_ref(); } } diff --git a/lib/rbx_loader/src/rbx.rs b/lib/rbx_loader/src/rbx.rs index cb4953d..4209e53 100644 --- a/lib/rbx_loader/src/rbx.rs +++ b/lib/rbx_loader/src/rbx.rs @@ -13,16 +13,13 @@ use strafesnet_deferred_loader::deferred_loader::{RenderConfigDeferredLoader,Mes use strafesnet_deferred_loader::mesh::Meshes; use strafesnet_deferred_loader::texture::{RenderConfigs,Texture}; -// disallow non-static lifetimes -fn static_ustr(s:&'static str)->rbx_dom_weak::Ustr{ - rbx_dom_weak::ustr(s) -} +use rbx_dom_weak::{hstr,HashStr}; fn recursive_collect_superclass( objects:&mut std::vec::Vec<rbx_dom_weak::types::Ref>, dom:&rbx_dom_weak::WeakDom, instance:&rbx_dom_weak::Instance, - superclass:&str + superclass:&HashStr, ){ let instance=instance; let db=rbx_reflection_database::get(); @@ -31,7 +28,7 @@ fn recursive_collect_superclass( }; objects.extend( dom.descendants_of(instance.referent()).filter_map(|instance|{ - let class=db.classes.get(instance.class.as_str())?; + let class=db.classes.get(instance.class)?; db.has_superclass(class,superclass).then(||instance.referent()) }) ); @@ -410,7 +407,7 @@ fn get_texture_description<'a>( //use the biggest one and cut it down later... let mut part_texture_description=RobloxPartDescription::default(); temp_objects.clear(); - recursive_collect_superclass(temp_objects,&dom,object,"Decal"); + recursive_collect_superclass(temp_objects,&dom,object,hstr!("Decal")); for &mut decal_ref in temp_objects{ let Some(decal)=dom.get_by_ref(decal_ref) else{ println!("Decal get_by_ref failed"); @@ -422,10 +419,10 @@ fn get_texture_description<'a>( Some(rbx_dom_weak::types::Variant::Color3(decal_color3)), Some(rbx_dom_weak::types::Variant::Float32(decal_transparency)), )=( - decal.properties.get(&static_ustr("TextureContent")), - decal.properties.get(&static_ustr("Face")), - decal.properties.get(&static_ustr("Color3")), - decal.properties.get(&static_ustr("Transparency")), + decal.properties.get(hstr!("TextureContent")), + decal.properties.get(hstr!("Face")), + decal.properties.get(hstr!("Color3")), + decal.properties.get(hstr!("Transparency")), )else{ println!("Decal is missing a required property"); continue; @@ -447,10 +444,10 @@ fn get_texture_description<'a>( Some(&rbx_dom_weak::types::Variant::Float32(studs_per_tile_u)), Some(&rbx_dom_weak::types::Variant::Float32(studs_per_tile_v)), ) = ( - decal.properties.get(&static_ustr("OffsetStudsU")), - decal.properties.get(&static_ustr("OffsetStudsV")), - decal.properties.get(&static_ustr("StudsPerTileU")), - decal.properties.get(&static_ustr("StudsPerTileV")), + decal.properties.get(hstr!("OffsetStudsU")), + decal.properties.get(hstr!("OffsetStudsV")), + decal.properties.get(hstr!("StudsPerTileU")), + decal.properties.get(hstr!("StudsPerTileV")), ) { let (size_u,size_v)=match cube_face{ @@ -537,7 +534,7 @@ pub fn convert<'a>( let mut object_refs=Vec::new(); let mut temp_objects=Vec::new(); - recursive_collect_superclass(&mut object_refs, &dom, dom.root(),"BasePart"); + recursive_collect_superclass(&mut object_refs, &dom, dom.root(),hstr!("BasePart")); for object_ref in object_refs { if let Some(object)=dom.get_by_ref(object_ref){ if let ( @@ -548,12 +545,12 @@ pub fn convert<'a>( Some(rbx_dom_weak::types::Variant::Color3uint8(color3)), Some(rbx_dom_weak::types::Variant::Bool(can_collide)), ) = ( - object.properties.get(&static_ustr("CFrame")), - object.properties.get(&static_ustr("Size")), - object.properties.get(&static_ustr("Velocity")), - object.properties.get(&static_ustr("Transparency")), - object.properties.get(&static_ustr("Color")), - object.properties.get(&static_ustr("CanCollide")), + object.properties.get(hstr!("CFrame")), + object.properties.get(hstr!("Size")), + object.properties.get(hstr!("Velocity")), + object.properties.get(hstr!("Transparency")), + object.properties.get(hstr!("Color")), + object.properties.get(hstr!("CanCollide")), ) { let model_transform=planar64_affine3_from_roblox(cf,size); @@ -572,7 +569,7 @@ pub fn convert<'a>( //TODO: also detect "CylinderMesh" etc here let shape=match object.class.as_str(){ - "Part"=>if let Some(rbx_dom_weak::types::Variant::Enum(shape))=object.properties.get(&static_ustr("Shape")){ + "Part"=>if let Some(rbx_dom_weak::types::Variant::Enum(shape))=object.properties.get(hstr!("Shape")){ Shape::Primitive(shape.to_u32().try_into().expect("Funky roblox PartType")) }else{ panic!("Part has no Shape!"); @@ -646,9 +643,9 @@ pub fn convert<'a>( Some(rbx_dom_weak::types::Variant::Content(texture_content)), )=( // mesh must exist - object.properties.get(&static_ustr("MeshContent")), + object.properties.get(hstr!("MeshContent")), // texture is allowed to be none - object.properties.get(&static_ustr("TextureContent")), + object.properties.get(hstr!("TextureContent")), ){ let mesh_asset_id=get_content_url(mesh_content).expect("MeshPart Mesh is not a Uri"); let texture_asset_id=get_content_url(texture_content); @@ -663,13 +660,13 @@ pub fn convert<'a>( let mut content=""; let mut mesh_data:&[u8]=&[]; let mut physics_data:&[u8]=&[]; - if let Some(rbx_dom_weak::types::Variant::ContentId(asset_id))=object.properties.get(&static_ustr("AssetId")){ + if let Some(rbx_dom_weak::types::Variant::ContentId(asset_id))=object.properties.get(hstr!("AssetId")){ content=asset_id.as_ref(); } - if let Some(rbx_dom_weak::types::Variant::BinaryString(data))=object.properties.get(&static_ustr("MeshData")){ + if let Some(rbx_dom_weak::types::Variant::BinaryString(data))=object.properties.get(hstr!("MeshData")){ mesh_data=data.as_ref(); } - if let Some(rbx_dom_weak::types::Variant::BinaryString(data))=object.properties.get(&static_ustr("PhysicsData")){ + if let Some(rbx_dom_weak::types::Variant::BinaryString(data))=object.properties.get(hstr!("PhysicsData")){ physics_data=data.as_ref(); } let part_texture_description=get_texture_description(&mut temp_objects,render_config_deferred_loader,dom,object,size); diff --git a/lib/roblox_emulator/src/context.rs b/lib/roblox_emulator/src/context.rs index f2d4a1b..a38eca1 100644 --- a/lib/roblox_emulator/src/context.rs +++ b/lib/roblox_emulator/src/context.rs @@ -1,5 +1,4 @@ -use crate::util::static_ustr; -use rbx_dom_weak::{types::Ref,InstanceBuilder,WeakDom}; +use rbx_dom_weak::{hstr,types::Ref,InstanceBuilder,WeakDom,UnhashedStr}; #[derive(Debug)] pub enum ServicesError{ @@ -28,36 +27,36 @@ impl Services{ } } -pub type LuaAppData=&'static mut WeakDom; -pub struct Context{ - pub(crate)dom:WeakDom, +pub type LuaAppData=&'static mut WeakDom<'static>; +pub struct Context<'a>{ + pub(crate)dom:WeakDom<'a>, pub(crate)services:Services, } -impl Context{ - pub fn from_place(dom:WeakDom)->Result<Context,ServicesError>{ +impl<'a> Context<'a>{ + pub fn from_place(dom:WeakDom<'a>)->Result<Context<'a>,ServicesError>{ let services=Services::find_services(&dom)?; Ok(Self{dom,services}) } - pub fn script_singleton(source:String)->(Context,crate::runner::instance::Instance){ - let script=InstanceBuilder::new("Script") - .with_property("Source",rbx_types::Variant::String(source)); + pub fn script_singleton(source:String)->(Context<'a>,crate::runner::instance::Instance){ + let script=InstanceBuilder::new(hstr!("Script")) + .with_property(hstr!("Source"),rbx_types::Variant::String(source)); let script_ref=script.referent(); let dom=WeakDom::new( - InstanceBuilder::new("DataModel") + InstanceBuilder::new(hstr!("DataModel")) .with_child(script) ); let context=Self::from_model(dom); (context,crate::runner::instance::Instance::new_unchecked(script_ref)) } /// 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{ + pub fn superclass_iter<'b>(&'b self,superclass:&'b str)->impl Iterator<Item=Ref>+'b{ let db=rbx_reflection_database::get(); - let Some(superclass)=db.classes.get(superclass)else{ + let Some(superclass)=db.classes.get(UnhashedStr::from_ref(superclass))else{ panic!("Invalid class"); }; self.dom.descendants().filter_map(|instance|{ - let class=db.classes.get(instance.class.as_str())?; + let class=db.classes.get(instance.class)?; db.has_superclass(class,superclass).then(||instance.referent()) }) } @@ -65,7 +64,7 @@ impl Context{ self.superclass_iter("Script") .filter_map(|script_ref|{ let script=self.dom.get_by_ref(script_ref)?; - if let None|Some(rbx_dom_weak::types::Variant::Bool(false))=script.properties.get(&static_ustr("Disabled")){ + if let None|Some(rbx_dom_weak::types::Variant::Bool(false))=script.properties.get(hstr!("Disabled")){ return Some(crate::runner::instance::Instance::new_unchecked(script_ref)); } None @@ -73,17 +72,17 @@ impl Context{ .collect() } - pub fn from_model(mut dom:WeakDom)->Context{ + pub fn from_model(mut dom:WeakDom<'a>)->Context<'a>{ //snapshot root instances let children=dom.root().children().to_owned(); //insert services let game=dom.root_ref(); - let terrain_bldr=InstanceBuilder::new("Terrain"); + let terrain_bldr=InstanceBuilder::new(hstr!("Terrain")); let workspace=dom.insert(game, - InstanceBuilder::new("Workspace") + InstanceBuilder::new(hstr!("Workspace")) //Set Workspace.Terrain property equal to Terrain - .with_property("Terrain",terrain_bldr.referent()) + .with_property(hstr!("Terrain"),terrain_bldr.referent()) .with_child(terrain_bldr) ); @@ -96,18 +95,18 @@ impl Context{ //Lowercase and upper case workspace property! 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)); + game.properties.insert(hstr!("workspace"),rbx_types::Variant::Ref(workspace)); + game.properties.insert(hstr!("Workspace"),rbx_types::Variant::Ref(workspace)); } - dom.insert(game,InstanceBuilder::new("Lighting")); + dom.insert(game,InstanceBuilder::new(hstr!("Lighting"))); let services=Services{game,workspace}; Self{dom,services} } } -impl AsRef<WeakDom> for Context{ - fn as_ref(&self)->&WeakDom{ +impl<'a> AsRef<WeakDom<'a>> for Context<'a>{ + fn as_ref(&self)->&WeakDom<'a>{ &self.dom } } diff --git a/lib/roblox_emulator/src/lib.rs b/lib/roblox_emulator/src/lib.rs index 0a825a4..362280a 100644 --- a/lib/roblox_emulator/src/lib.rs +++ b/lib/roblox_emulator/src/lib.rs @@ -1,4 +1,3 @@ -mod util; pub mod runner; pub mod context; #[cfg(feature="run-service")] diff --git a/lib/roblox_emulator/src/runner/enum.rs b/lib/roblox_emulator/src/runner/enum.rs index d3c3dc3..e018279 100644 --- a/lib/roblox_emulator/src/runner/enum.rs +++ b/lib/roblox_emulator/src/runner/enum.rs @@ -1,11 +1,13 @@ +use rbx_dom_weak::{HashStr, UnhashedStr}; + #[derive(Clone,Copy)] pub struct EnumItem<'a>{ - name:Option<&'a str>, + name:Option<&'a HashStr>, value:u32, } impl<'a> EnumItem<'a>{ - fn known_name((name,&value):(&'a std::borrow::Cow<'a,str>,&u32))->Self{ - Self{name:Some(name.as_ref()),value} + fn known_name((name,&value):(&&'a HashStr,&u32))->Self{ + Self{name:Some(name),value} } } impl<'a> From<rbx_types::Enum> for EnumItem<'a>{ @@ -38,7 +40,7 @@ pub struct Enums; impl Enums{ pub fn get(&self,index:&str)->Option<EnumItems<'static>>{ let db=rbx_reflection_database::get(); - db.enums.get(index).map(|ed|EnumItems{ed}) + db.enums.get(UnhashedStr::from_ref(index)).map(|ed|EnumItems{ed}) } } #[derive(Clone,Copy)] @@ -51,7 +53,7 @@ impl<'a> EnumItems<'a>{ self.ed.items.iter().find(|&(_,&v)|v==value).map(EnumItem::known_name) } pub fn from_name(&self,name:&str)->Option<EnumItem<'a>>{ - self.ed.items.get_key_value(name).map(EnumItem::known_name) + self.ed.items.get_key_value(UnhashedStr::from_ref(name)).map(EnumItem::known_name) } pub fn from_enum(&self,enum_item:EnumItem)->Option<EnumItem<'a>>{ match enum_item.name{ @@ -105,7 +107,7 @@ impl mlua::UserData for EnumItems<'static>{ }); methods.add_meta_function(mlua::MetaMethod::Index,|_,(this,val):(EnumItems,mlua::String)|{ let index=&*val.to_str()?; - Ok(this.ed.items.get_key_value(index).map(EnumItem::known_name)) + Ok(this.ed.items.get_key_value(UnhashedStr::from_ref(index)).map(EnumItem::known_name)) }); } } @@ -124,7 +126,7 @@ type_from_lua_userdata!(Enums); impl mlua::UserData for EnumItem<'_>{ fn add_fields<F:mlua::UserDataFields<Self>>(fields:&mut F){ - fields.add_field_method_get("Name",|_,this|Ok(this.name)); + fields.add_field_method_get("Name",|_,this|Ok(this.name.map(|s|s.as_str()))); fields.add_field_method_get("Value",|_,this|Ok(this.value)); } fn add_methods<M:mlua::UserDataMethods<Self>>(methods:&mut M){ diff --git a/lib/roblox_emulator/src/runner/instance/instance.rs b/lib/roblox_emulator/src/runner/instance/instance.rs index 1804691..0ccd089 100644 --- a/lib/roblox_emulator/src/runner/instance/instance.rs +++ b/lib/roblox_emulator/src/runner/instance/instance.rs @@ -2,9 +2,8 @@ use std::collections::{hash_map::Entry,HashMap}; use mlua::{FromLua,FromLuaMulti,IntoLua,IntoLuaMulti}; use rbx_types::Ref; -use rbx_dom_weak::{Ustr,InstanceBuilder,WeakDom}; +use rbx_dom_weak::{hstr,HashStr,UnhashedStr,InstanceBuilder,WeakDom}; -use crate::util::static_ustr; use crate::runner::vector3::Vector3; use crate::runner::number::Number; @@ -38,7 +37,7 @@ pub fn dom_mut<T>(lua:&mlua::Lua,mut f:impl FnMut(&mut WeakDom)->mlua::Result<T> pub fn class_is_a(class:&str,superclass:&str)->bool{ let db=rbx_reflection_database::get(); - let (Some(class),Some(superclass))=(db.classes.get(class),db.classes.get(superclass))else{ + let (Some(class),Some(superclass))=(db.classes.get(UnhashedStr::from_ref(class)),db.classes.get(UnhashedStr::from_ref(superclass)))else{ return false; }; db.has_superclass(class,superclass) @@ -57,7 +56,7 @@ fn get_full_name(dom:&rbx_dom_weak::WeakDom,instance:&rbx_dom_weak::Instance)->S pub fn get_name_source(lua:&mlua::Lua,script:Instance)->Result<(String,String),mlua::Error>{ dom_mut(lua,|dom|{ let instance=script.get(dom)?; - let source=match instance.properties.get(&static_ustr("Source")){ + let source=match instance.properties.get(hstr!("Source")){ Some(rbx_dom_weak::types::Variant::String(s))=>s.clone(), _=>Err(mlua::Error::external("Missing script.Source"))?, }; @@ -65,32 +64,32 @@ pub fn get_name_source(lua:&mlua::Lua,script:Instance)->Result<(String,String),m }) } -pub fn find_first_child<'a>(dom:&'a rbx_dom_weak::WeakDom,instance:&rbx_dom_weak::Instance,name:&str)->Option<&'a rbx_dom_weak::Instance>{ +pub fn find_first_child<'a>(dom:&'a rbx_dom_weak::WeakDom<'a>,instance:&rbx_dom_weak::Instance<'a>,name:&str)->Option<&'a rbx_dom_weak::Instance<'a>>{ instance.children().iter().filter_map(|&r|dom.get_by_ref(r)).find(|inst|inst.name==name) } -pub fn find_first_descendant<'a>(dom:&'a rbx_dom_weak::WeakDom,instance:&rbx_dom_weak::Instance,name:&str)->Option<&'a rbx_dom_weak::Instance>{ +pub fn find_first_descendant<'a>(dom:&'a rbx_dom_weak::WeakDom<'a>,instance:&rbx_dom_weak::Instance<'a>,name:&str)->Option<&'a rbx_dom_weak::Instance<'a>>{ dom.descendants_of(instance.referent()).find(|&inst|inst.name==name) } -pub fn find_first_child_of_class<'a>(dom:&'a rbx_dom_weak::WeakDom,instance:&rbx_dom_weak::Instance,class:&str)->Option<&'a rbx_dom_weak::Instance>{ +pub fn find_first_child_of_class<'a>(dom:&'a rbx_dom_weak::WeakDom<'a>,instance:&rbx_dom_weak::Instance<'a>,class:&str)->Option<&'a rbx_dom_weak::Instance<'a>>{ instance.children().iter().filter_map(|&r|dom.get_by_ref(r)).find(|inst|inst.class==class) } -pub fn find_first_descendant_of_class<'a>(dom:&'a rbx_dom_weak::WeakDom,instance:&rbx_dom_weak::Instance,class:&str)->Option<&'a rbx_dom_weak::Instance>{ +pub fn find_first_descendant_of_class<'a>(dom:&'a rbx_dom_weak::WeakDom<'a>,instance:&rbx_dom_weak::Instance<'a>,class:&str)->Option<&'a rbx_dom_weak::Instance<'a>>{ dom.descendants_of(instance.referent()).find(|&inst|inst.class==class) } -pub fn find_first_child_which_is_a<'a>(dom:&'a rbx_dom_weak::WeakDom,instance:&rbx_dom_weak::Instance,superclass:&str)->Option<&'a rbx_dom_weak::Instance>{ +pub fn find_first_child_which_is_a<'a>(dom:&'a rbx_dom_weak::WeakDom<'a>,instance:&rbx_dom_weak::Instance<'a>,superclass:&str)->Option<&'a rbx_dom_weak::Instance<'a>>{ let db=rbx_reflection_database::get(); - let superclass_descriptor=db.classes.get(superclass)?; + let superclass_descriptor=db.classes.get(UnhashedStr::from_ref(superclass))?; instance.children().iter().filter_map(|&r|dom.get_by_ref(r)).find(|inst|{ - db.classes.get(inst.class.as_str()).is_some_and(|descriptor|db.has_superclass(descriptor,superclass_descriptor)) + db.classes.get(inst.class).is_some_and(|descriptor|db.has_superclass(descriptor,superclass_descriptor)) }) } -pub fn find_first_descendant_which_is_a<'a>(dom:&'a rbx_dom_weak::WeakDom,instance:&rbx_dom_weak::Instance,superclass:&str)->Option<&'a rbx_dom_weak::Instance>{ +pub fn find_first_descendant_which_is_a<'a>(dom:&'a rbx_dom_weak::WeakDom<'a>,instance:&rbx_dom_weak::Instance<'a>,superclass:&str)->Option<&'a rbx_dom_weak::Instance<'a>>{ let db=rbx_reflection_database::get(); - let superclass_descriptor=db.classes.get(superclass)?; + let superclass_descriptor=db.classes.get(UnhashedStr::from_ref(superclass))?; dom.descendants_of(instance.referent()).find(|inst|{ - db.classes.get(inst.class.as_str()).is_some_and(|descriptor|db.has_superclass(descriptor,superclass_descriptor)) + db.classes.get(inst.class).is_some_and(|descriptor|db.has_superclass(descriptor,superclass_descriptor)) }) } @@ -105,10 +104,10 @@ impl Instance{ pub fn new(referent:Ref)->Option<Self>{ referent.is_some().then_some(Self{referent}) } - pub fn get<'a>(&self,dom:&'a WeakDom)->mlua::Result<&'a rbx_dom_weak::Instance>{ + pub fn get<'a>(&self,dom:&'a WeakDom<'a>)->mlua::Result<&'a rbx_dom_weak::Instance<'a>>{ dom.get_by_ref(self.referent).ok_or_else(||mlua::Error::runtime("Instance missing")) } - pub fn get_mut<'a>(&self,dom:&'a mut WeakDom)->mlua::Result<&'a mut rbx_dom_weak::Instance>{ + pub fn get_mut<'a,'b>(&self,dom:&'a mut WeakDom<'b>)->mlua::Result<&'a mut rbx_dom_weak::Instance<'b>>{ dom.get_by_ref_mut(self.referent).ok_or_else(||mlua::Error::runtime("Instance missing")) } } @@ -150,7 +149,7 @@ impl mlua::UserData for Instance{ fields.add_field_method_get("ClassName",|lua,this|{ dom_mut(lua,|dom|{ let instance=this.get(dom)?; - Ok(instance.class.to_owned()) + Ok(instance.class.as_str().to_owned()) }) }); } @@ -283,7 +282,7 @@ impl mlua::UserData for Instance{ let instance=this.get(dom)?; //println!("__index t={} i={index:?}",instance.name); let db=rbx_reflection_database::get(); - let class=db.classes.get(instance.class.as_str()).ok_or_else(||mlua::Error::runtime("Class missing"))?; + let class=db.classes.get(instance.class).ok_or_else(||mlua::Error::runtime("Class missing"))?; // Find existing property // Interestingly, ustr can know ahead of time if // a property does not exist in any runtime instance @@ -342,7 +341,7 @@ impl mlua::UserData for Instance{ dom_mut(lua,|dom|{ let instance=this.get_mut(dom)?; let db=rbx_reflection_database::get(); - let class=db.classes.get(instance.class.as_str()).ok_or_else(||mlua::Error::runtime("Class missing"))?; + let class=db.classes.get(instance.class).ok_or_else(||mlua::Error::runtime("Class missing"))?; let property=db.superclasses_iter(class).find_map(|cls| cls.properties.get(index_str) ).ok_or_else(|| @@ -590,7 +589,7 @@ static VIRTUAL_PROPERTY_DATABASE:VPD=phf::phf_map!{ }; fn find_virtual_property( - properties:&rbx_dom_weak::UstrMap<rbx_types::Variant>, + properties:&rbx_dom_weak::HashStrMap<rbx_types::Variant>, class:&rbx_reflection::ClassDescriptor, index:&str, )->Option<rbx_types::Variant>{ @@ -641,7 +640,7 @@ static LAZY_USER_DATA:LUD=phf::phf_map!{ fn get_or_create_userdata(instance:&mut rbx_dom_weak::Instance,lua:&mlua::Lua,index:&str)->mlua::Result<Option<mlua::AnyUserData>>{ use std::collections::hash_map::Entry; let db=rbx_reflection_database::get(); - let Some(class)=db.classes.get(instance.class.as_str())else{ + let Some(class)=db.classes.get(instance.class)else{ return Ok(None) }; if let Some((&static_str,create_userdata))=db.superclasses_iter(class).find_map(|superclass| diff --git a/lib/roblox_emulator/src/runner/runner.rs b/lib/roblox_emulator/src/runner/runner.rs index 7c3eb98..255c58e 100644 --- a/lib/roblox_emulator/src/runner/runner.rs +++ b/lib/roblox_emulator/src/runner/runner.rs @@ -1,5 +1,4 @@ use crate::context::Context; -use crate::util::static_ustr; #[cfg(feature="run-service")] use crate::scheduler::scheduler_mut; @@ -59,7 +58,7 @@ impl Runner{ init(&runner.lua).map_err(Error::RustLua)?; Ok(runner) } - pub fn runnable_context<'a>(self,context:&'a mut Context)->Result<Runnable<'a>,Error>{ + pub fn runnable_context<'a>(self,context:&'a mut Context<'a>)->Result<Runnable<'a>,Error>{ { let globals=self.lua.globals(); globals.set("game",super::instance::Instance::new_unchecked(context.services.game)).map_err(Error::RustLua)?; @@ -68,8 +67,7 @@ impl Runner{ // SAFETY: This is not a &'static mut WeakDom, // but as long as Runnable<'a> holds the lifetime of &'a mut Context // it is a valid unique reference. - let ptr=&mut context.dom as *mut rbx_dom_weak::WeakDom; - self.lua.set_app_data::<crate::context::LuaAppData>(unsafe{&mut*ptr}); + self.lua.set_app_data::<crate::context::LuaAppData>(unsafe{core::mem::transmute(&mut context.dom)}); #[cfg(feature="run-service")] self.lua.set_app_data::<crate::scheduler::Scheduler>(crate::scheduler::Scheduler::default()); Ok(Runnable{ diff --git a/lib/roblox_emulator/src/util.rs b/lib/roblox_emulator/src/util.rs deleted file mode 100644 index 92ac42d..0000000 --- a/lib/roblox_emulator/src/util.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub fn static_ustr(s:&'static str)->rbx_dom_weak::Ustr{ - rbx_dom_weak::ustr(s) -}