use rbx_dom_weak::WeakDom; use super::vector3::Vector3; pub struct Instance{ referent:rbx_types::Ref, } impl From for Instance{ fn from(value:crate::script::Script)->Self{ Self{referent:value.script} } } impl Instance{ pub const fn new(referent:rbx_types::Ref)->Self{ Self{referent} } pub fn get<'a>(&'a self,dom:&'a WeakDom)->mlua::Result<&'a rbx_dom_weak::Instance>{ dom.get_by_ref(self.referent).ok_or(mlua::Error::runtime("Instance missing")) } pub fn get_mut<'a>(&'a self,dom:&'a mut WeakDom)->mlua::Result<&'a mut rbx_dom_weak::Instance>{ dom.get_by_ref_mut(self.referent).ok_or(mlua::Error::runtime("Instance missing")) } } // LMAO look at this function! fn dom(lua:&mlua::Lua,mut f:impl FnMut(&mut WeakDom)->mlua::Result)->mlua::Result{ f(&mut *lua.app_data_mut::().ok_or(mlua::Error::runtime("DataModel missing"))?) } impl mlua::UserData for Instance{ fn add_fields<'lua,F:mlua::UserDataFields<'lua,Self>>(fields:&mut F){ fields.add_field_method_get("Parent",|lua,this|{ dom(lua,|dom|{ let instance=this.get(dom)?; Ok(Instance::new(instance.parent())) }) }); fields.add_field_method_set("Parent",|lua,this,val:Self|{ dom(lua,|dom|{ dom.transfer_within(this.referent,val.referent); Ok(()) }) }); } fn add_methods<'lua,M:mlua::UserDataMethods<'lua,Self>>(methods:&mut M){ methods.add_meta_function(mlua::MetaMethod::NewIndex,|lua,(this,index,value):(Self,mlua::String,mlua::Value)| dom(lua,|dom|{ let instance=this.get_mut(dom)?; let index_str=index.to_str()?; let class=rbx_reflection_database::get().classes.get(instance.class.as_str()).ok_or(mlua::Error::runtime("Class missing"))?; let property=class.default_properties.get(index_str).ok_or(mlua::Error::runtime(format!("Property '{index_str}' missing on class '{}'",class.name)))?; match property{ rbx_types::Variant::Vector3(_)=>{ let typed_value:Vector3=value.as_userdata().ok_or(mlua::Error::runtime("Expected Userdata"))?.take()?; instance.properties.insert(index_str.to_owned(),rbx_types::Variant::Vector3(typed_value.into())); }, rbx_types::Variant::Float64(_)=>{ let typed_value:f64=value.as_f64().ok_or(mlua::Error::runtime("Expected f64"))?; instance.properties.insert(index_str.to_owned(),rbx_types::Variant::Float64(typed_value)); }, _=>unimplemented!(), } Ok(()) }) ); } } impl<'lua> mlua::FromLua<'lua> for Instance{ fn from_lua(value:mlua::prelude::LuaValue<'lua>,_lua:&'lua mlua::prelude::Lua)->mlua::prelude::LuaResult{ match value{ mlua::Value::UserData(ud)=>ud.take(), other=>Err(mlua::Error::runtime(format!("Expected Instance got {:?}",other))), } } }