@@ -7,7 +7,7 @@ use std::os::raw::c_void;
77use std:: string:: String as StdString ;
88
99use crate :: error:: { Error , Result } ;
10- use crate :: state:: { Lua , RawLua } ;
10+ use crate :: state:: { Lua , LuaGuard } ;
1111use crate :: traits:: { FromLua , FromLuaMulti , IntoLua , IntoLuaMulti } ;
1212use crate :: types:: { Callback , MaybeSend } ;
1313use crate :: userdata:: { AnyUserData , MetaMethod , UserData , UserDataFields , UserDataMethods , UserDataStorage } ;
@@ -26,8 +26,6 @@ use std::rc::Rc;
2626#[ cfg( feature = "userdata-wrappers" ) ]
2727use std:: sync:: { Arc , Mutex , RwLock } ;
2828
29- type StaticFieldCallback = Box < dyn FnOnce ( & RawLua ) -> Result < ( ) > + ' static > ;
30-
3129#[ derive( Clone , Copy ) ]
3230enum UserDataTypeId {
3331 Shared ( TypeId ) ,
@@ -51,17 +49,18 @@ enum UserDataTypeId {
5149
5250/// Handle to registry for userdata methods and metamethods.
5351pub struct UserDataRegistry < T > {
52+ lua : LuaGuard ,
5453 raw : RawUserDataRegistry ,
5554 ud_type_id : UserDataTypeId ,
5655 _type : PhantomData < T > ,
5756}
5857
5958pub ( crate ) struct RawUserDataRegistry {
6059 // Fields
61- pub ( crate ) fields : Vec < ( String , StaticFieldCallback ) > ,
60+ pub ( crate ) fields : Vec < ( String , Result < Value > ) > ,
6261 pub ( crate ) field_getters : Vec < ( String , Callback ) > ,
6362 pub ( crate ) field_setters : Vec < ( String , Callback ) > ,
64- pub ( crate ) meta_fields : Vec < ( String , StaticFieldCallback ) > ,
63+ pub ( crate ) meta_fields : Vec < ( String , Result < Value > ) > ,
6564
6665 // Methods
6766 pub ( crate ) methods : Vec < ( String , Callback ) > ,
@@ -102,17 +101,17 @@ impl UserDataTypeId {
102101
103102impl < T > UserDataRegistry < T > {
104103 #[ inline( always) ]
105- pub ( crate ) fn new ( type_id : TypeId ) -> Self {
106- Self :: with_type_id ( UserDataTypeId :: Shared ( type_id) )
104+ pub ( crate ) fn new ( lua : & Lua , type_id : TypeId ) -> Self {
105+ Self :: with_type_id ( lua , UserDataTypeId :: Shared ( type_id) )
107106 }
108107
109108 #[ inline( always) ]
110- pub ( crate ) fn new_unique ( ud_ptr : * mut c_void ) -> Self {
111- Self :: with_type_id ( UserDataTypeId :: Unique ( ud_ptr as usize ) )
109+ pub ( crate ) fn new_unique ( lua : & Lua , ud_ptr : * mut c_void ) -> Self {
110+ Self :: with_type_id ( lua , UserDataTypeId :: Unique ( ud_ptr as usize ) )
112111 }
113112
114113 #[ inline( always) ]
115- fn with_type_id ( ud_type_id : UserDataTypeId ) -> Self {
114+ fn with_type_id ( lua : & Lua , ud_type_id : UserDataTypeId ) -> Self {
116115 let raw = RawUserDataRegistry {
117116 fields : Vec :: new ( ) ,
118117 field_getters : Vec :: new ( ) ,
@@ -130,6 +129,7 @@ impl<T> UserDataRegistry<T> {
130129 } ;
131130
132131 UserDataRegistry {
132+ lua : lua. lock_arc ( ) ,
133133 raw,
134134 ud_type_id,
135135 _type : PhantomData ,
@@ -548,10 +548,7 @@ impl<T> UserDataFields<T> for UserDataRegistry<T> {
548548 V : IntoLua + ' static ,
549549 {
550550 let name = name. to_string ( ) ;
551- self . raw . fields . push ( (
552- name,
553- Box :: new ( move |rawlua| unsafe { value. push_into_stack ( rawlua) } ) ,
554- ) ) ;
551+ self . raw . fields . push ( ( name, value. into_lua ( self . lua . lua ( ) ) ) ) ;
555552 }
556553
557554 fn add_field_method_get < M , R > ( & mut self , name : impl ToString , method : M )
@@ -598,28 +595,21 @@ impl<T> UserDataFields<T> for UserDataRegistry<T> {
598595 where
599596 V : IntoLua + ' static ,
600597 {
598+ let lua = self . lua . lua ( ) ;
601599 let name = name. to_string ( ) ;
602- self . raw . meta_fields . push ( (
603- name. clone ( ) ,
604- Box :: new ( move |rawlua| unsafe {
605- Self :: check_meta_field ( rawlua. lua ( ) , & name, value) ?. push_into_stack ( rawlua)
606- } ) ,
607- ) ) ;
600+ let field = Self :: check_meta_field ( lua, & name, value) . and_then ( |v| v. into_lua ( lua) ) ;
601+ self . raw . meta_fields . push ( ( name, field) ) ;
608602 }
609603
610604 fn add_meta_field_with < F , R > ( & mut self , name : impl ToString , f : F )
611605 where
612606 F : FnOnce ( & Lua ) -> Result < R > + ' static ,
613607 R : IntoLua ,
614608 {
609+ let lua = self . lua . lua ( ) ;
615610 let name = name. to_string ( ) ;
616- self . raw . meta_fields . push ( (
617- name. clone ( ) ,
618- Box :: new ( move |rawlua| unsafe {
619- let lua = rawlua. lua ( ) ;
620- Self :: check_meta_field ( lua, & name, f ( lua) ?) ?. push_into_stack ( rawlua)
621- } ) ,
622- ) ) ;
611+ let field = f ( lua) . and_then ( |v| Self :: check_meta_field ( lua, & name, v) . and_then ( |v| v. into_lua ( lua) ) ) ;
612+ self . raw . meta_fields . push ( ( name, field) ) ;
623613 }
624614}
625615
@@ -803,7 +793,7 @@ macro_rules! lua_userdata_impl {
803793 ( $type: ty, $type_id: expr) => {
804794 impl <T : UserData + ' static > UserData for $type {
805795 fn register( registry: & mut UserDataRegistry <Self >) {
806- let mut orig_registry = UserDataRegistry :: with_type_id( $type_id) ;
796+ let mut orig_registry = UserDataRegistry :: with_type_id( registry . lua . lua ( ) , $type_id) ;
807797 T :: register( & mut orig_registry) ;
808798
809799 // Copy all fields, methods, etc. from the original registry
@@ -841,3 +831,9 @@ lua_userdata_impl!(Arc<RwLock<T>> => ArcRwLock);
841831lua_userdata_impl ! ( Arc <parking_lot:: Mutex <T >> => ArcParkingLotMutex ) ;
842832#[ cfg( feature = "userdata-wrappers" ) ]
843833lua_userdata_impl ! ( Arc <parking_lot:: RwLock <T >> => ArcParkingLotRwLock ) ;
834+
835+ #[ cfg( test) ]
836+ mod assertions {
837+ #[ cfg( feature = "send" ) ]
838+ static_assertions:: assert_impl_all!( super :: RawUserDataRegistry : Send ) ;
839+ }
0 commit comments