File tree Expand file tree Collapse file tree 5 files changed +49
-16
lines changed
itest/rust/src/object_tests Expand file tree Collapse file tree 5 files changed +49
-16
lines changed Original file line number Diff line number Diff line change @@ -206,6 +206,18 @@ pub trait IndexEnum: EngineEnum {
206
206
}
207
207
}
208
208
209
+ /// Trait that's implemented for user-defined classes that provide a `#[base]` field.
210
+ ///
211
+ /// Gives direct access to the containing `Gd<Self>` from `Self`.
212
+ // Possible alternative for builder APIs, although even less ergonomic: Base<T> could be Base<T, Self> and return Gd<Self>.
213
+ pub trait WithBaseField : GodotClass {
214
+ /// Returns the `Gd` pointer containing this object.
215
+ ///
216
+ /// This is intended to be stored or passed to engine methods. You cannot call `bind()` or `bind_mut()` on it, while the method
217
+ /// calling `to_gd()` is still running; that would lead to a double borrow panic.
218
+ fn to_gd ( & self ) -> Gd < Self > ;
219
+ }
220
+
209
221
// ----------------------------------------------------------------------------------------------------------------------------------------------
210
222
211
223
/// Capability traits, providing dedicated functionalities for Godot classes
@@ -257,17 +269,6 @@ pub mod cap {
257
269
}
258
270
}
259
271
260
- /// Trait that's implemented for user-defined classes that provide a `#[base]` field.
261
- ///
262
- /// Gives direct access to the base pointer without going through upcast FFI.
263
- pub trait WithBaseField : GodotClass {
264
- #[ doc( hidden) ]
265
- fn __godot_base ( & self ) -> & Gd < Self :: Base > ;
266
-
267
- #[ doc( hidden) ]
268
- fn __godot_base_mut ( & mut self ) -> & mut Gd < Self :: Base > ;
269
- }
270
-
271
272
// TODO Evaluate whether we want this public or not
272
273
#[ doc( hidden) ]
273
274
pub trait GodotToString : GodotClass {
Original file line number Diff line number Diff line change @@ -50,6 +50,18 @@ pub fn derive_godot_class(decl: Declaration) -> ParseResult<TokenStream> {
50
50
quote ! { }
51
51
} ;
52
52
53
+ let godot_withbase_impl = if let Some ( Field { name, .. } ) = & fields. base_field {
54
+ quote ! {
55
+ impl :: godot:: obj:: WithBaseField for #class_name {
56
+ fn to_gd( & self ) -> Gd <Self > {
57
+ :: godot:: obj:: Gd :: clone( & * self . #name) . cast( )
58
+ }
59
+ }
60
+ }
61
+ } else {
62
+ quote ! { }
63
+ } ;
64
+
53
65
let ( godot_init_impl, create_fn, recreate_fn) ;
54
66
if struct_cfg. has_generated_init {
55
67
godot_init_impl = make_godot_init_impl ( class_name, fields) ;
@@ -78,11 +90,10 @@ pub fn derive_godot_class(decl: Declaration) -> ParseResult<TokenStream> {
78
90
:: godot:: builtin:: meta:: ClassName :: from_ascii_cstr( #class_name_cstr)
79
91
}
80
92
}
81
- impl :: godot:: obj:: UserClass for #class_name {
82
-
83
- }
93
+ impl :: godot:: obj:: UserClass for #class_name { }
84
94
85
95
#godot_init_impl
96
+ #godot_withbase_impl
86
97
#godot_exports_impl
87
98
#config_impl
88
99
Original file line number Diff line number Diff line change @@ -100,7 +100,7 @@ use crate::util::ident;
100
100
/// #[class(base = Node2D)]
101
101
/// struct MyStruct {
102
102
/// #[base]
103
- /// base: Gd <Node2D>,
103
+ /// base: Base <Node2D>,
104
104
/// }
105
105
/// ```
106
106
///
Original file line number Diff line number Diff line change @@ -235,5 +235,6 @@ pub mod prelude {
235
235
// Make trait methods available
236
236
pub use super :: engine:: NodeExt as _;
237
237
pub use super :: obj:: EngineEnum as _;
238
- pub use super :: obj:: UserClass as _; // new_gd(), self_gd()
238
+ pub use super :: obj:: UserClass as _; // new_gd(), alloc_gd()
239
+ pub use super :: obj:: WithBaseField as _; // to_gd()
239
240
}
Original file line number Diff line number Diff line change @@ -93,6 +93,19 @@ fn base_with_init() {
93
93
obj. free ( ) ;
94
94
}
95
95
96
+ #[ itest]
97
+ fn base_gd_self ( ) {
98
+ let obj = Based :: alloc_gd ( ) ;
99
+ let obj2 = obj. bind ( ) . access_gd_self ( ) ;
100
+
101
+ assert_eq ! ( obj, obj2) ;
102
+ assert_eq ! ( obj. instance_id( ) , obj2. instance_id( ) ) ;
103
+
104
+ obj. free ( ) ;
105
+ }
106
+
107
+ // ----------------------------------------------------------------------------------------------------------------------------------------------
108
+
96
109
#[ derive( GodotClass ) ]
97
110
#[ class( init, base=Node2D ) ]
98
111
struct Based {
@@ -102,6 +115,13 @@ struct Based {
102
115
i : i32 ,
103
116
}
104
117
118
+ impl Based {
119
+ fn access_gd_self ( & self ) -> Gd < Self > {
120
+ use godot:: obj:: WithBaseField as _;
121
+ self . to_gd ( )
122
+ }
123
+ }
124
+
105
125
#[ derive( GodotClass ) ]
106
126
#[ class( init, base=Node2D ) ]
107
127
struct Baseless {
You can’t perform that action at this time.
0 commit comments