From fa07d16cf467d0952465bb92166ddf6eccfe53f2 Mon Sep 17 00:00:00 2001 From: Quaternions <krakow20@gmail.com> Date: Fri, 18 Apr 2025 11:06:55 -0700 Subject: [PATCH] refactor some util functions to use new rbx-dom features --- lib/rbx_loader/src/rbx.rs | 42 ++++++++----------- lib/roblox_emulator/src/context.rs | 21 ++++------ .../src/runner/instance/instance.rs | 10 ++++- 3 files changed, 34 insertions(+), 39 deletions(-) diff --git a/lib/rbx_loader/src/rbx.rs b/lib/rbx_loader/src/rbx.rs index 15cbf2e..78fdbd6 100644 --- a/lib/rbx_loader/src/rbx.rs +++ b/lib/rbx_loader/src/rbx.rs @@ -18,31 +18,25 @@ fn static_ustr(s:&'static str)->rbx_dom_weak::Ustr{ rbx_dom_weak::ustr(s) } -fn class_is_a(class: &str, superclass: &str) -> bool { - if class==superclass { - return true - } - let class_descriptor=rbx_reflection_database::get().classes.get(class); - if let Some(descriptor) = &class_descriptor { - if let Some(class_super) = &descriptor.superclass { - return class_is_a(&class_super, superclass) - } - } - false -} -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){ - let mut stack=vec![instance]; - while let Some(item)=stack.pop(){ - for &referent in item.children(){ - if let Some(c)=dom.get_by_ref(referent){ - if class_is_a(c.class.as_str(),superclass){ - objects.push(c.referent());//copy ref - } - stack.push(c); - } - } - } +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 +){ + let instance=instance; + let db=rbx_reflection_database::get(); + let Some(superclass)=db.classes.get(superclass)else{ + return; + }; + objects.extend( + dom.descendants_of(instance.referent()).filter_map(|instance|{ + let class=db.classes.get(instance.class.as_str())?; + db.has_superclass(class,superclass).then(||instance.referent()) + }) + ); } + fn planar64_affine3_from_roblox(cf:&rbx_dom_weak::types::CFrame,size:&rbx_dom_weak::types::Vector3)->Planar64Affine3{ Planar64Affine3::new( Planar64Mat3::from_cols([ diff --git a/lib/roblox_emulator/src/context.rs b/lib/roblox_emulator/src/context.rs index 7dd360b..17b0ea5 100644 --- a/lib/roblox_emulator/src/context.rs +++ b/lib/roblox_emulator/src/context.rs @@ -5,16 +5,6 @@ fn static_ustr(s:&'static str)->rbx_dom_weak::Ustr{ rbx_dom_weak::ustr(s) } -pub fn class_is_a(class:&str,superclass:&str)->bool{ - class==superclass - ||rbx_reflection_database::get().classes.get(class) - .is_some_and(|descriptor| - descriptor.superclass.as_ref().is_some_and(|class_super| - class_is_a(class_super,superclass) - ) - ) -} - #[repr(transparent)] pub struct Context{ pub(crate)dom:WeakDom, @@ -43,9 +33,14 @@ impl 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{ - self.dom.descendants().filter(|&instance| - class_is_a(instance.class.as_ref(),superclass) - ).map(|instance|instance.referent()) + let db=rbx_reflection_database::get(); + let Some(superclass)=db.classes.get(superclass)else{ + panic!("Invalid class"); + }; + self.dom.descendants().filter_map(|instance|{ + let class=db.classes.get(instance.class.as_str())?; + db.has_superclass(class,superclass).then(||instance.referent()) + }) } pub fn scripts(&self)->Vec<crate::runner::instance::Instance>{ self.superclass_iter("LuaSourceContainer").map(crate::runner::instance::Instance::new).collect() diff --git a/lib/roblox_emulator/src/runner/instance/instance.rs b/lib/roblox_emulator/src/runner/instance/instance.rs index 4400a2a..78c6bf4 100644 --- a/lib/roblox_emulator/src/runner/instance/instance.rs +++ b/lib/roblox_emulator/src/runner/instance/instance.rs @@ -48,7 +48,13 @@ fn coerce_float32(value:&mlua::Value)->Option<f32>{ _=>None, } } - +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{ + return false; + }; + db.has_superclass(class,superclass) +} fn get_full_name(dom:&rbx_dom_weak::WeakDom,instance:&rbx_dom_weak::Instance)->String{ let mut full_name=instance.name.clone(); let mut pref=instance.parent(); @@ -196,7 +202,7 @@ impl mlua::UserData for Instance{ methods.add_method("IsA",|lua,this,classname:mlua::String| dom_mut(lua,|dom|{ let instance=this.get(dom)?; - Ok(crate::context::class_is_a(instance.class.as_str(),&*classname.to_str()?)) + Ok(class_is_a(instance.class.as_str(),&*classname.to_str()?)) }) ); methods.add_method("Destroy",|lua,this,()|