2024-09-19 01:47:38 +00:00
use rbx_dom_weak ::WeakDom ;
use super ::vector3 ::Vector3 ;
pub struct Instance {
referent :rbx_types ::Ref ,
}
impl From < crate ::script ::Script > 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 < T > ( lua :& mlua ::Lua , mut f :impl FnMut ( & mut WeakDom ) ->mlua ::Result < T > ) ->mlua ::Result < T > {
2024-09-20 20:51:17 +00:00
let mut dom = lua . app_data_mut ::< & 'static mut WeakDom > ( ) . ok_or ( mlua ::Error ::runtime ( " DataModel missing " ) ) ? ;
f ( & mut * dom )
2024-09-19 01:47:38 +00:00
}
2024-09-21 00:54:16 +00:00
fn coerce_float32 ( value :& mlua ::Value ) ->Option < f32 > {
2024-09-19 03:16:14 +00:00
match value {
& mlua ::Value ::Integer ( i ) = > Some ( i as f32 ) ,
& mlua ::Value ::Number ( f ) = > Some ( f as f32 ) ,
_ = > None ,
}
}
2024-09-19 01:47:38 +00:00
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 ) {
2024-09-19 03:16:14 +00:00
methods . add_method ( " GetChildren " , | lua , this , _ :( ) |
dom ( lua , | dom | {
let instance = this . get ( dom ) ? ;
let children :Vec < _ > = instance
. children ( )
. iter ( )
. copied ( )
. map ( Instance ::new )
. collect ( ) ;
Ok ( children )
} )
) ;
2024-09-19 03:16:28 +00:00
methods . add_method ( " GetDescendants " , | lua , this , _ :( ) |
dom ( lua , | dom | {
let children :Vec < _ > = dom
. descendants_of ( this . referent )
. map ( | instance |
Instance ::new ( instance . referent ( ) )
)
. collect ( ) ;
Ok ( children )
} )
) ;
2024-09-19 03:16:14 +00:00
methods . add_method ( " IsA " , | lua , this , classname :mlua ::String |
dom ( lua , | dom | {
let instance = this . get ( dom ) ? ;
Ok ( crate ::context ::class_is_a ( instance . class . as_str ( ) , classname . to_str ( ) ? ) )
} )
) ;
2024-09-19 01:47:38 +00:00
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 ( ) ? ;
2024-09-21 00:54:43 +00:00
let db = rbx_reflection_database ::get ( ) ;
let class = db . classes . get ( instance . class . as_str ( ) ) . ok_or ( mlua ::Error ::runtime ( " Class missing " ) ) ? ;
let property = db . find_default_property ( class , index_str ) . ok_or ( mlua ::Error ::runtime ( format! ( " Property ' {index_str} ' missing on class ' {} ' " , class . name ) ) ) ? ;
2024-09-19 01:47:38 +00:00
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 ( ) ) ) ;
} ,
2024-09-19 03:16:14 +00:00
rbx_types ::Variant ::Float32 ( _ ) = > {
2024-09-21 00:54:16 +00:00
let typed_value :f32 = coerce_float32 ( & value ) . ok_or ( mlua ::Error ::runtime ( " Expected f32 " ) ) ? ;
2024-09-19 03:16:14 +00:00
instance . properties . insert ( index_str . to_owned ( ) , rbx_types ::Variant ::Float32 ( typed_value ) ) ;
2024-09-19 01:47:38 +00:00
} ,
2024-09-19 03:16:14 +00:00
other = > println! ( " Unimplemented property type: {other:?} " ) ,
2024-09-19 01:47:38 +00:00
}
Ok ( ( ) )
} )
) ;
}
}
impl < ' lua > mlua ::FromLua < ' lua > for Instance {
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 Instance got {:?} " , other ) ) ) ,
}
}
}