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 {
206206 }
207207}
208208
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+
209221// ----------------------------------------------------------------------------------------------------------------------------------------------
210222
211223/// Capability traits, providing dedicated functionalities for Godot classes
@@ -257,17 +269,6 @@ pub mod cap {
257269 }
258270 }
259271
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-
271272 // TODO Evaluate whether we want this public or not
272273 #[ doc( hidden) ]
273274 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> {
5050 quote ! { }
5151 } ;
5252
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+
5365 let ( godot_init_impl, create_fn, recreate_fn) ;
5466 if struct_cfg. has_generated_init {
5567 godot_init_impl = make_godot_init_impl ( class_name, fields) ;
@@ -78,11 +90,10 @@ pub fn derive_godot_class(decl: Declaration) -> ParseResult<TokenStream> {
7890 :: godot:: builtin:: meta:: ClassName :: from_ascii_cstr( #class_name_cstr)
7991 }
8092 }
81- impl :: godot:: obj:: UserClass for #class_name {
82-
83- }
93+ impl :: godot:: obj:: UserClass for #class_name { }
8494
8595 #godot_init_impl
96+ #godot_withbase_impl
8697 #godot_exports_impl
8798 #config_impl
8899
Original file line number Diff line number Diff line change @@ -100,7 +100,7 @@ use crate::util::ident;
100100/// #[class(base = Node2D)]
101101/// struct MyStruct {
102102/// #[base]
103- /// base: Gd <Node2D>,
103+ /// base: Base <Node2D>,
104104/// }
105105/// ```
106106///
Original file line number Diff line number Diff line change @@ -235,5 +235,6 @@ pub mod prelude {
235235 // Make trait methods available
236236 pub use super :: engine:: NodeExt as _;
237237 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()
239240}
Original file line number Diff line number Diff line change @@ -93,6 +93,19 @@ fn base_with_init() {
9393 obj. free ( ) ;
9494}
9595
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+
96109#[ derive( GodotClass ) ]
97110#[ class( init, base=Node2D ) ]
98111struct Based {
@@ -102,6 +115,13 @@ struct Based {
102115 i : i32 ,
103116}
104117
118+ impl Based {
119+ fn access_gd_self ( & self ) -> Gd < Self > {
120+ use godot:: obj:: WithBaseField as _;
121+ self . to_gd ( )
122+ }
123+ }
124+
105125#[ derive( GodotClass ) ]
106126#[ class( init, base=Node2D ) ]
107127struct Baseless {
You can’t perform that action at this time.
0 commit comments