6
6
7
7
use std:: fmt:: { Debug , Display , Formatter , Result as FmtResult } ;
8
8
use std:: ops:: { Deref , DerefMut } ;
9
- use std:: ptr;
10
9
11
10
use godot_ffi as sys;
12
11
use godot_ffi:: VariantType ;
@@ -23,28 +22,65 @@ use super::RawGd;
23
22
24
23
/// Smart pointer to objects owned by the Godot engine.
25
24
///
25
+ /// See also [chapter about objects][book] in the book.
26
+ ///
26
27
/// This smart pointer can only hold _objects_ in the Godot sense: instances of Godot classes (`Node`, `RefCounted`, etc.)
27
- /// or user-declared structs (`#[derive(GodotClass)]`). It does **not** hold built-in types (`Vector3`, `Color`, `i32`).
28
+ /// or user-declared structs (declared with `#[derive(GodotClass)]`). It does **not** hold built-in types (`Vector3`, `Color`, `i32`).
28
29
///
29
30
/// `Gd<T>` never holds null objects. If you need nullability, use `Option<Gd<T>>`.
30
31
///
32
+ /// # Memory management
33
+ ///
31
34
/// This smart pointer behaves differently depending on `T`'s associated types, see [`GodotClass`] for their documentation.
32
35
/// In particular, the memory management strategy is fully dependent on `T`:
33
36
///
34
- /// * Objects of type [`RefCounted`] or inherited from it are **reference-counted**. This means that every time a smart pointer is
37
+ /// - **Reference-counted**<br>
38
+ /// Objects of type [`RefCounted`] or inherited from it are **reference-counted**. This means that every time a smart pointer is
35
39
/// shared using [`Clone::clone()`], the reference counter is incremented, and every time one is dropped, it is decremented.
36
- /// This ensures that the last reference (either in Rust or Godot) will deallocate the object and call `T`'s destructor.
40
+ /// This ensures that the last reference (either in Rust or Godot) will deallocate the object and call `T`'s destructor.<br><br>
37
41
///
38
- /// * Objects inheriting from [`Object`] which are not `RefCounted` (or inherited) are **manually-managed**.
42
+ /// - **Manual**<br>
43
+ /// Objects inheriting from [`Object`] which are not `RefCounted` (or inherited) are **manually-managed**.
39
44
/// Their destructor is not automatically called (unless they are part of the scene tree). Creating a `Gd<T>` means that
40
- /// you are responsible of explicitly deallocating such objects using [`Gd:: free()`].
45
+ /// you are responsible of explicitly deallocating such objects using [`free()`][Self::free].<br><br>
41
46
///
42
- /// * For `T=Object`, the memory strategy is determined **dynamically**. Due to polymorphism, a `Gd<T>` can point to either
47
+ /// - **Dynamic**<br>
48
+ /// For `T=Object`, the memory strategy is determined **dynamically**. Due to polymorphism, a `Gd<Object>` can point to either
43
49
/// reference-counted or manually-managed types at runtime. The behavior corresponds to one of the two previous points.
44
50
/// Note that if the dynamic type is also `Object`, the memory is manually-managed.
45
51
///
46
- /// [`Object`]: crate::engine::Object
47
- /// [`RefCounted`]: crate::engine::RefCounted
52
+ /// # Construction
53
+ ///
54
+ /// To construct default instances of various `Gd<T>` types, there are extension methods on the type `T` itself:
55
+ ///
56
+ /// | Type \ Memory Strategy | Ref-counted | Manually managed | Singleton |
57
+ /// |------------------------|----------------------|-----------------------|-------------------------|
58
+ /// | **Engine type** | `Resource::new()` | `Node::new_alloc()` | `Os::singleton()` |
59
+ /// | **User type** | `MyClass::new_gd()` | `MyClass::alloc_gd()` | _(not yet implemented)_ |
60
+ ///
61
+ /// In addition, the smart pointer can be constructed in multiple ways:
62
+ ///
63
+ /// * [`Gd::default()`] for reference-counted types that are constructible. For user types, this means they must expose an `init` function
64
+ /// or have a generated one. `Gd::<T>::default()` is equivalent to the shorter `T::new_gd()` and primarily useful for derives or generics.
65
+ /// * [`Gd::from_init_fn(function)`][Gd::from_init_fn] for Rust objects with `#[base]` field, which are constructed inside the smart pointer.
66
+ /// This is a very handy function if you want to pass extra parameters to your object upon construction.
67
+ /// * [`Gd::from_object(rust_obj)`][Gd::from_object] for existing Rust objects without a `#[base]` field that are moved _into_ the smart pointer.
68
+ /// * [`Gd::from_instance_id(id)`][Gd::from_instance_id] and [`Gd::try_from_instance_id(id)`][Gd::try_from_instance_id]
69
+ /// to obtain a pointer to an object which is already alive in the engine.
70
+ ///
71
+ /// # Binds
72
+ ///
73
+ /// The [`bind()`][Self::bind] and [`bind_mut()`][Self::bind_mut] methods allow you to obtain a shared or exclusive guard to the user instance.
74
+ /// These provide interior mutability similar to [`RefCell`][std::cell::RefCell], with the addition that `Gd` simultaneously handles reference
75
+ /// counting (for some types `T`).
76
+ ///
77
+ /// When you declare a `#[func]` method on your own class and it accepts `&self` or `&mut self`, an implicit `bind()` or `bind_mut()` call
78
+ /// on the owning `Gd<T>` is performed. This is important to keep in mind, as you can get into situations that violate dynamic borrow rules; for
79
+ /// example if you are inside a `&mut self` method, make a call to GDScript and indirectly call another method on the same object (re-entrancy).
80
+ ///
81
+ /// [book]: https://godot-rust.github.io/book/intro/objects.html
82
+ /// [`Object`]: engine::Object
83
+ /// [`RefCounted`]: engine::RefCounted
48
84
#[ repr( C ) ] // must be layout compatible with engine classes
49
85
pub struct Gd < T : GodotClass > {
50
86
// Note: `opaque` has the same layout as GDExtensionObjectPtr == Object* in C++, i.e. the bytes represent a pointer
@@ -68,27 +104,6 @@ impl<T> Gd<T>
68
104
where
69
105
T : GodotClass < Declarer = dom:: UserDomain > ,
70
106
{
71
- /// Moves a user-created object into this smart pointer, submitting ownership to the Godot engine.
72
- ///
73
- /// This is only useful for types `T` which do not store their base objects (if they have a base,
74
- /// you cannot construct them standalone).
75
- pub fn new ( user_object : T ) -> Self {
76
- Self :: with_base ( move |_base| user_object)
77
- }
78
-
79
- /// Creates a default-constructed instance of `T` inside a smart pointer.
80
- ///
81
- /// This is equivalent to the GDScript expression `T.new()`.
82
- pub fn new_default ( ) -> Self
83
- where
84
- T : cap:: GodotInit ,
85
- {
86
- unsafe {
87
- let object_ptr = callbacks:: create :: < T > ( ptr:: null_mut ( ) ) ;
88
- Gd :: from_obj_sys ( object_ptr)
89
- }
90
- }
91
-
92
107
/// Creates a `Gd<T>` using a function that constructs a `T` from a provided base.
93
108
///
94
109
/// Imagine you have a type `T`, which has a `#[base]` field that you cannot default-initialize.
@@ -106,19 +121,48 @@ where
106
121
/// other_field: i32,
107
122
/// }
108
123
///
109
- /// let obj = Gd::<MyClass>::with_base (|my_base| {
124
+ /// let obj = Gd::from_init_fn (|my_base| {
110
125
/// // accepts the base and returns a constructed object containing it
111
126
/// MyClass { my_base, other_field: 732 }
112
127
/// });
113
128
/// ```
114
- pub fn with_base < F > ( init : F ) -> Self
129
+ pub fn from_init_fn < F > ( init : F ) -> Self
115
130
where
116
131
F : FnOnce ( crate :: obj:: Base < T :: Base > ) -> T ,
117
132
{
118
133
let object_ptr = callbacks:: create_custom ( init) ;
119
134
unsafe { Gd :: from_obj_sys ( object_ptr) }
120
135
}
121
136
137
+ /// Moves a user-created object into this smart pointer, submitting ownership to the Godot engine.
138
+ ///
139
+ /// This is only useful for types `T` which do not store their base objects (if they have a base,
140
+ /// you cannot construct them standalone).
141
+ pub fn from_object ( user_object : T ) -> Self {
142
+ Self :: from_init_fn ( move |_base| user_object)
143
+ }
144
+
145
+ #[ deprecated = "Use `Gd::from_object()` instead." ]
146
+ pub fn new ( user_object : T ) -> Self {
147
+ Self :: from_object ( user_object)
148
+ }
149
+
150
+ #[ deprecated = "Use `Gd::default()` or the short-hands `T::new_gd()` and `T::alloc_gd()` instead." ]
151
+ pub fn new_default ( ) -> Self
152
+ where
153
+ T : cap:: GodotDefault ,
154
+ {
155
+ Self :: default_instance ( )
156
+ }
157
+
158
+ #[ deprecated = "Use `Gd::from_init_fn()` instead." ]
159
+ pub fn with_base < F > ( init : F ) -> Self
160
+ where
161
+ F : FnOnce ( crate :: obj:: Base < T :: Base > ) -> T ,
162
+ {
163
+ Self :: from_init_fn ( init)
164
+ }
165
+
122
166
/// Hands out a guard for a shared borrow, through which the user instance can be read.
123
167
///
124
168
/// The pattern is very similar to interior mutability with standard [`RefCell`][std::cell::RefCell].
@@ -242,7 +286,7 @@ impl<T: GodotClass> Gd<T> {
242
286
/// #[class(init, base=Node2D)]
243
287
/// struct MyClass {}
244
288
///
245
- /// let obj: Gd<MyClass> = Gd::new_default ();
289
+ /// let obj: Gd<MyClass> = MyClass::alloc_gd ();
246
290
/// let base = obj.clone().upcast::<Node>();
247
291
/// ```
248
292
pub fn upcast < Base > ( self ) -> Gd < Base >
@@ -295,7 +339,19 @@ impl<T: GodotClass> Gd<T> {
295
339
. map_err ( Self :: from_ffi)
296
340
}
297
341
298
- #[ doc( hidden) ]
342
+ /// Create default instance for all types that have `GodotDefault`.
343
+ ///
344
+ /// Deliberately more loose than `Gd::default()`, does not require ref-counted memory strategy for user types.
345
+ pub ( crate ) fn default_instance ( ) -> Self
346
+ where
347
+ T : cap:: GodotDefault ,
348
+ {
349
+ unsafe {
350
+ let object_ptr = crate :: callbacks:: create :: < T > ( std:: ptr:: null_mut ( ) ) ;
351
+ Gd :: from_obj_sys ( object_ptr)
352
+ }
353
+ }
354
+
299
355
pub ( crate ) unsafe fn from_obj_sys_or_none ( ptr : sys:: GDExtensionObjectPtr ) -> Option < Self > {
300
356
Self :: try_from_ffi ( RawGd :: from_obj_sys ( ptr) )
301
357
}
@@ -305,26 +361,21 @@ impl<T: GodotClass> Gd<T> {
305
361
///
306
362
/// This is the default for most initializations from FFI. In cases where reference counter
307
363
/// should explicitly **not** be updated, [`Self::from_obj_sys_weak`] is available.
308
- #[ doc( hidden) ]
309
364
pub ( crate ) unsafe fn from_obj_sys ( ptr : sys:: GDExtensionObjectPtr ) -> Self {
310
365
Self :: from_obj_sys_or_none ( ptr) . unwrap ( )
311
366
}
312
367
313
- #[ doc( hidden) ]
314
368
pub ( crate ) unsafe fn from_obj_sys_weak_or_none ( ptr : sys:: GDExtensionObjectPtr ) -> Option < Self > {
315
369
Self :: try_from_ffi ( RawGd :: from_obj_sys_weak ( ptr) )
316
370
}
317
371
318
- #[ doc( hidden) ]
319
372
pub ( crate ) unsafe fn from_obj_sys_weak ( ptr : sys:: GDExtensionObjectPtr ) -> Self {
320
373
Self :: from_obj_sys_weak_or_none ( ptr) . unwrap ( )
321
374
}
322
375
323
- #[ doc( hidden) ]
324
376
pub ( crate ) fn obj_sys ( & self ) -> sys:: GDExtensionObjectPtr {
325
377
self . raw . obj_sys ( )
326
378
}
327
-
328
379
/// Returns a callable referencing a method from this object named `method_name`.
329
380
pub fn callable < S : Into < StringName > > ( & self , method_name : S ) -> Callable {
330
381
Callable :: from_object_method ( self . clone ( ) , method_name)
@@ -486,6 +537,22 @@ impl<T: GodotClass> GodotType for Gd<T> {
486
537
}
487
538
}
488
539
540
+ impl < T > Default for Gd < T >
541
+ where
542
+ T : cap:: GodotDefault + GodotClass < Mem = mem:: StaticRefCount > ,
543
+ {
544
+ /// Creates a default-constructed `T` inside a smart pointer.
545
+ ///
546
+ /// This is equivalent to the GDScript expression `T.new()`, and to the shorter Rust expression `T::new_gd()`.
547
+ ///
548
+ /// This trait is only implemented for reference-counted classes. Classes with manually-managed memory (e.g. `Node`) are not covered,
549
+ /// because they need explicit memory management, and deriving `Default` has a high chance of the user forgetting to call `free()` on those.
550
+ /// `T::alloc_gd()` should be used for those instead.
551
+ fn default ( ) -> Self {
552
+ T :: __godot_default ( )
553
+ }
554
+ }
555
+
489
556
impl < T : GodotClass > Clone for Gd < T > {
490
557
fn clone ( & self ) -> Self {
491
558
out ! ( "Gd::clone" ) ;
0 commit comments