roblox_emulator: fix subtle ustr bugs
This commit is contained in:
parent
fa07d16cf4
commit
08b5445838
@ -219,22 +219,23 @@ impl mlua::UserData for Instance{
|
|||||||
});
|
});
|
||||||
methods.add_meta_function(mlua::MetaMethod::Index,|lua,(this,index):(Instance,mlua::String)|{
|
methods.add_meta_function(mlua::MetaMethod::Index,|lua,(this,index):(Instance,mlua::String)|{
|
||||||
let index_str=&*index.to_str()?;
|
let index_str=&*index.to_str()?;
|
||||||
let Some(index_ustr)=Ustr::from_existing(index_str)else{
|
|
||||||
return Ok(mlua::Value::Nil)
|
|
||||||
};
|
|
||||||
dom_mut(lua,|dom|{
|
dom_mut(lua,|dom|{
|
||||||
let instance=this.get(dom)?;
|
let instance=this.get(dom)?;
|
||||||
//println!("__index t={} i={index:?}",instance.name);
|
//println!("__index t={} i={index:?}",instance.name);
|
||||||
let db=rbx_reflection_database::get();
|
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.as_str()).ok_or_else(||mlua::Error::runtime("Class missing"))?;
|
||||||
//Find existing property
|
// Find existing property
|
||||||
match instance.properties.get(&index_ustr)
|
// Interestingly, ustr can know ahead of time if
|
||||||
.cloned()
|
// a property does not exist in any runtime instance
|
||||||
|
match Ustr::from_existing(index_str)
|
||||||
|
.and_then(|index_ustr|
|
||||||
|
instance.properties.get(&index_ustr).cloned()
|
||||||
|
)
|
||||||
//Find default value
|
//Find default value
|
||||||
.or_else(||db.find_default_property(class,index_str).cloned())
|
.or_else(||db.find_default_property(class,index_str).cloned())
|
||||||
//Find virtual property
|
//Find virtual property
|
||||||
.or_else(||db.superclasses_iter(class).find_map(|class|
|
.or_else(||db.superclasses_iter(class).find_map(|class|
|
||||||
find_virtual_property(&instance.properties,class,&index_ustr)
|
find_virtual_property(&instance.properties,class,index_str)
|
||||||
))
|
))
|
||||||
{
|
{
|
||||||
Some(rbx_types::Variant::Int32(val))=>return val.into_lua(lua),
|
Some(rbx_types::Variant::Int32(val))=>return val.into_lua(lua),
|
||||||
@ -276,9 +277,6 @@ impl mlua::UserData for Instance{
|
|||||||
});
|
});
|
||||||
methods.add_meta_function(mlua::MetaMethod::NewIndex,|lua,(this,index,value):(Instance,mlua::String,mlua::Value)|{
|
methods.add_meta_function(mlua::MetaMethod::NewIndex,|lua,(this,index,value):(Instance,mlua::String,mlua::Value)|{
|
||||||
let index_str=&*index.to_str()?;
|
let index_str=&*index.to_str()?;
|
||||||
let Some(index_ustr)=Ustr::from_existing(index_str)else{
|
|
||||||
return Ok(())
|
|
||||||
};
|
|
||||||
dom_mut(lua,|dom|{
|
dom_mut(lua,|dom|{
|
||||||
let instance=this.get_mut(dom)?;
|
let instance=this.get_mut(dom)?;
|
||||||
let db=rbx_reflection_database::get();
|
let db=rbx_reflection_database::get();
|
||||||
@ -288,6 +286,9 @@ impl mlua::UserData for Instance{
|
|||||||
).ok_or_else(||
|
).ok_or_else(||
|
||||||
mlua::Error::runtime(format!("Property '{index_str}' missing on class '{}'",class.name))
|
mlua::Error::runtime(format!("Property '{index_str}' missing on class '{}'",class.name))
|
||||||
)?;
|
)?;
|
||||||
|
// the index is known to be a real property at this point
|
||||||
|
// allow creating a permanent ustr (memory leak)
|
||||||
|
let index_ustr=rbx_dom_weak::ustr(index_str);
|
||||||
match &property.data_type{
|
match &property.data_type{
|
||||||
rbx_reflection::DataType::Value(rbx_types::VariantType::Vector3)=>{
|
rbx_reflection::DataType::Value(rbx_types::VariantType::Vector3)=>{
|
||||||
let typed_value:Vector3=*value.as_userdata().ok_or_else(||mlua::Error::runtime("Expected Userdata"))?.borrow()?;
|
let typed_value:Vector3=*value.as_userdata().ok_or_else(||mlua::Error::runtime("Expected Userdata"))?.borrow()?;
|
||||||
@ -469,7 +470,7 @@ static VIRTUAL_PROPERTY_DATABASE:VPD=phf::phf_map!{
|
|||||||
fn find_virtual_property(
|
fn find_virtual_property(
|
||||||
properties:&rbx_dom_weak::UstrMap<rbx_types::Variant>,
|
properties:&rbx_dom_weak::UstrMap<rbx_types::Variant>,
|
||||||
class:&rbx_reflection::ClassDescriptor,
|
class:&rbx_reflection::ClassDescriptor,
|
||||||
index:&Ustr,
|
index:&str,
|
||||||
)->Option<rbx_types::Variant>{
|
)->Option<rbx_types::Variant>{
|
||||||
//Find virtual property
|
//Find virtual property
|
||||||
let class_virtual_properties=VIRTUAL_PROPERTY_DATABASE.get(&class.name)?;
|
let class_virtual_properties=VIRTUAL_PROPERTY_DATABASE.get(&class.name)?;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user