godot_core/obj/gd.rs
1/*
2 * Copyright (c) godot-rust; Bromeon and contributors.
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
6 */
7
8use std::fmt::{Debug, Display, Formatter, Result as FmtResult};
9use std::ops::{Deref, DerefMut};
10
11use godot_ffi as sys;
12use sys::{static_assert_eq_size_align, SysPtr as _};
13
14use crate::builtin::{Callable, GString, NodePath, StringName, Variant};
15use crate::meta::error::{ConvertError, FromFfiError};
16use crate::meta::{
17 ArrayElement, AsArg, ByRef, CallContext, ClassName, CowArg, FromGodot, GodotConvert, GodotType,
18 ParamType, PropertyHintInfo, RefArg, ToGodot,
19};
20use crate::obj::{
21 bounds, cap, Bounds, DynGd, GdDerefTarget, GdMut, GdRef, GodotClass, Inherits, InstanceId,
22 OnEditor, RawGd, WithSignals,
23};
24use crate::private::{callbacks, PanicPayload};
25use crate::registry::class::try_dynify_object;
26use crate::registry::property::{object_export_element_type_string, Export, Var};
27use crate::{classes, out};
28
29/// Smart pointer to objects owned by the Godot engine.
30///
31/// See also [chapter about objects][book] in the book.
32///
33/// This smart pointer can only hold _objects_ in the Godot sense: instances of Godot classes (`Node`, `RefCounted`, etc.)
34/// or user-declared structs (declared with `#[derive(GodotClass)]`). It does **not** hold built-in types (`Vector3`, `Color`, `i32`).
35///
36/// `Gd<T>` never holds null objects. If you need nullability, use `Option<Gd<T>>`. To pass null objects to engine APIs, you can
37/// additionally use [`Gd::null_arg()`] as a shorthand.
38///
39/// # Memory management
40///
41/// This smart pointer behaves differently depending on `T`'s associated types, see [`GodotClass`] for their documentation.
42/// In particular, the memory management strategy is fully dependent on `T`:
43///
44/// - **Reference-counted**<br>
45/// Objects of type [`RefCounted`] or inherited from it are **reference-counted**. This means that every time a smart pointer is
46/// shared using [`Clone::clone()`], the reference counter is incremented, and every time one is dropped, it is decremented.
47/// This ensures that the last reference (either in Rust or Godot) will deallocate the object and call `T`'s destructor.<br><br>
48///
49/// - **Manual**<br>
50/// Objects inheriting from [`Object`] which are not `RefCounted` (or inherited) are **manually-managed**.
51/// Their destructor is not automatically called (unless they are part of the scene tree). Creating a `Gd<T>` means that
52/// you are responsible for explicitly deallocating such objects using [`free()`][Self::free].<br><br>
53///
54/// - **Dynamic**<br>
55/// For `T=Object`, the memory strategy is determined **dynamically**. Due to polymorphism, a `Gd<Object>` can point to either
56/// reference-counted or manually-managed types at runtime. The behavior corresponds to one of the two previous points.
57/// Note that if the dynamic type is also `Object`, the memory is manually-managed.
58///
59/// # Construction
60///
61/// To construct default instances of various `Gd<T>` types, there are extension methods on the type `T` itself:
62///
63/// - Manually managed: [`NewAlloc::new_alloc()`][crate::obj::NewAlloc::new_alloc]
64/// - Reference-counted: [`NewGd::new_gd()`][crate::obj::NewGd::new_gd]
65/// - Singletons: `T::singleton()` (inherent)
66///
67/// In addition, the smart pointer can be constructed in multiple ways:
68///
69/// * [`Gd::default()`] for reference-counted types that are constructible. For user types, this means they must expose an `init` function
70/// or have a generated one. `Gd::<T>::default()` is equivalent to the shorter `T::new_gd()` and primarily useful for derives or generics.
71/// * [`Gd::from_init_fn(function)`][Gd::from_init_fn] for Rust objects with `Base<T>` field, which are constructed inside the smart pointer.
72/// This is a very handy function if you want to pass extra parameters to your object upon construction.
73/// * [`Gd::from_object(rust_obj)`][Gd::from_object] for existing Rust objects without a `Base<T>` field that are moved _into_ the smart pointer.
74/// * [`Gd::from_instance_id(id)`][Gd::from_instance_id] and [`Gd::try_from_instance_id(id)`][Gd::try_from_instance_id]
75/// to obtain a pointer to an object which is already alive in the engine.
76///
77/// # Bind guards
78///
79/// The [`bind()`][Self::bind] and [`bind_mut()`][Self::bind_mut] methods allow you to obtain a shared or exclusive guard to the user instance.
80/// These provide interior mutability similar to [`RefCell`][std::cell::RefCell], with the addition that `Gd` simultaneously handles reference
81/// counting (for some types `T`).
82///
83/// Holding a bind guard will prevent other code paths from obtaining their own shared/mutable bind. As such, you should drop the guard
84/// as soon as you don't need it anymore, by closing a `{ }` block or calling `std::mem::drop()`.
85///
86/// When you declare a `#[func]` method on your own class, and it accepts `&self` or `&mut self`, an implicit `bind()` or `bind_mut()` call
87/// 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
88/// 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).
89///
90/// # Conversions
91///
92/// For type conversions, please read the [`godot::meta` module docs][crate::meta].
93///
94/// # Exporting
95///
96/// The [`Export`][crate::registry::property::Export] trait is not directly implemented for `Gd<T>`, because the editor expects object-based
97/// properties to be nullable, while `Gd<T>` can't be null. Instead, `Export` is implemented for [`OnEditor<Gd<T>>`][crate::obj::OnEditor],
98/// which validates that objects have been set by the editor. For the most flexible but least ergonomic option, you can also export
99/// `Option<Gd<T>>` fields.
100///
101/// Objects can only be exported if `T: Inherits<Node>` or `T: Inherits<Resource>`, just like GDScript.
102/// This means you cannot use `#[export]` with `OnEditor<Gd<RefCounted>>`, for example.
103///
104/// [book]: https://godot-rust.github.io/book/godot-api/objects.html
105/// [`Object`]: classes::Object
106/// [`RefCounted`]: classes::RefCounted
107#[repr(C)] // must be layout compatible with engine classes
108pub struct Gd<T: GodotClass> {
109 // Note: `opaque` has the same layout as GDExtensionObjectPtr == Object* in C++, i.e. the bytes represent a pointer
110 // To receive a GDExtensionTypePtr == GDExtensionObjectPtr* == Object**, we need to get the address of this
111 // Hence separate sys() for GDExtensionTypePtr, and obj_sys() for GDExtensionObjectPtr.
112 // The former is the standard FFI type, while the latter is used in object-specific GDExtension engines.
113 // pub(crate) because accessed in obj::dom
114 pub(crate) raw: RawGd<T>,
115}
116
117// Size equality check (should additionally be covered by mem::transmute())
118static_assert_eq_size_align!(
119 sys::GDExtensionObjectPtr,
120 sys::types::OpaqueObject,
121 "Godot FFI: pointer type `Object*` should have size advertised in JSON extension file"
122);
123
124/// _The methods in this impl block are only available for user-declared `T`, that is,
125/// structs with `#[derive(GodotClass)]` but not Godot classes like `Node` or `RefCounted`._ <br><br>
126impl<T> Gd<T>
127where
128 T: GodotClass + Bounds<Declarer = bounds::DeclUser>,
129{
130 /// Creates a `Gd<T>` using a function that constructs a `T` from a provided base.
131 ///
132 /// Imagine you have a type `T`, which has a base field that you cannot default-initialize.
133 /// The `init` function provides you with a `Base<T::Base>` object that you can use inside your `T`, which
134 /// is then wrapped in a `Gd<T>`.
135 ///
136 /// # Example
137 /// ```no_run
138 /// # use godot::prelude::*;
139 /// #[derive(GodotClass)]
140 /// #[class(init, base=Node2D)]
141 /// struct MyClass {
142 /// my_base: Base<Node2D>,
143 /// other_field: i32,
144 /// }
145 ///
146 /// let obj = Gd::from_init_fn(|my_base| {
147 /// // accepts the base and returns a constructed object containing it
148 /// MyClass { my_base, other_field: 732 }
149 /// });
150 /// ```
151 ///
152 /// # Panics
153 /// Panics occurring in the `init` function are propagated to the caller.
154 pub fn from_init_fn<F>(init: F) -> Self
155 where
156 F: FnOnce(crate::obj::Base<T::Base>) -> T,
157 {
158 let object_ptr = callbacks::create_custom(init) // or propagate panic.
159 .unwrap_or_else(|payload| PanicPayload::repanic(payload));
160
161 unsafe { Gd::from_obj_sys(object_ptr) }
162 }
163
164 /// Moves a user-created object into this smart pointer, submitting ownership to the Godot engine.
165 ///
166 /// This is only useful for types `T` which do not store their base objects (if they have a base,
167 /// you cannot construct them standalone).
168 pub fn from_object(user_object: T) -> Self {
169 Self::from_init_fn(move |_base| user_object)
170 }
171
172 /// Hands out a guard for a shared borrow, through which the user instance can be read.
173 ///
174 /// The pattern is very similar to interior mutability with standard [`RefCell`][std::cell::RefCell].
175 /// You can either have multiple `GdRef` shared guards, or a single `GdMut` exclusive guard to a Rust
176 /// `GodotClass` instance, independently of how many `Gd` smart pointers point to it. There are runtime
177 /// checks to ensure that Rust safety rules (e.g. no `&` and `&mut` coexistence) are upheld.
178 ///
179 /// Drop the guard as soon as you don't need it anymore. See also [Bind guards](#bind-guards).
180 ///
181 /// # Panics
182 /// * If another `Gd` smart pointer pointing to the same Rust instance has a live `GdMut` guard bound.
183 /// * If there is an ongoing function call from GDScript to Rust, which currently holds a `&mut T`
184 /// reference to the user instance. This can happen through re-entrancy (Rust -> GDScript -> Rust call).
185 // Note: possible names: write/read, hold/hold_mut, r/w, r/rw, ...
186 pub fn bind(&self) -> GdRef<'_, T> {
187 self.raw.bind()
188 }
189
190 /// Hands out a guard for an exclusive borrow, through which the user instance can be read and written.
191 ///
192 /// The pattern is very similar to interior mutability with standard [`RefCell`][std::cell::RefCell].
193 /// You can either have multiple `GdRef` shared guards, or a single `GdMut` exclusive guard to a Rust
194 /// `GodotClass` instance, independently of how many `Gd` smart pointers point to it. There are runtime
195 /// checks to ensure that Rust safety rules (e.g. no `&mut` aliasing) are upheld.
196 ///
197 /// Drop the guard as soon as you don't need it anymore. See also [Bind guards](#bind-guards).
198 ///
199 /// # Panics
200 /// * If another `Gd` smart pointer pointing to the same Rust instance has a live `GdRef` or `GdMut` guard bound.
201 /// * If there is an ongoing function call from GDScript to Rust, which currently holds a `&T` or `&mut T`
202 /// reference to the user instance. This can happen through re-entrancy (Rust -> GDScript -> Rust call).
203 pub fn bind_mut(&mut self) -> GdMut<'_, T> {
204 self.raw.bind_mut()
205 }
206}
207
208/// _The methods in this impl block are available for any `T`._ <br><br>
209impl<T: GodotClass> Gd<T> {
210 /// Looks up the given instance ID and returns the associated object, if possible.
211 ///
212 /// If no such instance ID is registered, or if the dynamic type of the object behind that instance ID
213 /// is not compatible with `T`, then `None` is returned.
214 pub fn try_from_instance_id(instance_id: InstanceId) -> Result<Self, ConvertError> {
215 let ptr = classes::object_ptr_from_id(instance_id);
216
217 // SAFETY: assumes that the returned GDExtensionObjectPtr is convertible to Object* (i.e. C++ upcast doesn't modify the pointer)
218 let untyped = unsafe { Gd::<classes::Object>::from_obj_sys_or_none(ptr)? };
219 untyped
220 .owned_cast::<T>()
221 .map_err(|obj| FromFfiError::WrongObjectType.into_error(obj))
222 }
223
224 /// ⚠️ Looks up the given instance ID and returns the associated object.
225 ///
226 /// Corresponds to Godot's global function `instance_from_id()`.
227 ///
228 /// # Panics
229 /// If no such instance ID is registered, or if the dynamic type of the object behind that instance ID
230 /// is not compatible with `T`.
231 #[doc(alias = "instance_from_id")]
232 pub fn from_instance_id(instance_id: InstanceId) -> Self {
233 Self::try_from_instance_id(instance_id).unwrap_or_else(|err| {
234 panic!(
235 "Instance ID {} does not belong to a valid object of class '{}': {}",
236 instance_id,
237 T::class_name(),
238 err
239 )
240 })
241 }
242
243 /// Returns the instance ID of this object, or `None` if the object is dead or null.
244 pub(crate) fn instance_id_or_none(&self) -> Option<InstanceId> {
245 let known_id = self.instance_id_unchecked();
246
247 // Refreshes the internal cached ID on every call, as we cannot be sure that the object has not been
248 // destroyed since last time. The only reliable way to find out is to call is_instance_id_valid().
249 if self.raw.is_instance_valid() {
250 Some(known_id)
251 } else {
252 None
253 }
254 }
255
256 /// ⚠️ Returns the instance ID of this object (panics when dead).
257 ///
258 /// # Panics
259 /// If this object is no longer alive (registered in Godot's object database).
260 pub fn instance_id(&self) -> InstanceId {
261 self.instance_id_or_none().unwrap_or_else(|| {
262 panic!(
263 "failed to call instance_id() on destroyed object; \
264 use instance_id_or_none() or keep your objects alive"
265 )
266 })
267 }
268
269 /// Returns the last known, possibly invalid instance ID of this object.
270 ///
271 /// This function does not check that the returned instance ID points to a valid instance!
272 /// Unless performance is a problem, use [`instance_id()`][Self::instance_id] instead.
273 ///
274 /// This method is safe and never panics.
275 pub fn instance_id_unchecked(&self) -> InstanceId {
276 let instance_id = self.raw.instance_id_unchecked();
277
278 // SAFETY: a `Gd` can only be created from a non-null `RawGd`, meaning `raw.instance_id_unchecked()` will
279 // always return `Some`.
280 unsafe { instance_id.unwrap_unchecked() }
281 }
282
283 /// Checks if this smart pointer points to a live object (read description!).
284 ///
285 /// Using this method is often indicative of bad design -- you should dispose of your pointers once an object is
286 /// destroyed. However, this method exists because GDScript offers it and there may be **rare** use cases.
287 ///
288 /// Do not use this method to check if you can safely access an object. Accessing dead objects is generally safe
289 /// and will panic in a defined manner. Encountering such panics is almost always a bug you should fix, and not a
290 /// runtime condition to check against.
291 pub fn is_instance_valid(&self) -> bool {
292 self.raw.is_instance_valid()
293 }
294
295 /// Returns the dynamic class name of the object as `StringName`.
296 ///
297 /// This method retrieves the class name of the object at runtime, which can be different from [`T::class_name()`][GodotClass::class_name]
298 /// if derived classes are involved.
299 ///
300 /// Unlike [`Object::get_class()`][crate::classes::Object::get_class], this returns `StringName` instead of `GString` and needs no
301 /// `Inherits<Object>` bound.
302 pub(crate) fn dynamic_class_string(&self) -> StringName {
303 unsafe {
304 StringName::new_with_string_uninit(|ptr| {
305 let success = sys::interface_fn!(object_get_class_name)(
306 self.obj_sys().as_const(),
307 sys::get_library(),
308 ptr,
309 );
310
311 let success = sys::conv::bool_from_sys(success);
312 assert!(success, "failed to get class name for object {self:?}");
313 })
314 }
315 }
316
317 /// Returns the reference count, if the dynamic object inherits `RefCounted`; and `None` otherwise.
318 ///
319 /// Returns `Err(())` if obtaining reference count failed, due to being called during init/drop.
320 pub(crate) fn maybe_refcount(&self) -> Option<Result<usize, ()>> {
321 // May become infallible if implemented via call() on Object, if ref-count bit of instance ID is set.
322 // This would likely be more efficient, too.
323
324 // Fast check if ref-counted without downcast.
325 if !self.instance_id().is_ref_counted() {
326 return None;
327 }
328
329 // Optimization: call `get_reference_count()` directly. Might also increase reliability and obviate the need for Result.
330
331 let rc = self
332 .raw
333 .try_with_ref_counted(|refc| refc.get_reference_count());
334
335 Some(rc.map(|i| i as usize))
336 }
337
338 #[cfg(feature = "trace")] // itest only.
339 #[doc(hidden)]
340 pub fn test_refcount(&self) -> Option<usize> {
341 self.maybe_refcount()
342 .transpose()
343 .expect("failed to obtain refcount")
344 }
345
346 /// **Upcast:** convert into a smart pointer to a base class. Always succeeds.
347 ///
348 /// Moves out of this value. If you want to create _another_ smart pointer instance,
349 /// use this idiom:
350 /// ```no_run
351 /// # use godot::prelude::*;
352 /// #[derive(GodotClass)]
353 /// #[class(init, base=Node2D)]
354 /// struct MyClass {}
355 ///
356 /// let obj: Gd<MyClass> = MyClass::new_alloc();
357 /// let base = obj.clone().upcast::<Node>();
358 /// ```
359 pub fn upcast<Base>(self) -> Gd<Base>
360 where
361 Base: GodotClass,
362 T: Inherits<Base>,
363 {
364 self.owned_cast()
365 .expect("Upcast failed. This is a bug; please report it.")
366 }
367
368 /// Equivalent to [`upcast::<Object>()`][Self::upcast], but without bounds.
369 // Not yet public because it might need _mut/_ref overloads, and 6 upcast methods are a bit much...
370 #[doc(hidden)] // no public API, but used by #[signal].
371 pub fn upcast_object(self) -> Gd<classes::Object> {
372 self.owned_cast()
373 .expect("Upcast to Object failed. This is a bug; please report it.")
374 }
375
376 // /// Equivalent to [`upcast_mut::<Object>()`][Self::upcast_mut], but without bounds.
377 // pub(crate) fn upcast_object_ref(&self) -> &classes::Object {
378 // self.raw.as_object_ref()
379 // }
380
381 /// Equivalent to [`upcast_mut::<Object>()`][Self::upcast_mut], but without bounds.
382 pub(crate) fn upcast_object_mut(&mut self) -> &mut classes::Object {
383 self.raw.as_object_mut()
384 }
385
386 // pub(crate) fn upcast_object_mut_from_ref(&self) -> &mut classes::Object {
387 // self.raw.as_object_mut()
388 // }
389
390 /// **Upcast shared-ref:** access this object as a shared reference to a base class.
391 ///
392 /// This is semantically equivalent to multiple applications of [`Self::deref()`]. Not really useful on its own, but combined with
393 /// generic programming:
394 /// ```no_run
395 /// # use godot::prelude::*;
396 /// fn print_node_name<T>(node: &Gd<T>)
397 /// where
398 /// T: Inherits<Node>,
399 /// {
400 /// println!("Node name: {}", node.upcast_ref().get_name());
401 /// }
402 /// ```
403 ///
404 /// Note that this cannot be used to get a reference to Rust classes, for that you should use [`Gd::bind()`]. For instance this
405 /// will fail:
406 /// ```compile_fail
407 /// # use godot::prelude::*;
408 /// #[derive(GodotClass)]
409 /// #[class(init, base = Node)]
410 /// struct SomeClass {}
411 ///
412 /// #[godot_api]
413 /// impl INode for SomeClass {
414 /// fn ready(&mut self) {
415 /// let other = SomeClass::new_alloc();
416 /// let _ = other.upcast_ref::<SomeClass>();
417 /// }
418 /// }
419 /// ```
420 pub fn upcast_ref<Base>(&self) -> &Base
421 where
422 Base: GodotClass + Bounds<Declarer = bounds::DeclEngine>,
423 T: Inherits<Base>,
424 {
425 // SAFETY: `Base` is guaranteed to be an engine base class of `T` because of the generic bounds.
426 unsafe { self.raw.as_upcast_ref::<Base>() }
427 }
428
429 /// **Upcast exclusive-ref:** access this object as an exclusive reference to a base class.
430 ///
431 /// This is semantically equivalent to multiple applications of [`Self::deref_mut()`]. Not really useful on its own, but combined with
432 /// generic programming:
433 /// ```no_run
434 /// # use godot::prelude::*;
435 /// fn set_node_name<T>(node: &mut Gd<T>, name: &str)
436 /// where
437 /// T: Inherits<Node>,
438 /// {
439 /// node.upcast_mut().set_name(name);
440 /// }
441 /// ```
442 ///
443 /// Note that this cannot be used to get a mutable reference to Rust classes, for that you should use [`Gd::bind_mut()`]. For instance this
444 /// will fail:
445 /// ```compile_fail
446 /// # use godot::prelude::*;
447 /// #[derive(GodotClass)]
448 /// #[class(init, base = Node)]
449 /// struct SomeClass {}
450 ///
451 /// #[godot_api]
452 /// impl INode for SomeClass {
453 /// fn ready(&mut self) {
454 /// let mut other = SomeClass::new_alloc();
455 /// let _ = other.upcast_mut::<SomeClass>();
456 /// }
457 /// }
458 /// ```
459 pub fn upcast_mut<Base>(&mut self) -> &mut Base
460 where
461 Base: GodotClass + Bounds<Declarer = bounds::DeclEngine>,
462 T: Inherits<Base>,
463 {
464 // SAFETY: `Base` is guaranteed to be an engine base class of `T` because of the generic bounds.
465 unsafe { self.raw.as_upcast_mut::<Base>() }
466 }
467
468 /// **Downcast:** try to convert into a smart pointer to a derived class.
469 ///
470 /// If `T`'s dynamic type is not `Derived` or one of its subclasses, `Err(self)` is returned, meaning you can reuse the original
471 /// object for further casts.
472 pub fn try_cast<Derived>(self) -> Result<Gd<Derived>, Self>
473 where
474 Derived: Inherits<T>,
475 {
476 // Separate method due to more restrictive bounds.
477 self.owned_cast()
478 }
479
480 /// ⚠️ **Downcast:** convert into a smart pointer to a derived class. Panics on error.
481 ///
482 /// # Panics
483 /// If the class' dynamic type is not `Derived` or one of its subclasses. Use [`Self::try_cast()`] if you want to check the result.
484 pub fn cast<Derived>(self) -> Gd<Derived>
485 where
486 Derived: Inherits<T>,
487 {
488 self.owned_cast().unwrap_or_else(|from_obj| {
489 panic!(
490 "downcast from {from} to {to} failed; instance {from_obj:?}",
491 from = T::class_name(),
492 to = Derived::class_name(),
493 )
494 })
495 }
496
497 /// Returns `Ok(cast_obj)` on success, `Err(self)` on error.
498 // Visibility: used by DynGd.
499 pub(crate) fn owned_cast<U>(self) -> Result<Gd<U>, Self>
500 where
501 U: GodotClass,
502 {
503 self.raw
504 .owned_cast()
505 .map(Gd::from_ffi)
506 .map_err(Self::from_ffi)
507 }
508
509 /// Create default instance for all types that have `GodotDefault`.
510 ///
511 /// Deliberately more loose than `Gd::default()`, does not require ref-counted memory strategy for user types.
512 pub(crate) fn default_instance() -> Self
513 where
514 T: cap::GodotDefault,
515 {
516 unsafe {
517 // Default value (and compat one) for `p_notify_postinitialize` is true in Godot.
518 #[cfg(since_api = "4.4")] #[cfg_attr(published_docs, doc(cfg(since_api = "4.4")))]
519 let object_ptr = callbacks::create::<T>(std::ptr::null_mut(), sys::conv::SYS_TRUE);
520 #[cfg(before_api = "4.4")] #[cfg_attr(published_docs, doc(cfg(before_api = "4.4")))]
521 let object_ptr = callbacks::create::<T>(std::ptr::null_mut());
522
523 Gd::from_obj_sys(object_ptr)
524 }
525 }
526
527 /// Upgrades to a `DynGd<T, D>` pointer, enabling the `D` abstraction.
528 ///
529 /// The `D` parameter can typically be inferred when there is a single `AsDyn<...>` implementation for `T`. \
530 /// Otherwise, use it as `gd.into_dyn::<dyn MyTrait>()`.
531 #[must_use]
532 pub fn into_dyn<D>(self) -> DynGd<T, D>
533 where
534 T: crate::obj::AsDyn<D> + Bounds<Declarer = bounds::DeclUser>,
535 D: ?Sized + 'static,
536 {
537 DynGd::<T, D>::from_gd(self)
538 }
539
540 /// Tries to upgrade to a `DynGd<T, D>` pointer, enabling the `D` abstraction.
541 ///
542 /// If `T`'s dynamic class doesn't implement `AsDyn<D>`, `Err(self)` is returned, meaning you can reuse the original
543 /// object for further casts.
544 pub fn try_dynify<D>(self) -> Result<DynGd<T, D>, Self>
545 where
546 T: GodotClass + Bounds<Declarer = bounds::DeclEngine>,
547 D: ?Sized + 'static,
548 {
549 match try_dynify_object(self) {
550 Ok(dyn_gd) => Ok(dyn_gd),
551 Err((_convert_err, obj)) => Err(obj),
552 }
553 }
554
555 /// Returns a callable referencing a method from this object named `method_name`.
556 ///
557 /// This is shorter syntax for [`Callable::from_object_method(self, method_name)`][Callable::from_object_method].
558 pub fn callable(&self, method_name: impl AsArg<StringName>) -> Callable {
559 Callable::from_object_method(self, method_name)
560 }
561
562 /// Creates a new callable linked to the given object from **single-threaded** Rust function or closure.
563 /// This is shorter syntax for [`Callable::from_linked_fn()`].
564 ///
565 /// `name` is used for the string representation of the closure, which helps with debugging.
566 ///
567 /// Such a callable will be automatically invalidated by Godot when a linked Object is freed.
568 /// If you need a Callable which can live indefinitely use [`Callable::from_local_fn()`].
569 #[cfg(since_api = "4.2")] #[cfg_attr(published_docs, doc(cfg(since_api = "4.2")))]
570 pub fn linked_callable<F>(&self, method_name: impl AsArg<GString>, rust_function: F) -> Callable
571 where
572 F: 'static + FnMut(&[&Variant]) -> Result<Variant, ()>,
573 {
574 Callable::from_linked_fn(method_name, self, rust_function)
575 }
576
577 pub(crate) unsafe fn from_obj_sys_or_none(
578 ptr: sys::GDExtensionObjectPtr,
579 ) -> Result<Self, ConvertError> {
580 // Used to have a flag to select RawGd::from_obj_sys_weak(ptr) for Base::to_init_gd(), but solved differently in the end.
581 let obj = RawGd::from_obj_sys(ptr);
582
583 Self::try_from_ffi(obj)
584 }
585
586 /// Initializes this `Gd<T>` from the object pointer as a **strong ref**, meaning
587 /// it initializes/increments the reference counter and keeps the object alive.
588 ///
589 /// This is the default for most initializations from FFI. In cases where reference counter
590 /// should explicitly **not** be updated, [`Self::from_obj_sys_weak`] is available.
591 pub(crate) unsafe fn from_obj_sys(ptr: sys::GDExtensionObjectPtr) -> Self {
592 debug_assert!(
593 !ptr.is_null(),
594 "Gd::from_obj_sys() called with null pointer"
595 );
596
597 Self::from_obj_sys_or_none(ptr).unwrap()
598 }
599
600 pub(crate) unsafe fn from_obj_sys_weak_or_none(
601 ptr: sys::GDExtensionObjectPtr,
602 ) -> Result<Self, ConvertError> {
603 Self::try_from_ffi(RawGd::from_obj_sys_weak(ptr))
604 }
605
606 pub(crate) unsafe fn from_obj_sys_weak(ptr: sys::GDExtensionObjectPtr) -> Self {
607 Self::from_obj_sys_weak_or_none(ptr).unwrap()
608 }
609
610 #[doc(hidden)]
611 pub fn obj_sys(&self) -> sys::GDExtensionObjectPtr {
612 self.raw.obj_sys()
613 }
614
615 #[doc(hidden)]
616 pub fn script_sys(&self) -> sys::GDExtensionScriptLanguagePtr
617 where
618 T: Inherits<classes::ScriptLanguage>,
619 {
620 self.raw.script_sys()
621 }
622
623 /// Runs `init_fn` on the address of a pointer (initialized to null). If that pointer is still null after the `init_fn` call,
624 /// then `None` will be returned; otherwise `Gd::from_obj_sys(ptr)`.
625 ///
626 /// This method will **NOT** increment the reference-count of the object, as it assumes the input to come from a Godot API
627 /// return value.
628 ///
629 /// # Safety
630 /// `init_fn` must be a function that correctly handles a _type pointer_ pointing to an _object pointer_.
631 #[doc(hidden)]
632 pub unsafe fn from_sys_init_opt(init_fn: impl FnOnce(sys::GDExtensionTypePtr)) -> Option<Self> {
633 // TODO(uninit) - should we use GDExtensionUninitializedTypePtr instead? Then update all the builtin codegen...
634 let init_fn = |ptr| {
635 init_fn(sys::SysPtr::force_init(ptr));
636 };
637
638 // Note: see _call_native_mb_ret_obj() in godot-cpp, which does things quite different (e.g. querying the instance binding).
639
640 // Initialize pointer with given function, return Some(ptr) on success and None otherwise
641 let object_ptr = super::raw_object_init(init_fn);
642
643 // Do not increment ref-count; assumed to be return value from FFI.
644 sys::ptr_then(object_ptr, |ptr| Gd::from_obj_sys_weak(ptr))
645 }
646}
647
648/// _The methods in this impl block are only available for objects `T` that are manually managed,
649/// i.e. anything that is not `RefCounted` or inherited from it._ <br><br>
650impl<T> Gd<T>
651where
652 T: GodotClass + Bounds<Memory = bounds::MemManual>,
653{
654 /// Destroy the manually-managed Godot object.
655 ///
656 /// Consumes this smart pointer and renders all other `Gd` smart pointers (as well as any GDScript references) to the same object
657 /// immediately invalid. Using those `Gd` instances will lead to panics, but not undefined behavior.
658 ///
659 /// This operation is **safe** and effectively prevents double-free.
660 ///
661 /// Not calling `free()` on manually-managed instances causes memory leaks, unless their ownership is delegated, for
662 /// example to the node tree in case of nodes.
663 ///
664 /// # Panics
665 /// - When the referred-to object has already been destroyed.
666 /// - When this is invoked on an upcast `Gd<Object>` that dynamically points to a reference-counted type (i.e. operation not supported).
667 /// - When the object is bound by an ongoing `bind()` or `bind_mut()` call (through a separate `Gd` pointer).
668 pub fn free(self) {
669 // Note: this method is NOT invoked when the free() call happens dynamically (e.g. through GDScript or reflection).
670 // As such, do not use it for operations and validations to perform upon destruction.
671
672 // free() is likely to be invoked in destructors during panic unwind. In this case, we cannot panic again.
673 // Instead, we print an error and exit free() immediately. The closure is supposed to be used in a unit return statement.
674 let is_panic_unwind = std::thread::panicking();
675 let error_or_panic = |msg: String| {
676 if is_panic_unwind {
677 if crate::private::has_error_print_level(1) {
678 crate::godot_error!(
679 "Encountered 2nd panic in free() during panic unwind; will skip destruction:\n{msg}"
680 );
681 }
682 } else {
683 panic!("{}", msg);
684 }
685 };
686
687 // TODO disallow for singletons, either only at runtime or both at compile time (new memory policy) and runtime
688 use bounds::Declarer;
689
690 // Runtime check in case of T=Object, no-op otherwise
691 let ref_counted =
692 <<T as Bounds>::DynMemory as bounds::DynMemory>::is_ref_counted(&self.raw);
693 if ref_counted == Some(true) {
694 return error_or_panic(format!(
695 "Called free() on Gd<Object> which points to a RefCounted dynamic type; free() only supported for manually managed types\n\
696 Object: {self:?}"
697 ));
698 }
699
700 // If ref_counted returned None, that means the instance was destroyed
701 if ref_counted != Some(false) || !self.is_instance_valid() {
702 return error_or_panic("called free() on already destroyed object".to_string());
703 }
704
705 // If the object is still alive, make sure the dynamic type matches. Necessary because subsequent checks may rely on the
706 // static type information to be correct. This is a no-op in Release mode.
707 // Skip check during panic unwind; would need to rewrite whole thing to use Result instead. Having BOTH panic-in-panic and bad type is
708 // a very unlikely corner case.
709 if !is_panic_unwind {
710 self.raw.check_dynamic_type(&CallContext::gd::<T>("free"));
711 }
712
713 // SAFETY: object must be alive, which was just checked above. No multithreading here.
714 // Also checked in the C free_instance_func callback, however error message can be more precise here, and we don't need to instruct
715 // the engine about object destruction. Both paths are tested.
716 let bound = unsafe { T::Declarer::is_currently_bound(&self.raw) };
717 if bound {
718 return error_or_panic(
719 "called free() while a bind() or bind_mut() call is active".to_string(),
720 );
721 }
722
723 // SAFETY: object alive as checked.
724 // This destroys the Storage instance, no need to run destructor again.
725 unsafe {
726 sys::interface_fn!(object_destroy)(self.raw.obj_sys());
727 }
728
729 // TODO: this might leak associated data in Gd<T>, e.g. ClassName.
730 std::mem::forget(self);
731 }
732}
733
734/// _The methods in this impl block are only available for objects `T` that are reference-counted,
735/// i.e. anything that inherits `RefCounted`._ <br><br>
736impl<T> Gd<T>
737where
738 T: GodotClass + Bounds<Memory = bounds::MemRefCounted>,
739{
740 /// Makes sure that `self` does not share references with other `Gd` instances.
741 ///
742 /// Succeeds if the reference count is 1.
743 /// Otherwise, returns the shared object and its reference count.
744 ///
745 /// ## Example
746 ///
747 /// ```no_run
748 /// use godot::prelude::*;
749 ///
750 /// let obj = RefCounted::new_gd();
751 /// match obj.try_to_unique() {
752 /// Ok(unique_obj) => {
753 /// // No other Gd<T> shares a reference with `unique_obj`.
754 /// },
755 /// Err((shared_obj, ref_count)) => {
756 /// // `shared_obj` is the original object `obj`.
757 /// // `ref_count` is the total number of references (including one held by `shared_obj`).
758 /// }
759 /// }
760 /// ```
761 pub fn try_to_unique(self) -> Result<Self, (Self, usize)> {
762 use crate::obj::bounds::DynMemory as _;
763
764 match <T as Bounds>::DynMemory::get_ref_count(&self.raw) {
765 Some(1) => Ok(self),
766 Some(ref_count) => Err((self, ref_count)),
767 None => unreachable!(),
768 }
769 }
770}
771
772impl<T> Gd<T>
773where
774 T: GodotClass + Bounds<Declarer = bounds::DeclEngine>,
775{
776 /// Represents `null` when passing an object argument to Godot.
777 ///
778 /// This expression is only intended for function argument lists. It can be used whenever a Godot signature accepts
779 /// [`AsObjectArg<T>`][crate::meta::AsObjectArg]. `Gd::null_arg()` as an argument is equivalent to `Option::<Gd<T>>::None`, but less wordy.
780 ///
781 /// To work with objects that can be null, use `Option<Gd<T>>` instead. For APIs that accept `Variant`, you can pass [`Variant::nil()`].
782 ///
783 /// # Nullability
784 /// <div class="warning">
785 /// The GDExtension API does not inform about nullability of its function parameters. It is up to you to verify that the arguments you pass
786 /// are only null when this is allowed. Doing this wrong should be safe, but can lead to the function call failing.
787 /// </div>
788 ///
789 /// # Example
790 /// ```no_run
791 /// # fn some_node() -> Gd<Node> { unimplemented!() }
792 /// use godot::prelude::*;
793 ///
794 /// let mut shape: Gd<Node> = some_node();
795 /// shape.set_owner(Gd::null_arg());
796 pub fn null_arg() -> impl crate::meta::AsObjectArg<T> {
797 crate::meta::ObjectNullArg(std::marker::PhantomData)
798 }
799}
800
801impl<T> Gd<T>
802where
803 T: WithSignals,
804{
805 /// Access user-defined signals of this object.
806 ///
807 /// For classes that have at least one `#[signal]` defined, returns a collection of signal names. Each returned signal has a specialized
808 /// API for connecting and emitting signals in a type-safe way. This method is the equivalent of [`WithUserSignals::signals()`], but when
809 /// called externally (not from `self`). Furthermore, this is also available for engine classes, not just user-defined ones.
810 ///
811 /// When you are within the `impl` of a class, use `self.signals()` directly instead.
812 ///
813 /// If you haven't already, read the [book chapter about signals](https://godot-rust.github.io/book/register/signals.html) for a
814 /// walkthrough.
815 ///
816 /// [`WithUserSignals::signals()`]: crate::obj::WithUserSignals::signals()
817 #[cfg(since_api = "4.2")] #[cfg_attr(published_docs, doc(cfg(since_api = "4.2")))]
818 pub fn signals(&self) -> T::SignalCollection<'_, T> {
819 T::__signals_from_external(self)
820 }
821}
822
823// ----------------------------------------------------------------------------------------------------------------------------------------------
824// Trait impls
825
826/// Dereferences to the nearest engine class, enabling direct calls to its `&self` methods.
827///
828/// For engine classes, returns `T` itself. For user classes, returns `T::Base` (the direct engine base class).
829/// The bound ensures that the target is always an engine-provided class.
830impl<T: GodotClass> Deref for Gd<T>
831where
832 GdDerefTarget<T>: Bounds<Declarer = bounds::DeclEngine>,
833{
834 // Target is always an engine class:
835 // * if T is an engine class => T
836 // * if T is a user class => T::Base
837 type Target = GdDerefTarget<T>;
838
839 fn deref(&self) -> &Self::Target {
840 self.raw.as_target()
841 }
842}
843
844/// Mutably dereferences to the nearest engine class, enabling direct calls to its `&mut self` methods.
845///
846/// For engine classes, returns `T` itself. For user classes, returns `T::Base` (the direct engine base class).
847/// The bound ensures that the target is always an engine-provided class.
848impl<T: GodotClass> DerefMut for Gd<T>
849where
850 GdDerefTarget<T>: Bounds<Declarer = bounds::DeclEngine>,
851{
852 fn deref_mut(&mut self) -> &mut Self::Target {
853 self.raw.as_target_mut()
854 }
855}
856
857impl<T: GodotClass> GodotConvert for Gd<T> {
858 type Via = Gd<T>;
859}
860
861impl<T: GodotClass> ToGodot for Gd<T> {
862 // TODO return RefArg here?
863 type ToVia<'v> = Gd<T>;
864
865 fn to_godot(&self) -> Self::ToVia<'_> {
866 self.raw.check_rtti("to_godot");
867 self.clone()
868 }
869}
870
871impl<T: GodotClass> FromGodot for Gd<T> {
872 fn try_from_godot(via: Self::Via) -> Result<Self, ConvertError> {
873 Ok(via)
874 }
875}
876
877// Keep in sync with DynGd.
878impl<T: GodotClass> GodotType for Gd<T> {
879 // Some #[doc(hidden)] are repeated despite already declared in trait; some IDEs suggest in auto-complete otherwise.
880 type Ffi = RawGd<T>;
881
882 type ToFfi<'f>
883 = RefArg<'f, RawGd<T>>
884 where
885 Self: 'f;
886
887 #[doc(hidden)]
888 fn to_ffi(&self) -> Self::ToFfi<'_> {
889 RefArg::new(&self.raw)
890 }
891
892 #[doc(hidden)]
893 fn into_ffi(self) -> Self::Ffi {
894 self.raw
895 }
896
897 fn try_from_ffi(raw: Self::Ffi) -> Result<Self, ConvertError> {
898 if raw.is_null() {
899 Err(FromFfiError::NullRawGd.into_error(raw))
900 } else {
901 Ok(Self { raw })
902 }
903 }
904
905 fn class_name() -> ClassName {
906 T::class_name()
907 }
908
909 fn godot_type_name() -> String {
910 T::class_name().to_string()
911 }
912
913 fn qualifies_as_special_none(from_variant: &Variant) -> bool {
914 // Behavior in Godot 4.2 when unsetting an #[export]'ed property:
915 // 🔁 reset button: passes null object pointer inside Variant (as expected).
916 // 🧹 clear button: sends a NodePath with an empty string (!?).
917
918 // We recognize the latter case and return a Gd::null() instead of failing to convert the NodePath.
919 if let Ok(node_path) = from_variant.try_to::<NodePath>() {
920 if node_path.is_empty() {
921 return true;
922 }
923 }
924
925 false
926 }
927}
928
929impl<T: GodotClass> ArrayElement for Gd<T> {
930 fn element_type_string() -> String {
931 // See also impl Export for Gd<T>.
932 object_export_element_type_string::<T>(T::class_name())
933 }
934}
935
936impl<T: GodotClass> ArrayElement for Option<Gd<T>> {
937 fn element_type_string() -> String {
938 Gd::<T>::element_type_string()
939 }
940}
941
942/*
943// TODO find a way to generalize AsArg to derived->base conversions without breaking type inference in array![].
944// Possibly we could use a "canonical type" with unambiguous mapping (&Gd<T> -> &Gd<T>, not &Gd<T> -> &Gd<TBase>).
945// See also regression test in array_test.rs.
946
947impl<'r, T, TBase> AsArg<Gd<TBase>> for &'r Gd<T>
948where
949 T: Inherits<TBase>,
950 TBase: GodotClass,
951{
952 #[doc(hidden)] // Repeated despite already hidden in trait; some IDEs suggest this otherwise.
953 fn into_arg<'cow>(self) -> CowArg<'cow, Gd<TBase>>
954 where
955 'r: 'cow, // Original reference must be valid for at least as long as the returned cow.
956 {
957 // Performance: clones unnecessarily, which has overhead for ref-counted objects.
958 // A result of being generic over base objects and allowing T: Inherits<Base> rather than just T == Base.
959 // Was previously `CowArg::Borrowed(self)`. Borrowed() can maybe be specialized for objects, or combined with AsObjectArg.
960
961 CowArg::Owned(self.clone().upcast::<TBase>())
962 }
963}
964*/
965
966impl<T: GodotClass> ParamType for Gd<T> {
967 type ArgPassing = ByRef;
968}
969
970impl<T: GodotClass> AsArg<Option<Gd<T>>> for Option<&Gd<T>> {
971 fn into_arg<'cow>(self) -> CowArg<'cow, Option<Gd<T>>> {
972 // TODO avoid cloning.
973 match self {
974 Some(gd) => CowArg::Owned(Some(gd.clone())),
975 None => CowArg::Owned(None),
976 }
977 }
978}
979
980impl<T: GodotClass> ParamType for Option<Gd<T>> {
981 type ArgPassing = ByRef;
982}
983
984impl<T> Default for Gd<T>
985where
986 T: cap::GodotDefault + Bounds<Memory = bounds::MemRefCounted>,
987{
988 /// Creates a default-constructed `T` inside a smart pointer.
989 ///
990 /// This is equivalent to the GDScript expression `T.new()`, and to the shorter Rust expression `T::new_gd()`.
991 ///
992 /// This trait is only implemented for reference-counted classes. Classes with manually-managed memory (e.g. `Node`) are not covered,
993 /// because they need explicit memory management, and deriving `Default` has a high chance of the user forgetting to call `free()` on those.
994 /// `T::new_alloc()` should be used for those instead.
995 fn default() -> Self {
996 T::__godot_default()
997 }
998}
999
1000impl<T: GodotClass> Clone for Gd<T> {
1001 fn clone(&self) -> Self {
1002 out!("Gd::clone");
1003 Self {
1004 raw: self.raw.clone(),
1005 }
1006 }
1007}
1008
1009impl<T: GodotClass> Var for Gd<T> {
1010 fn get_property(&self) -> Self::Via {
1011 self.to_godot()
1012 }
1013
1014 fn set_property(&mut self, value: Self::Via) {
1015 *self = FromGodot::from_godot(value)
1016 }
1017}
1018
1019/// See [`Gd` Exporting](struct.Gd.html#exporting) section.
1020impl<T> Export for Option<Gd<T>>
1021where
1022 T: GodotClass + Bounds<Exportable = bounds::Yes>,
1023 Option<Gd<T>>: Var,
1024{
1025 fn export_hint() -> PropertyHintInfo {
1026 PropertyHintInfo::export_gd::<T>()
1027 }
1028
1029 #[doc(hidden)]
1030 fn as_node_class() -> Option<ClassName> {
1031 PropertyHintInfo::object_as_node_class::<T>()
1032 }
1033}
1034
1035impl<T: GodotClass> Default for OnEditor<Gd<T>> {
1036 fn default() -> Self {
1037 OnEditor::gd_invalid()
1038 }
1039}
1040
1041impl<T> GodotConvert for OnEditor<Gd<T>>
1042where
1043 T: GodotClass,
1044 Option<<Gd<T> as GodotConvert>::Via>: GodotType,
1045{
1046 type Via = Option<<Gd<T> as GodotConvert>::Via>;
1047}
1048
1049impl<T> Var for OnEditor<Gd<T>>
1050where
1051 T: GodotClass,
1052{
1053 fn get_property(&self) -> Self::Via {
1054 Self::get_property_inner(self)
1055 }
1056
1057 fn set_property(&mut self, value: Self::Via) {
1058 Self::set_property_inner(self, value)
1059 }
1060}
1061
1062/// See [`Gd` Exporting](struct.Gd.html#exporting) section.
1063impl<T> Export for OnEditor<Gd<T>>
1064where
1065 Self: Var,
1066 T: GodotClass + Bounds<Exportable = bounds::Yes>,
1067{
1068 fn export_hint() -> PropertyHintInfo {
1069 PropertyHintInfo::export_gd::<T>()
1070 }
1071
1072 #[doc(hidden)]
1073 fn as_node_class() -> Option<ClassName> {
1074 PropertyHintInfo::object_as_node_class::<T>()
1075 }
1076}
1077
1078impl<T: GodotClass> PartialEq for Gd<T> {
1079 /// ⚠️ Returns whether two `Gd` pointers point to the same object.
1080 ///
1081 /// # Panics
1082 /// When `self` or `other` is dead.
1083 fn eq(&self, other: &Self) -> bool {
1084 // Panics when one is dead
1085 self.instance_id() == other.instance_id()
1086 }
1087}
1088
1089impl<T: GodotClass> Eq for Gd<T> {}
1090
1091impl<T: GodotClass> Display for Gd<T> {
1092 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
1093 classes::display_string(self, f)
1094 }
1095}
1096
1097impl<T: GodotClass> Debug for Gd<T> {
1098 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
1099 classes::debug_string(self, f, "Gd")
1100 }
1101}
1102
1103impl<T: GodotClass> std::hash::Hash for Gd<T> {
1104 /// ⚠️ Hashes this object based on its instance ID.
1105 ///
1106 /// # Panics
1107 /// When `self` is dead.
1108 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
1109 self.instance_id().hash(state);
1110 }
1111}
1112
1113// Gd unwinding across panics does not invalidate any invariants;
1114// its mutability is anyway present, in the Godot engine.
1115impl<T: GodotClass> std::panic::UnwindSafe for Gd<T> {}
1116impl<T: GodotClass> std::panic::RefUnwindSafe for Gd<T> {}