1
1
use std:: cell:: Cell ;
2
2
use std:: rc:: Rc ;
3
+ use std:: sync:: Arc ;
3
4
4
5
use mlua:: {
5
6
AnyUserData , Error , Function , Lua , MetaMethod , Result , String , UserData , UserDataFields ,
@@ -26,84 +27,13 @@ fn scope_func() -> Result<()> {
26
27
assert_eq ! ( Rc :: strong_count( & rc) , 1 ) ;
27
28
28
29
match lua. globals ( ) . get :: < _ , Function > ( "bad" ) ?. call :: < _ , ( ) > ( ( ) ) {
29
- Err ( Error :: CallbackError { .. } ) => { }
30
- r => panic ! ( "improper return for destructed function: {:?}" , r) ,
31
- } ;
32
-
33
- Ok ( ( ) )
34
- }
35
-
36
- #[ test]
37
- fn scope_drop ( ) -> Result < ( ) > {
38
- let lua = Lua :: new ( ) ;
39
-
40
- struct MyUserdata ( Rc < ( ) > ) ;
41
- impl UserData for MyUserdata {
42
- fn add_methods < ' lua , M : UserDataMethods < ' lua , Self > > ( methods : & mut M ) {
43
- methods. add_method ( "method" , |_, _, ( ) | Ok ( ( ) ) ) ;
44
- }
45
- }
46
-
47
- let rc = Rc :: new ( ( ) ) ;
48
-
49
- lua. scope ( |scope| {
50
- lua. globals ( )
51
- . set ( "static_ud" , scope. create_userdata ( MyUserdata ( rc. clone ( ) ) ) ?) ?;
52
- assert_eq ! ( Rc :: strong_count( & rc) , 2 ) ;
53
- Ok ( ( ) )
54
- } ) ?;
55
- assert_eq ! ( Rc :: strong_count( & rc) , 1 ) ;
56
-
57
- match lua. load ( "static_ud:method()" ) . exec ( ) {
58
- Err ( Error :: CallbackError { ref cause, .. } ) => match cause. as_ref ( ) {
59
- Error :: CallbackDestructed => { }
60
- e => panic ! ( "expected CallbackDestructed, got {:?}" , e) ,
61
- } ,
62
- r => panic ! ( "improper return for destructed userdata: {:?}" , r) ,
63
- } ;
64
-
65
- let static_ud = lua. globals ( ) . get :: < _ , AnyUserData > ( "static_ud" ) ?;
66
- match static_ud. borrow :: < MyUserdata > ( ) {
67
- Ok ( _) => panic ! ( "borrowed destructed userdata" ) ,
68
- Err ( Error :: UserDataDestructed ) => { }
69
- Err ( e) => panic ! ( "expected UserDataDestructed, got {:?}" , e) ,
70
- }
71
-
72
- // Check non-static UserData drop
73
- struct MyUserDataRef < ' a > ( & ' a Cell < i64 > ) ;
74
-
75
- impl < ' a > UserData for MyUserDataRef < ' a > {
76
- fn add_methods < ' lua , M : UserDataMethods < ' lua , Self > > ( methods : & mut M ) {
77
- methods. add_method ( "inc" , |_, data, ( ) | {
78
- data. 0 . set ( data. 0 . get ( ) + 1 ) ;
79
- Ok ( ( ) )
80
- } ) ;
81
- }
82
- }
83
-
84
- let i = Cell :: new ( 1 ) ;
85
- lua. scope ( |scope| {
86
- lua. globals ( ) . set (
87
- "nonstatic_ud" ,
88
- scope. create_nonstatic_userdata ( MyUserDataRef ( & i) ) ?,
89
- )
90
- } ) ?;
91
-
92
- match lua. load ( "nonstatic_ud:inc(1)" ) . exec ( ) {
93
- Err ( Error :: CallbackError { ref cause, .. } ) => match cause. as_ref ( ) {
30
+ Err ( Error :: CallbackError { ref cause, .. } ) => match * cause. as_ref ( ) {
94
31
Error :: CallbackDestructed => { }
95
- e => panic ! ( "expected CallbackDestructed, got {:?}" , e ) ,
32
+ ref err => panic ! ( "wrong error type {:?}" , err ) ,
96
33
} ,
97
- r => panic ! ( "improper return for destructed userdata : {:?}" , r) ,
34
+ r => panic ! ( "improper return for destructed function : {:?}" , r) ,
98
35
} ;
99
36
100
- let nonstatic_ud = lua. globals ( ) . get :: < _ , AnyUserData > ( "nonstatic_ud" ) ?;
101
- match nonstatic_ud. borrow :: < MyUserDataRef > ( ) {
102
- Ok ( _) => panic ! ( "borrowed destructed userdata" ) ,
103
- Err ( Error :: UserDataDestructed ) => { }
104
- Err ( e) => panic ! ( "expected UserDataDestructed, got {:?}" , e) ,
105
- }
106
-
107
37
Ok ( ( ) )
108
38
}
109
39
@@ -126,7 +56,7 @@ fn scope_capture() -> Result<()> {
126
56
}
127
57
128
58
#[ test]
129
- fn outer_lua_access ( ) -> Result < ( ) > {
59
+ fn scope_outer_lua_access ( ) -> Result < ( ) > {
130
60
let lua = Lua :: new ( ) ;
131
61
132
62
let table = lua. create_table ( ) ?;
@@ -309,3 +239,103 @@ fn scope_userdata_mismatch() -> Result<()> {
309
239
310
240
Ok ( ( ) )
311
241
}
242
+
243
+ #[ test]
244
+ fn scope_userdata_drop ( ) -> Result < ( ) > {
245
+ let lua = Lua :: new ( ) ;
246
+
247
+ struct MyUserData ( Rc < ( ) > ) ;
248
+
249
+ impl UserData for MyUserData {
250
+ fn add_methods < ' lua , M : UserDataMethods < ' lua , Self > > ( methods : & mut M ) {
251
+ methods. add_method ( "method" , |_, _, ( ) | Ok ( ( ) ) ) ;
252
+ }
253
+ }
254
+
255
+ struct MyUserDataArc ( Arc < ( ) > ) ;
256
+
257
+ impl UserData for MyUserDataArc { }
258
+
259
+ let rc = Rc :: new ( ( ) ) ;
260
+ let arc = Arc :: new ( ( ) ) ;
261
+ lua. scope ( |scope| {
262
+ let ud = scope. create_userdata ( MyUserData ( rc. clone ( ) ) ) ?;
263
+ ud. set_user_value ( MyUserDataArc ( arc. clone ( ) ) ) ?;
264
+ lua. globals ( ) . set ( "ud" , ud) ?;
265
+ assert_eq ! ( Rc :: strong_count( & rc) , 2 ) ;
266
+ assert_eq ! ( Arc :: strong_count( & arc) , 2 ) ;
267
+ Ok ( ( ) )
268
+ } ) ?;
269
+
270
+ lua. gc_collect ( ) ?;
271
+ assert_eq ! ( Rc :: strong_count( & rc) , 1 ) ;
272
+ assert_eq ! ( Arc :: strong_count( & arc) , 1 ) ;
273
+
274
+ match lua. load ( "ud:method()" ) . exec ( ) {
275
+ Err ( Error :: CallbackError { ref cause, .. } ) => match cause. as_ref ( ) {
276
+ Error :: CallbackDestructed => { }
277
+ err => panic ! ( "expected CallbackDestructed, got {:?}" , err) ,
278
+ } ,
279
+ r => panic ! ( "improper return for destructed userdata: {:?}" , r) ,
280
+ } ;
281
+
282
+ let ud = lua. globals ( ) . get :: < _ , AnyUserData > ( "ud" ) ?;
283
+ match ud. borrow :: < MyUserData > ( ) {
284
+ Ok ( _) => panic ! ( "succesfull borrow for destructed userdata" ) ,
285
+ Err ( Error :: UserDataDestructed ) => { }
286
+ Err ( err) => panic ! ( "improper borrow error for destructed userdata: {:?}" , err) ,
287
+ }
288
+
289
+ Ok ( ( ) )
290
+ }
291
+
292
+ #[ test]
293
+ fn scope_nonstatic_userdata_drop ( ) -> Result < ( ) > {
294
+ let lua = Lua :: new ( ) ;
295
+
296
+ struct MyUserData < ' a > ( & ' a Cell < i64 > ) ;
297
+
298
+ impl < ' a > UserData for MyUserData < ' a > {
299
+ fn add_methods < ' lua , M : UserDataMethods < ' lua , Self > > ( methods : & mut M ) {
300
+ methods. add_method ( "inc" , |_, data, ( ) | {
301
+ data. 0 . set ( data. 0 . get ( ) + 1 ) ;
302
+ Ok ( ( ) )
303
+ } ) ;
304
+ }
305
+ }
306
+
307
+ struct MyUserDataArc ( Arc < ( ) > ) ;
308
+
309
+ impl UserData for MyUserDataArc { }
310
+
311
+ let i = Cell :: new ( 1 ) ;
312
+ let arc = Arc :: new ( ( ) ) ;
313
+ lua. scope ( |scope| {
314
+ let ud = scope. create_nonstatic_userdata ( MyUserData ( & i) ) ?;
315
+ ud. set_user_value ( MyUserDataArc ( arc. clone ( ) ) ) ?;
316
+ lua. globals ( ) . set ( "ud" , ud) ?;
317
+ lua. load ( "ud:inc()" ) . exec ( ) ?;
318
+ assert_eq ! ( Arc :: strong_count( & arc) , 2 ) ;
319
+ Ok ( ( ) )
320
+ } ) ?;
321
+
322
+ lua. gc_collect ( ) ?;
323
+ assert_eq ! ( Arc :: strong_count( & arc) , 1 ) ;
324
+
325
+ match lua. load ( "ud:inc()" ) . exec ( ) {
326
+ Err ( Error :: CallbackError { ref cause, .. } ) => match cause. as_ref ( ) {
327
+ Error :: CallbackDestructed => { }
328
+ err => panic ! ( "expected CallbackDestructed, got {:?}" , err) ,
329
+ } ,
330
+ r => panic ! ( "improper return for destructed userdata: {:?}" , r) ,
331
+ } ;
332
+
333
+ let ud = lua. globals ( ) . get :: < _ , AnyUserData > ( "ud" ) ?;
334
+ match ud. borrow :: < MyUserData > ( ) {
335
+ Ok ( _) => panic ! ( "succesfull borrow for destructed userdata" ) ,
336
+ Err ( Error :: UserDataDestructed ) => { }
337
+ Err ( err) => panic ! ( "improper borrow error for destructed userdata: {:?}" , err) ,
338
+ }
339
+
340
+ Ok ( ( ) )
341
+ }
0 commit comments