@@ -7,7 +7,7 @@ use std::os::raw::c_void;
7
7
use std:: string:: String as StdString ;
8
8
9
9
use crate :: error:: { Error , Result } ;
10
- use crate :: state:: { Lua , RawLua } ;
10
+ use crate :: state:: { Lua , LuaGuard } ;
11
11
use crate :: traits:: { FromLua , FromLuaMulti , IntoLua , IntoLuaMulti } ;
12
12
use crate :: types:: { Callback , MaybeSend } ;
13
13
use crate :: userdata:: { AnyUserData , MetaMethod , UserData , UserDataFields , UserDataMethods , UserDataStorage } ;
@@ -26,8 +26,6 @@ use std::rc::Rc;
26
26
#[ cfg( feature = "userdata-wrappers" ) ]
27
27
use std:: sync:: { Arc , Mutex , RwLock } ;
28
28
29
- type StaticFieldCallback = Box < dyn FnOnce ( & RawLua ) -> Result < ( ) > + ' static > ;
30
-
31
29
#[ derive( Clone , Copy ) ]
32
30
enum UserDataTypeId {
33
31
Shared ( TypeId ) ,
@@ -51,17 +49,18 @@ enum UserDataTypeId {
51
49
52
50
/// Handle to registry for userdata methods and metamethods.
53
51
pub struct UserDataRegistry < T > {
52
+ lua : LuaGuard ,
54
53
raw : RawUserDataRegistry ,
55
54
ud_type_id : UserDataTypeId ,
56
55
_type : PhantomData < T > ,
57
56
}
58
57
59
58
pub ( crate ) struct RawUserDataRegistry {
60
59
// Fields
61
- pub ( crate ) fields : Vec < ( String , StaticFieldCallback ) > ,
60
+ pub ( crate ) fields : Vec < ( String , Result < Value > ) > ,
62
61
pub ( crate ) field_getters : Vec < ( String , Callback ) > ,
63
62
pub ( crate ) field_setters : Vec < ( String , Callback ) > ,
64
- pub ( crate ) meta_fields : Vec < ( String , StaticFieldCallback ) > ,
63
+ pub ( crate ) meta_fields : Vec < ( String , Result < Value > ) > ,
65
64
66
65
// Methods
67
66
pub ( crate ) methods : Vec < ( String , Callback ) > ,
@@ -102,17 +101,17 @@ impl UserDataTypeId {
102
101
103
102
impl < T > UserDataRegistry < T > {
104
103
#[ 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) )
107
106
}
108
107
109
108
#[ 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 ) )
112
111
}
113
112
114
113
#[ inline( always) ]
115
- fn with_type_id ( ud_type_id : UserDataTypeId ) -> Self {
114
+ fn with_type_id ( lua : & Lua , ud_type_id : UserDataTypeId ) -> Self {
116
115
let raw = RawUserDataRegistry {
117
116
fields : Vec :: new ( ) ,
118
117
field_getters : Vec :: new ( ) ,
@@ -130,6 +129,7 @@ impl<T> UserDataRegistry<T> {
130
129
} ;
131
130
132
131
UserDataRegistry {
132
+ lua : lua. lock_arc ( ) ,
133
133
raw,
134
134
ud_type_id,
135
135
_type : PhantomData ,
@@ -548,10 +548,7 @@ impl<T> UserDataFields<T> for UserDataRegistry<T> {
548
548
V : IntoLua + ' static ,
549
549
{
550
550
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 ( ) ) ) ) ;
555
552
}
556
553
557
554
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> {
598
595
where
599
596
V : IntoLua + ' static ,
600
597
{
598
+ let lua = self . lua . lua ( ) ;
601
599
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) ) ;
608
602
}
609
603
610
604
fn add_meta_field_with < F , R > ( & mut self , name : impl ToString , f : F )
611
605
where
612
606
F : FnOnce ( & Lua ) -> Result < R > + ' static ,
613
607
R : IntoLua ,
614
608
{
609
+ let lua = self . lua . lua ( ) ;
615
610
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) ) ;
623
613
}
624
614
}
625
615
@@ -803,7 +793,7 @@ macro_rules! lua_userdata_impl {
803
793
( $type: ty, $type_id: expr) => {
804
794
impl <T : UserData + ' static > UserData for $type {
805
795
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) ;
807
797
T :: register( & mut orig_registry) ;
808
798
809
799
// Copy all fields, methods, etc. from the original registry
@@ -841,3 +831,9 @@ lua_userdata_impl!(Arc<RwLock<T>> => ArcRwLock);
841
831
lua_userdata_impl ! ( Arc <parking_lot:: Mutex <T >> => ArcParkingLotMutex ) ;
842
832
#[ cfg( feature = "userdata-wrappers" ) ]
843
833
lua_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