@@ -82,6 +82,24 @@ use std::{fmt, ops};
82
82
/// guard.deal_damage(120);
83
83
/// assert!(!guard.is_alive());
84
84
/// ```
85
+ ///
86
+ /// # Polymorphic `dyn` re-enrichment
87
+ ///
88
+ /// When passing `DynGd<T, D>` to Godot, you will lose the `D` part of the type inside the engine, because Godot doesn't know about Rust traits.
89
+ /// The trait methods won't be accessible through GDScript, either.
90
+ ///
91
+ /// If you now receive the same object back from Godot, you can easily obtain it as `Gd<T>` -- but what if you need the original `DynGd<T, D>`?
92
+ /// If `T` is concrete (i.e. directly implements `D`), then [`Gd::into_dyn()`] is of course possible. But in reality, you may have a polymorphic
93
+ /// base class such as `RefCounted` and want to ensure that trait object `D` dispatches to the correct subclass, without manually checking every
94
+ /// possible candidate.
95
+ ///
96
+ /// To stay with the above example: let's say `Health` is implemented for both `Monster` and `Knight` classes. You now receive a
97
+ /// `DynGd<RefCounted, dyn Health>`, which can represent either of the two classes. How can this work without trying to downcast to both?
98
+ ///
99
+ /// godot-rust has a mechanism to re-enrich the `DynGd` with the correct trait object. Thanks to `#[godot_dyn]`, the library knows for which
100
+ /// classes `Health` is implemented, and it can query the dynamic type of the object. Based on that type, it can find the `impl Health`
101
+ /// implementation matching the correct class. Behind the scenes, everything is wired up correctly so that you can restore the original `DynGd`
102
+ /// even after it has passed through Godot.
85
103
pub struct DynGd < T , D >
86
104
where
87
105
// T does _not_ require AsDyn<D> here. Otherwise, it's impossible to upcast (without implementing the relation for all base classes).
@@ -226,6 +244,9 @@ where
226
244
T : GodotClass + Bounds < Memory = bounds:: MemManual > ,
227
245
D : ?Sized ,
228
246
{
247
+ /// Destroy the manually-managed Godot object.
248
+ ///
249
+ /// See [`Gd::free()`] for semantics and panics.
229
250
pub fn free ( self ) {
230
251
self . obj . free ( )
231
252
}
0 commit comments