VIRTUAL_PROPERTY_DATABASE (another goddamn superclass walk)

This commit is contained in:
Quaternions 2024-10-06 17:14:46 -07:00
parent 3ad9d45452
commit fd02d5ed47

View File

@ -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::<super::cframe::CFrame>::into(cf).into_lua(lua),
Some(&rbx_types::Variant::Vector3(v))=>return Into::<super::vector3::Vector3>::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::<super::cframe::CFrame>::into(cf).into_lua(lua),
Some(rbx_types::Variant::Vector3(v))=>return Into::<super::vector3::Vector3>::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,42 @@ impl ClassMethods<'_>{
})
}
}
/// A virtual property pointer definition shorthand.
type VirtualPropertyFunctionPointer=fn(&rbx_types::Variant)->Option<rbx_types::Variant>;
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<String,rbx_types::Variant>,class:&rbx_reflection::ClassDescriptor,index:&str)->Option<rbx_types::Variant>{
let class_virtual_properties=VIRTUAL_PROPERTY_DATABASE.get(&class.name)?;
let vp=class_virtual_properties.get(index)?;
let variant=properties.get(vp.property)?;
(vp.pointer)(variant)
}