Compare commits

...

5 Commits

Author SHA1 Message Date
d272ac242b sneak past type issues 2024-10-03 19:21:14 -07:00
e67f0f0889 implement Instance.__index 2024-10-03 19:09:02 -07:00
40655cdf44 get referent from any class 2024-10-03 18:55:50 -07:00
6c12bc2bf6 print errors better 2024-10-03 18:54:37 -07:00
5a1df16bd9 from_lua macro 2024-10-03 18:53:17 -07:00
8 changed files with 63 additions and 64 deletions

View File

@ -76,11 +76,5 @@ impl mlua::UserData for CFrame{
);
}
}
impl<'lua> mlua::FromLua<'lua> for CFrame{
fn from_lua(value:mlua::prelude::LuaValue<'lua>,_lua:&'lua mlua::prelude::Lua)->mlua::prelude::LuaResult<Self>{
match value{
mlua::Value::UserData(ud)=>ud.take()?,
other=>Err(mlua::Error::runtime(format!("Expected CFrame got {:?}",other))),
}
}
}
type_from_lua_userdata!(CFrame);

View File

@ -40,11 +40,4 @@ impl mlua::UserData for Color3{
fn add_methods<'lua,M:mlua::UserDataMethods<'lua,Self>>(methods:&mut M){
}
}
impl<'lua> mlua::FromLua<'lua> for Color3{
fn from_lua(value:mlua::prelude::LuaValue<'lua>,_lua:&'lua mlua::prelude::Lua)->mlua::prelude::LuaResult<Self>{
match value{
mlua::Value::UserData(ud)=>ud.take()?,
other=>Err(mlua::Error::runtime(format!("Expected Color3 got {:?}",other))),
}
}
}
type_from_lua_userdata!(Color3);

View File

@ -39,14 +39,7 @@ impl mlua::UserData for EnumItem{
});
}
}
impl<'lua> mlua::FromLua<'lua> for EnumItem{
fn from_lua(value:mlua::prelude::LuaValue<'lua>,_lua:&'lua mlua::prelude::Lua)->mlua::prelude::LuaResult<Self>{
match value{
mlua::Value::UserData(ud)=>ud.take()?,
other=>Err(mlua::Error::runtime(format!("Expected Enum got {:?}",other))),
}
}
}
type_from_lua_userdata!(EnumItem);
impl mlua::UserData for EnumItems{
fn add_fields<'lua,F:mlua::UserDataFields<'lua,Self>>(_fields:&mut F){
@ -61,14 +54,7 @@ impl mlua::UserData for EnumItems{
});
}
}
impl<'lua> mlua::FromLua<'lua> for EnumItems{
fn from_lua(value:mlua::prelude::LuaValue<'lua>,_lua:&'lua mlua::prelude::Lua)->mlua::prelude::LuaResult<Self>{
match value{
mlua::Value::UserData(ud)=>ud.take()?,
other=>Err(mlua::Error::runtime(format!("Expected Enum got {:?}",other))),
}
}
}
type_from_lua_userdata!(EnumItems);
impl mlua::UserData for Enum{
fn add_fields<'lua,F:mlua::UserDataFields<'lua,Self>>(_fields:&mut F){
@ -76,11 +62,4 @@ impl mlua::UserData for Enum{
fn add_methods<'lua,M:mlua::UserDataMethods<'lua,Self>>(_methods:&mut M){
}
}
impl<'lua> mlua::FromLua<'lua> for Enum{
fn from_lua(value:mlua::prelude::LuaValue<'lua>,_lua:&'lua mlua::prelude::Lua)->mlua::prelude::LuaResult<Self>{
match value{
mlua::Value::UserData(ud)=>ud.take()?,
other=>Err(mlua::Error::runtime(format!("Expected Enum got {:?}",other))),
}
}
}
type_from_lua_userdata!(Enum);

View File

@ -29,6 +29,16 @@ fn get_full_name(dom:&rbx_dom_weak::WeakDom,instance:&rbx_dom_weak::Instance)->S
full_name
}
//workaround until I have an enum of classes
struct Dereferent(Ref);
impl mlua::UserData for Dereferent{}
type_from_lua_userdata!(Dereferent);
impl Referent for Dereferent{
fn referent(&self)->Ref{
self.0
}
}
trait Referent{
fn referent(&self)->Ref;
fn get<'a>(&self,dom:&'a WeakDom)->mlua::Result<&'a rbx_dom_weak::Instance>{
@ -54,20 +64,16 @@ macro_rules! class{
self.referent
}
}
impl<'lua> mlua::FromLua<'lua> for $class{
fn from_lua(value:mlua::Value<'lua>,_lua:&'lua mlua::Lua)->mlua::Result<Self>{
match value{
mlua::Value::UserData(ud)=>ud.take(),
other=>Err(mlua::Error::runtime(format!("Expected {} got {:?}",stringify!($class),other))),
}
}
}
type_from_lua_userdata!($class);
};
}
macro_rules! class_composition{
($class:ident,($($superclass:ident),*))=>{
impl mlua::UserData for $class{
fn add_fields<'lua,F:mlua::UserDataFields<'lua,Self>>(fields:&mut F){
fields.add_field_method_get("Referent",|_,this|{
Ok(Dereferent(this.referent()))
});
$(
$superclass::composition_add_fields(fields);
)*
@ -93,9 +99,10 @@ impl Instance{
Ok(Instance::new(instance.parent()))
})
});
fields.add_field_method_set("Parent",|lua,this,val:Self|{
fields.add_field_method_set("Parent",|lua,this,val:mlua::AnyUserData|{
let Dereferent(referent)=mlua::AnyUserDataExt::get(&val,"Referent")?;
dom(lua,|dom|{
dom.transfer_within(this.referent(),val.referent);
dom.transfer_within(this.referent(),referent);
Ok(())
})
});
@ -150,10 +157,29 @@ impl Instance{
Ok(crate::context::class_is_a(instance.class.as_str(),classname.to_str()?))
})
);
methods.add_meta_function(mlua::MetaMethod::NewIndex,|lua,(this,index,value):(Self,mlua::String,mlua::Value)|
methods.add_meta_function(mlua::MetaMethod::Index,|lua,(this,index):(mlua::AnyUserData,mlua::String)|{
let index_str=index.to_str()?;
let dereferent:Dereferent=mlua::AnyUserDataExt::get(&this,"Referent")?;
dom(lua,|dom|{
//println!("__newindex t={this:?} i={index:?} v={value:?}");
let instance=this.get_mut(dom)?;
let instance=dereferent.get(dom)?;
//find a child with a matching name
let maybe_child=instance.children()
.iter()
.find(|&&r|
dom.get_by_ref(r)
.is_some_and(|instance|instance.name==index_str)
);
match maybe_child{
Some(&referent)=>Instance::new(referent).into_lua(lua),
None=>mlua::Value::Nil.into_lua(lua),
}
})
});
methods.add_meta_function(mlua::MetaMethod::NewIndex,|lua,(this,index,value):(mlua::AnyUserData,mlua::String,mlua::Value)|{
let dereferent:Dereferent=mlua::AnyUserDataExt::get(&this,"Referent")?;
dom(lua,|dom|{
let instance=dereferent.get_mut(dom)?;
//println!("__newindex t={} i={index:?} v={value:?}",instance.name);
let index_str=index.to_str()?;
let db=rbx_reflection_database::get();
let class=db.classes.get(instance.class.as_str()).ok_or(mlua::Error::runtime("Class missing"))?;
@ -179,7 +205,7 @@ impl Instance{
}
Ok(())
})
);
});
}
}

12
src/runner/macros.rs Normal file
View File

@ -0,0 +1,12 @@
macro_rules! type_from_lua_userdata{
($asd:ident)=>{
impl<'lua> mlua::FromLua<'lua> for $asd{
fn from_lua(value:mlua::Value<'lua>,_lua:&'lua mlua::Lua)->Result<Self,mlua::Error>{
match value{
mlua::Value::UserData(ud)=>ud.take(),
other=>Err(mlua::Error::runtime(format!("Expected {} got {:?}",stringify!($asd),other))),
}
}
}
};
}

View File

@ -1,3 +1,5 @@
#[macro_use]
mod macros;
mod runner;
mod r#enum;

View File

@ -16,8 +16,8 @@ pub enum Error{
impl std::fmt::Display for Error{
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
match self{
Self::Lua{source,error:mlua::Error::RuntimeError(s)}=>write!(f,"lua error: {s}\nsource:{source}"),
Self::RustLua(mlua::Error::RuntimeError(s))=>write!(f,"rust-side lua error: {s}"),
Self::Lua{source,error}=>write!(f,"lua error: source:\n{source}\n{error}"),
Self::RustLua(error)=>write!(f,"rust-side lua error: {error}"),
other=>write!(f,"{other:?}"),
}
}

View File

@ -73,11 +73,4 @@ impl mlua::UserData for Vector3{
}
}
impl<'lua> mlua::FromLua<'lua> for Vector3{
fn from_lua(value:mlua::prelude::LuaValue<'lua>,_lua:&'lua mlua::prelude::Lua)->mlua::prelude::LuaResult<Self>{
match value{
mlua::Value::UserData(ud)=>ud.take(),
other=>Err(mlua::Error::runtime(format!("Expected Vector3 got {:?}",other))),
}
}
}
type_from_lua_userdata!(Vector3);