godot_core/obj/
traits.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 crate::builder::ClassBuilder;
9use crate::builtin::GString;
10use crate::init::InitLevel;
11use crate::meta::ClassName;
12use crate::obj::{bounds, Base, BaseMut, BaseRef, Bounds, Gd};
13use crate::storage::Storage;
14
15use godot_ffi as sys;
16
17/// Makes `T` eligible to be managed by Godot and stored in [`Gd<T>`][crate::obj::Gd] pointers.
18///
19/// The behavior of types implementing this trait is influenced by the associated types; check their documentation for information.
20///
21/// Normally, you don't need to implement this trait yourself; use [`#[derive(GodotClass)]`](../register/derive.GodotClass.html) instead.
22// Above intra-doc link to the derive-macro only works as HTML, not as symbol link.
23#[diagnostic::on_unimplemented(
24    message = "Only classes registered with Godot are allowed in this context",
25    note = "you can use `#[derive(GodotClass)]` to register your own structs with Godot",
26    note = "see also: https://godot-rust.github.io/book/register/classes.html"
27)]
28pub trait GodotClass: Bounds + 'static
29where
30    Self: Sized,
31{
32    /// The immediate superclass of `T`. This is always a Godot engine class.
33    type Base: GodotClass; // not EngineClass because it can be ()
34
35    /// The name of the class, under which it is registered in Godot.
36    ///
37    /// This may deviate from the Rust struct name: `HttpRequest::class_name().as_str() == "HTTPRequest"`.
38    fn class_name() -> ClassName;
39
40    /// Initialization level, during which this class should be initialized with Godot.
41    ///
42    /// The default is a good choice in most cases; override only if you have very specific initialization requirements.
43    /// It must not be less than `Base::INIT_LEVEL`.
44    const INIT_LEVEL: InitLevel = <Self::Base as GodotClass>::INIT_LEVEL;
45
46    /// Returns whether `Self` inherits from `U`.
47    ///
48    /// This is reflexive, i.e `Self` inherits from itself.
49    ///
50    /// See also [`Inherits`] for a trait bound.
51    fn inherits<U: GodotClass>() -> bool {
52        if Self::class_name() == U::class_name() {
53            true
54        } else if Self::Base::class_name() == <NoBase>::class_name() {
55            false
56        } else {
57            Self::Base::inherits::<U>()
58        }
59    }
60}
61
62/// Type representing the absence of a base class, at the root of the hierarchy.
63///
64/// `NoBase` is used as the base class for exactly one class: [`Object`][crate::classes::Object].
65///
66/// This is an enum without any variants, as we should never construct an instance of this class.
67pub enum NoBase {}
68
69impl GodotClass for NoBase {
70    type Base = NoBase;
71
72    fn class_name() -> ClassName {
73        ClassName::none()
74    }
75
76    const INIT_LEVEL: InitLevel = InitLevel::Core; // arbitrary; never read.
77}
78
79unsafe impl Bounds for NoBase {
80    type Memory = bounds::MemManual;
81    type DynMemory = bounds::MemManual;
82    type Declarer = bounds::DeclEngine;
83    type Exportable = bounds::No;
84}
85
86/// Non-strict inheritance relationship in the Godot class hierarchy.
87///
88/// `Derived: Inherits<Base>` means that either `Derived` is a subclass of `Base`, or the class `Base` itself (hence "non-strict").
89///
90/// This trait is automatically implemented for all Godot engine classes and user-defined classes that derive [`GodotClass`].
91/// It has `GodotClass` as a supertrait, allowing your code to have bounds solely on `Derived: Inherits<Base>` rather than
92/// `Derived: Inherits<Base> + GodotClass`.
93///
94/// Inheritance is transitive across indirect base classes: `Node3D` implements `Inherits<Node>` and `Inherits<Object>`.
95///
96/// The trait is also reflexive: `T` always implements `Inherits<T>`.
97///
98/// # Usage
99///
100/// The primary use case for this trait is polymorphism: you write a function that accepts anything that derives from a certain class
101/// (including the class itself):
102/// ```no_run
103/// # use godot::prelude::*;
104/// fn print_node<T>(node: Gd<T>)
105/// where
106///     T: Inherits<Node>,
107/// {
108///     let up = node.upcast(); // type Gd<Node> inferred
109///     println!("Node #{} with name {}", up.instance_id(), up.get_name());
110///     up.free();
111/// }
112///
113/// // Call with different types
114/// print_node(Node::new_alloc());   // works on T=Node as well
115/// print_node(Node2D::new_alloc()); // or derived classes
116/// print_node(Node3D::new_alloc());
117/// ```
118///
119/// A variation of the above pattern works without `Inherits` or generics, if you move the `upcast()` into the call site:
120/// ```no_run
121/// # use godot::prelude::*;
122/// fn print_node(node: Gd<Node>) { /* ... */ }
123///
124/// // Call with different types
125/// print_node(Node::new_alloc());            // no upcast needed
126/// print_node(Node2D::new_alloc().upcast());
127/// print_node(Node3D::new_alloc().upcast());
128/// ```
129///
130/// # Safety
131///
132/// This trait must only be implemented for subclasses of `Base`.
133///
134/// Importantly, this means it is always safe to upcast a value of type `Gd<Self>` to `Gd<Base>`.
135pub unsafe trait Inherits<Base: GodotClass>: GodotClass {}
136
137// SAFETY: Every class is a subclass of itself.
138unsafe impl<T: GodotClass> Inherits<T> for T {}
139
140/// Trait that defines a `T` -> `dyn Trait` relation for use in [`DynGd`][crate::obj::DynGd].
141///
142/// You should typically not implement this manually, but use the [`#[godot_dyn]`](../register/attr.godot_dyn.html) macro.
143#[diagnostic::on_unimplemented(
144    message = "`{Trait}` needs to be a trait object linked with class `{Self}` in the library",
145    note = "you can use `#[godot_dyn]` on `impl Trait for Class` to auto-generate `impl Implements<dyn Trait> for Class`"
146)]
147// Note: technically, `Trait` doesn't _have to_ implement `Self`. The Rust type system provides no way to verify that a) D is a trait object,
148// and b) that the trait behind it is implemented for the class. Thus, users could any another reference type, such as `&str` pointing to a field.
149// This should be safe, since lifetimes are checked throughout and the class instance remains in place (pinned) inside a DynGd.
150pub trait AsDyn<Trait: ?Sized>: GodotClass {
151    fn dyn_upcast(&self) -> &Trait;
152    fn dyn_upcast_mut(&mut self) -> &mut Trait;
153}
154
155/// Implemented for all user-defined classes, providing extensions on the raw object to interact with `Gd`.
156#[doc(hidden)]
157pub trait UserClass: Bounds<Declarer = bounds::DeclUser> {
158    #[doc(hidden)]
159    fn __config() -> crate::private::ClassConfig;
160
161    #[doc(hidden)]
162    fn __before_ready(&mut self);
163
164    #[doc(hidden)]
165    fn __default_virtual_call(
166        _method_name: &str,
167        #[cfg(since_api = "4.4")] _hash: u32,
168    ) -> sys::GDExtensionClassCallVirtual {
169        None
170    }
171}
172
173/// Auto-implemented for all engine-provided enums.
174pub trait EngineEnum: Copy {
175    fn try_from_ord(ord: i32) -> Option<Self>;
176
177    /// Ordinal value of the enumerator, as specified in Godot.
178    /// This is not necessarily unique.
179    fn ord(self) -> i32;
180
181    fn from_ord(ord: i32) -> Self {
182        Self::try_from_ord(ord)
183            .unwrap_or_else(|| panic!("ordinal {ord} does not map to any enumerator"))
184    }
185
186    // The name of the enumerator, as it appears in Rust.
187    //
188    // If the value does not match one of the known enumerators, the empty string is returned.
189    fn as_str(&self) -> &'static str;
190
191    // The equivalent name of the enumerator, as specified in Godot.
192    //
193    // If the value does not match one of the known enumerators, the empty string is returned.
194    fn godot_name(&self) -> &'static str;
195}
196
197/// Auto-implemented for all engine-provided bitfields.
198pub trait EngineBitfield: Copy {
199    fn try_from_ord(ord: u64) -> Option<Self>;
200
201    /// Ordinal value of the bit flag, as specified in Godot.
202    fn ord(self) -> u64;
203
204    fn from_ord(ord: u64) -> Self {
205        Self::try_from_ord(ord)
206            .unwrap_or_else(|| panic!("ordinal {ord} does not map to any valid bit flag"))
207    }
208
209    // TODO consolidate API: named methods vs. | & ! etc.
210    fn is_set(self, flag: Self) -> bool {
211        self.ord() & flag.ord() != 0
212    }
213}
214
215/// Trait for enums that can be used as indices in arrays.
216///
217/// The conditions for a Godot enum to be "index-like" are:
218/// - Contains an enumerator ending in `_MAX`, which has the highest ordinal (denotes the size).
219/// - All other enumerators are consecutive integers inside `0..max` (no negative ordinals, no gaps).
220///
221/// Duplicates are explicitly allowed, to allow for renamings/deprecations. The order in which Godot exposes
222/// the enumerators in the JSON is irrelevant.
223pub trait IndexEnum: EngineEnum {
224    /// Number of **distinct** enumerators in the enum.
225    ///
226    /// All enumerators are guaranteed to be in the range `0..ENUMERATOR_COUNT`, so you can use them
227    /// as indices in an array of size `ENUMERATOR_COUNT`.
228    ///
229    /// Keep in mind that two enumerators with the same ordinal are only counted once.
230    const ENUMERATOR_COUNT: usize;
231
232    /// Converts the enumerator to `usize`, which can be used as an array index.
233    ///
234    /// Note that two enumerators may have the same index, if they have the same ordinal.
235    fn to_index(self) -> usize {
236        self.ord() as usize
237    }
238}
239
240/// Trait that is automatically implemented for user classes containing a `Base<T>` field.
241///
242/// Gives direct access to the containing `Gd<Self>` from `self`.
243///
244/// # Usage as a bound
245///
246/// In order to call `base()` or `base_mut()` within a function or on a type you define, you need a `WithBaseField<Base = T>` bound,
247/// where `T` is the base class of your type.
248///
249/// ```no_run
250/// # use godot::prelude::*;
251/// # use godot::obj::WithBaseField;
252/// fn some_fn<T>(value: &T)
253/// where
254///     T: WithBaseField<Base = Node3D>,
255/// {
256///     let base = value.base();
257///     let pos = base.get_position();
258/// }
259/// ```
260///
261// Possible alternative for builder APIs, although even less ergonomic: Base<T> could be Base<T, Self> and return Gd<Self>.
262#[diagnostic::on_unimplemented(
263    message = "Class `{Self}` requires a `Base<T>` field",
264    label = "missing field `_base: Base<...>`",
265    note = "A base field is required to access the base from within `self`, for script-virtual functions or #[rpc] methods",
266    note = "see also: https://godot-rust.github.io/book/register/classes.html#the-base-field"
267)]
268pub trait WithBaseField: GodotClass + Bounds<Declarer = bounds::DeclUser> {
269    /// Returns the `Gd` pointer containing this object.
270    ///
271    /// This is intended to be stored or passed to engine methods. You cannot call `bind()` or `bind_mut()` on it, while the method
272    /// calling `to_gd()` is still running; that would lead to a double borrow panic.
273    fn to_gd(&self) -> Gd<Self>;
274
275    /// Returns a reference to the `Base` stored by this object.
276    fn base_field(&self) -> &Base<Self::Base>;
277
278    /// Returns a shared reference suitable for calling engine methods on this object.
279    ///
280    /// Holding a shared guard prevents other code paths from obtaining a _mutable_ reference to `self`, as such it is recommended to drop the
281    /// guard as soon as you no longer need it.
282    ///
283    /// # Examples
284    ///
285    /// ```no_run
286    /// use godot::prelude::*;
287    ///
288    /// #[derive(GodotClass)]
289    /// #[class(init, base = Node)]
290    /// struct MyClass {
291    ///     base: Base<Node>,
292    /// }
293    ///
294    /// #[godot_api]
295    /// impl INode for MyClass {
296    ///     fn process(&mut self, _delta: f64) {
297    ///         let name = self.base().get_name();
298    ///         godot_print!("name is {name}");
299    ///     }
300    /// }
301    ///
302    /// # pub struct Test;
303    ///
304    /// # #[gdextension]
305    /// # unsafe impl ExtensionLibrary for Test {}
306    /// ```
307    ///
308    /// However, we cannot call methods that require `&mut Base`, such as
309    /// [`Node::add_child()`](crate::classes::Node::add_child).
310    ///
311    /// ```compile_fail
312    /// use godot::prelude::*;
313    ///
314    /// #[derive(GodotClass)]
315    /// #[class(init, base = Node)]
316    /// struct MyClass {
317    ///     ///     base: Base<Node>,
318    /// }
319    ///
320    /// #[godot_api]
321    /// impl INode for MyClass {
322    ///     fn process(&mut self, _delta: f64) {
323    ///         let node = Node::new_alloc();
324    ///         // fails because `add_child` requires a mutable reference.
325    ///         self.base().add_child(&node);
326    ///     }
327    /// }
328    ///
329    /// # pub struct Test;
330    ///
331    /// # #[gdextension]
332    /// # unsafe impl ExtensionLibrary for Test {}
333    /// ```
334    ///
335    /// For this, use [`base_mut()`](WithBaseField::base_mut()) instead.
336    fn base(&self) -> BaseRef<'_, Self> {
337        let gd = self.base_field().to_gd();
338
339        BaseRef::new(gd, self)
340    }
341
342    /// Returns a mutable reference suitable for calling engine methods on this object.
343    ///
344    /// This method will allow you to call back into the same object from Godot, unlike what would happen
345    /// if you used [`to_gd()`](WithBaseField::to_gd).
346    ///
347    /// Holding a mutable guard prevents other code paths from obtaining _any_ reference to `self`, as such it is recommended to drop the
348    /// guard as soon as you no longer need it.
349    ///
350    /// # Examples
351    ///
352    /// ```no_run
353    /// use godot::prelude::*;
354    ///
355    /// #[derive(GodotClass)]
356    /// #[class(init, base = Node)]
357    /// struct MyClass {
358    ///     base: Base<Node>,
359    /// }
360    ///
361    /// #[godot_api]
362    /// impl INode for MyClass {
363    ///     fn process(&mut self, _delta: f64) {
364    ///         let node = Node::new_alloc();
365    ///         self.base_mut().add_child(&node);
366    ///     }
367    /// }
368    ///
369    /// # pub struct Test;
370    ///
371    /// # #[gdextension]
372    /// # unsafe impl ExtensionLibrary for Test {}
373    /// ```
374    ///
375    /// We can call back into `self` through Godot:
376    ///
377    /// ```
378    /// use godot::prelude::*;
379    ///
380    /// #[derive(GodotClass)]
381    /// #[class(init, base = Node)]
382    /// struct MyClass {
383    ///     base: Base<Node>,
384    /// }
385    ///
386    /// #[godot_api]
387    /// impl INode for MyClass {
388    ///     fn process(&mut self, _delta: f64) {
389    ///         self.base_mut().call("other_method", &[]);
390    ///     }
391    /// }
392    ///
393    /// #[godot_api]
394    /// impl MyClass {
395    ///     #[func]
396    ///     fn other_method(&mut self) {}
397    /// }
398    ///
399    /// # pub struct Test;
400    ///
401    /// # #[gdextension]
402    /// # unsafe impl ExtensionLibrary for Test {}
403    /// ```
404    #[allow(clippy::let_unit_value)]
405    fn base_mut(&mut self) -> BaseMut<'_, Self> {
406        let base_gd = self.base_field().to_gd();
407
408        let gd = self.to_gd();
409        // SAFETY:
410        // - We have a `Gd<Self>` so, provided that `storage_unbounded` succeeds, the associated instance
411        //   storage has been created.
412        //
413        // - Since we can get a `&'a Base<Self::Base>` from `&'a self`, that must mean we have a Rust object
414        //   somewhere that has this base object. The only way to have such a base object is by being the
415        //   Rust object referenced by that base object. I.e. this storage's user-instance is that Rust
416        //   object. That means this storage cannot be destroyed for the lifetime of that Rust object. And
417        //   since we have a reference to the base object derived from that Rust object, then that Rust
418        //   object must outlive `'a`. And so the storage cannot be destroyed during the lifetime `'a`.
419        let storage = unsafe {
420            gd.raw
421                .storage_unbounded()
422                .expect("we have a `Gd<Self>` so the raw should not be null")
423        };
424
425        let guard = storage.get_inaccessible(self);
426
427        BaseMut::new(base_gd, guard)
428    }
429}
430
431/// Extension trait for all reference-counted classes.
432pub trait NewGd: GodotClass {
433    /// Return a new, ref-counted `Gd` containing a default-constructed instance.
434    ///
435    /// `MyClass::new_gd()` is equivalent to `Gd::<MyClass>::default()`.
436    fn new_gd() -> Gd<Self>;
437}
438
439impl<T> NewGd for T
440where
441    T: cap::GodotDefault + Bounds<Memory = bounds::MemRefCounted>,
442{
443    fn new_gd() -> Gd<Self> {
444        Gd::default()
445    }
446}
447
448/// Extension trait for all manually managed classes.
449pub trait NewAlloc: GodotClass {
450    /// Return a new, manually-managed `Gd` containing a default-constructed instance.
451    ///
452    /// The result must be manually managed, e.g. by attaching it to the scene tree or calling `free()` after usage.
453    /// Failure to do so will result in memory leaks.
454    #[must_use]
455    fn new_alloc() -> Gd<Self>;
456}
457
458impl<T> NewAlloc for T
459where
460    T: cap::GodotDefault + Bounds<Memory = bounds::MemManual>,
461{
462    fn new_alloc() -> Gd<Self> {
463        use crate::obj::bounds::Declarer as _;
464
465        <Self as Bounds>::Declarer::create_gd()
466    }
467}
468
469// ----------------------------------------------------------------------------------------------------------------------------------------------
470
471/// Capability traits, providing dedicated functionalities for Godot classes
472pub mod cap {
473    use super::*;
474    use crate::builtin::{StringName, Variant};
475    use crate::meta::PropertyInfo;
476    use crate::obj::{Base, Bounds, Gd};
477    use std::any::Any;
478
479    /// Trait for all classes that are default-constructible from the Godot engine.
480    ///
481    /// Enables the `MyClass.new()` syntax in GDScript, and allows the type to be used by the editor, which often default-constructs objects.
482    ///
483    /// This trait is automatically implemented for the following classes:
484    /// - User defined classes if either:
485    ///   - they override an `init()` method
486    ///   - they have `#[class(init)]` attribute
487    /// - Engine classes if:
488    ///   - they are reference-counted and constructible (i.e. provide a `new()` method).
489    ///
490    /// This trait is not manually implemented, and you cannot call any methods. You can use it as a bound, but typically you'd use
491    /// it indirectly through [`Gd::default()`][crate::obj::Gd::default()]. Note that `Gd::default()` has an additional requirement on
492    /// being reference-counted, meaning not every `GodotDefault` class can automatically be used with `Gd::default()`.
493    #[diagnostic::on_unimplemented(
494        message = "Class `{Self}` requires either an `init` constructor, or explicit opt-out",
495        label = "needs `init`",
496        note = "To provide a default constructor, use `#[class(init)]` or implement an `init` method",
497        note = "To opt out, use `#[class(no_init)]`",
498        note = "see also: https://godot-rust.github.io/book/register/constructors.html"
499    )]
500    pub trait GodotDefault: GodotClass {
501        /// Provides a default smart pointer instance.
502        ///
503        /// Semantics:
504        /// - For user-defined classes, this calls `T::init()` or the generated init-constructor.
505        /// - For engine classes, this calls `T::new()`.
506        #[doc(hidden)]
507        fn __godot_default() -> Gd<Self> {
508            // This is a bit hackish, but the alternatives are:
509            // 1. Separate trait `GodotUserDefault` for user classes, which then proliferates through all APIs and makes abstraction harder.
510            // 2. Repeatedly implementing __godot_default() that forwards to something like Gd::default_user_instance(). Possible, but this
511            //    will make the step toward builder APIs more difficult, as users would need to re-implement this as well.
512            debug_assert_eq!(
513                std::any::TypeId::of::<<Self as Bounds>::Declarer>(),
514                std::any::TypeId::of::<bounds::DeclUser>(),
515                "__godot_default() called on engine class; must be overridden for engine classes"
516            );
517
518            Gd::default_instance()
519        }
520
521        /// Only provided for user classes.
522        #[doc(hidden)]
523        fn __godot_user_init(_base: Base<Self::Base>) -> Self {
524            unreachable!(
525                "__godot_user_init() called on engine class; must be overridden for user classes"
526            )
527        }
528    }
529
530    // TODO Evaluate whether we want this public or not
531    #[doc(hidden)]
532    pub trait GodotToString: GodotClass {
533        #[doc(hidden)]
534        fn __godot_to_string(&self) -> GString;
535    }
536
537    // TODO Evaluate whether we want this public or not
538    #[doc(hidden)]
539    pub trait GodotNotification: GodotClass {
540        #[doc(hidden)]
541        fn __godot_notification(&mut self, what: i32);
542    }
543
544    // TODO Evaluate whether we want this public or not
545    #[doc(hidden)]
546    pub trait GodotRegisterClass: GodotClass {
547        #[doc(hidden)]
548        fn __godot_register_class(builder: &mut ClassBuilder<Self>);
549    }
550
551    #[doc(hidden)]
552    pub trait GodotGet: GodotClass {
553        #[doc(hidden)]
554        fn __godot_get_property(&self, property: StringName) -> Option<Variant>;
555    }
556
557    #[doc(hidden)]
558    pub trait GodotSet: GodotClass {
559        #[doc(hidden)]
560        fn __godot_set_property(&mut self, property: StringName, value: Variant) -> bool;
561    }
562
563    #[doc(hidden)]
564    pub trait GodotGetPropertyList: GodotClass {
565        #[doc(hidden)]
566        fn __godot_get_property_list(&mut self) -> Vec<crate::meta::PropertyInfo>;
567    }
568
569    #[doc(hidden)]
570    pub trait GodotPropertyGetRevert: GodotClass {
571        #[doc(hidden)]
572        fn __godot_property_get_revert(&self, property: StringName) -> Option<Variant>;
573    }
574
575    #[doc(hidden)]
576    #[cfg(since_api = "4.2")]
577    pub trait GodotValidateProperty: GodotClass {
578        #[doc(hidden)]
579        fn __godot_validate_property(&self, property: &mut PropertyInfo);
580    }
581
582    /// Auto-implemented for `#[godot_api] impl MyClass` blocks
583    pub trait ImplementsGodotApi: GodotClass {
584        #[doc(hidden)]
585        fn __register_methods();
586        #[doc(hidden)]
587        fn __register_constants();
588        #[doc(hidden)]
589        fn __register_rpcs(_: &mut dyn Any) {}
590    }
591
592    pub trait ImplementsGodotExports: GodotClass {
593        #[doc(hidden)]
594        fn __register_exports();
595    }
596
597    /// Auto-implemented for `#[godot_api] impl XyVirtual for MyClass` blocks
598    pub trait ImplementsGodotVirtual: GodotClass {
599        #[doc(hidden)]
600        fn __virtual_call(
601            name: &str,
602            #[cfg(since_api = "4.4")] hash: u32,
603        ) -> sys::GDExtensionClassCallVirtual;
604    }
605}