From 6dfa46bc6783a19659bfaa90d76eea3bee63e98d Mon Sep 17 00:00:00 2001 From: Quaternions Date: Sun, 6 Oct 2024 17:14:46 -0700 Subject: [PATCH] VIRTUAL_PROPERTY_DATABASE (another goddamn superclass walk) --- src/runner/instance.rs | 75 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 67 insertions(+), 8 deletions(-) diff --git a/src/runner/instance.rs b/src/runner/instance.rs index 8ce90b8..222201a 100644 --- a/src/runner/instance.rs +++ b/src/runner/instance.rs @@ -237,16 +237,27 @@ impl mlua::UserData for Instance{ let class=db.classes.get(instance.class.as_str()).ok_or(mlua::Error::runtime("Class missing"))?; //Find existing property match instance.properties.get(index_str) + .cloned() //Find default value - .or_else(||db.find_default_property(class,index_str)) + .or_else(||db.find_default_property(class,index_str).cloned()) + //Find virtual property + .or_else(||{ + SuperClassIter{ + database:db, + descriptor:Some(class), + } + .find_map(|class| + find_virtual_property(&instance.properties,class,index_str) + ) + }) { - Some(&rbx_types::Variant::Int32(val))=>return val.into_lua(lua), - Some(&rbx_types::Variant::Int64(val))=>return val.into_lua(lua), - Some(&rbx_types::Variant::Float32(val))=>return val.into_lua(lua), - Some(&rbx_types::Variant::Float64(val))=>return val.into_lua(lua), - Some(&rbx_types::Variant::Ref(val))=>return Instance::new(val).into_lua(lua), - Some(&rbx_types::Variant::CFrame(cf))=>return Into::::into(cf).into_lua(lua), - Some(&rbx_types::Variant::Vector3(v))=>return Into::::into(v).into_lua(lua), + Some(rbx_types::Variant::Int32(val))=>return val.into_lua(lua), + Some(rbx_types::Variant::Int64(val))=>return val.into_lua(lua), + Some(rbx_types::Variant::Float32(val))=>return val.into_lua(lua), + Some(rbx_types::Variant::Float64(val))=>return val.into_lua(lua), + Some(rbx_types::Variant::Ref(val))=>return Instance::new(val).into_lua(lua), + Some(rbx_types::Variant::CFrame(cf))=>return Into::::into(cf).into_lua(lua), + Some(rbx_types::Variant::Vector3(v))=>return Into::::into(v).into_lua(lua), None=>(), other=>return Err(mlua::Error::runtime(format!("Instance.__index Unsupported property type instance={} index={index_str} value={other:?}",instance.name))), } @@ -415,3 +426,51 @@ impl ClassMethods<'_>{ }) } } + +/// A virtual property pointer definition shorthand. +type VirtualPropertyFunctionPointer=fn(&rbx_types::Variant)->Option; +const fn vpp( + property:&'static str, + pointer:VirtualPropertyFunctionPointer, +)->VirtualProperty{ + VirtualProperty{ + property, + pointer, + } +} +struct VirtualProperty{ + property:&'static str,// Source property name + pointer:VirtualPropertyFunctionPointer, +} +type VPD=phf::Map<&'static str,// Class name + phf::Map<&'static str,// Virtual property name + VirtualProperty + > +>; +static VIRTUAL_PROPERTY_DATABASE:VPD=phf::phf_map!{ + "BasePart"=>phf::phf_map!{ + "Position"=>vpp("CFrame",|c:&rbx_types::Variant|{ + let c=match c{ + rbx_types::Variant::CFrame(c)=>c, + _=>return None,//fail silently and ungracefully + }; + Some(rbx_types::Variant::Vector3(c.position)) + }), + }, +}; + +fn find_virtual_property( + properties:&HashMap, + class:&rbx_reflection::ClassDescriptor, + index:&str +)->Option{ + //Find virtual property + let class_virtual_properties=VIRTUAL_PROPERTY_DATABASE.get(&class.name)?; + let virtual_property=class_virtual_properties.get(index)?; + + //Get source property + let variant=properties.get(virtual_property.property)?; + + //Transform Source property with provided function + (virtual_property.pointer)(variant) +}