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::inspect::EnumConstant;
12use crate::meta::ClassName;
13use crate::obj::{bounds, Base, BaseMut, BaseRef, Bounds, Gd};
14#[cfg(since_api = "4.2")] #[cfg_attr(published_docs, doc(cfg(since_api = "4.2")))]
15use crate::registry::signal::SignalObject;
16use crate::storage::Storage;
17use godot_ffi as sys;
18
19/// Makes `T` eligible to be managed by Godot and stored in [`Gd<T>`][crate::obj::Gd] pointers.
20///
21/// The behavior of types implementing this trait is influenced by the associated types; check their documentation for information.
22///
23/// Normally, you don't need to implement this trait yourself; use [`#[derive(GodotClass)]`](../register/derive.GodotClass.html) instead.
24// Above intra-doc link to the derive-macro only works as HTML, not as symbol link.
25#[diagnostic::on_unimplemented(
26 message = "only classes registered with Godot are allowed in this context",
27 note = "you can use `#[derive(GodotClass)]` to register your own structs with Godot",
28 note = "see also: https://godot-rust.github.io/book/register/classes.html"
29)]
30pub trait GodotClass: Bounds + 'static
31where
32 Self: Sized,
33{
34 /// The immediate superclass of `T`. This is always a Godot engine class.
35 type Base: GodotClass; // not EngineClass because it can be ()
36
37 /// The name of the class, under which it is registered in Godot.
38 ///
39 /// This may deviate from the Rust struct name: `HttpRequest::class_name().as_str() == "HTTPRequest"`.
40 fn class_name() -> ClassName;
41
42 /// Initialization level, during which this class should be initialized with Godot.
43 ///
44 /// The default is a good choice in most cases; override only if you have very specific initialization requirements.
45 /// It must not be less than `Base::INIT_LEVEL`.
46 const INIT_LEVEL: InitLevel = <Self::Base as GodotClass>::INIT_LEVEL;
47
48 /// Returns whether `Self` inherits from `U`.
49 ///
50 /// This is reflexive, i.e `Self` inherits from itself.
51 ///
52 /// See also [`Inherits`] for a trait bound.
53 fn inherits<U: GodotClass>() -> bool {
54 if Self::class_name() == U::class_name() {
55 true
56 } else if Self::Base::class_name() == <NoBase>::class_name() {
57 false
58 } else {
59 Self::Base::inherits::<U>()
60 }
61 }
62}
63
64/// Type representing the absence of a base class, at the root of the hierarchy.
65///
66/// `NoBase` is used as the base class for exactly one class: [`Object`][crate::classes::Object].
67///
68/// This is an enum without any variants, as we should never construct an instance of this class.
69pub enum NoBase {}
70
71impl GodotClass for NoBase {
72 type Base = NoBase;
73
74 fn class_name() -> ClassName {
75 ClassName::none()
76 }
77
78 const INIT_LEVEL: InitLevel = InitLevel::Core; // arbitrary; never read.
79}
80
81unsafe impl Bounds for NoBase {
82 type Memory = bounds::MemManual;
83 type DynMemory = bounds::MemManual;
84 type Declarer = bounds::DeclEngine;
85 type Exportable = bounds::No;
86}
87
88/// Non-strict inheritance relationship in the Godot class hierarchy.
89///
90/// `Derived: Inherits<Base>` means that either `Derived` is a subclass of `Base`, or the class `Base` itself (hence "non-strict").
91///
92/// This trait is automatically implemented for all Godot engine classes and user-defined classes that derive [`GodotClass`].
93/// It has `GodotClass` as a supertrait, allowing your code to have bounds solely on `Derived: Inherits<Base>` rather than
94/// `Derived: Inherits<Base> + GodotClass`.
95///
96/// Inheritance is transitive across indirect base classes: `Node3D` implements `Inherits<Node>` and `Inherits<Object>`.
97///
98/// The trait is also reflexive: `T` always implements `Inherits<T>`.
99///
100/// # Usage
101///
102/// The primary use case for this trait is polymorphism: you write a function that accepts anything that derives from a certain class
103/// (including the class itself):
104/// ```no_run
105/// # use godot::prelude::*;
106/// fn print_node<T>(node: Gd<T>)
107/// where
108/// T: Inherits<Node>,
109/// {
110/// let up = node.upcast(); // type Gd<Node> inferred
111/// println!("Node #{} with name {}", up.instance_id(), up.get_name());
112/// up.free();
113/// }
114///
115/// // Call with different types
116/// print_node(Node::new_alloc()); // works on T=Node as well
117/// print_node(Node2D::new_alloc()); // or derived classes
118/// print_node(Node3D::new_alloc());
119/// ```
120///
121/// A variation of the above pattern works without `Inherits` or generics, if you move the `upcast()` into the call site:
122/// ```no_run
123/// # use godot::prelude::*;
124/// fn print_node(node: Gd<Node>) { /* ... */ }
125///
126/// // Call with different types
127/// print_node(Node::new_alloc()); // no upcast needed
128/// print_node(Node2D::new_alloc().upcast());
129/// print_node(Node3D::new_alloc().upcast());
130/// ```
131///
132/// # Safety
133///
134/// This trait must only be implemented for subclasses of `Base`.
135///
136/// Importantly, this means it is always safe to upcast a value of type `Gd<Self>` to `Gd<Base>`.
137pub unsafe trait Inherits<Base: GodotClass>: GodotClass {}
138
139// SAFETY: Every class is a subclass of itself.
140unsafe impl<T: GodotClass> Inherits<T> for T {}
141
142/// Trait that defines a `T` -> `dyn Trait` relation for use in [`DynGd`][crate::obj::DynGd].
143///
144/// You should typically not implement this manually, but use the [`#[godot_dyn]`](../register/attr.godot_dyn.html) macro.
145#[diagnostic::on_unimplemented(
146 message = "`{Trait}` needs to be a trait object linked with class `{Self}` in the library",
147 note = "you can use `#[godot_dyn]` on `impl Trait for Class` to auto-generate `impl Implements<dyn Trait> for Class`"
148)]
149// 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,
150// 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.
151// This should be safe, since lifetimes are checked throughout and the class instance remains in place (pinned) inside a DynGd.
152pub trait AsDyn<Trait>: GodotClass
153where
154 Trait: ?Sized + 'static,
155{
156 fn dyn_upcast(&self) -> &Trait;
157 fn dyn_upcast_mut(&mut self) -> &mut Trait;
158}
159
160/// Implemented for all user-defined classes, providing extensions on the raw object to interact with `Gd`.
161#[doc(hidden)]
162pub trait UserClass: Bounds<Declarer = bounds::DeclUser> {
163 #[doc(hidden)]
164 fn __config() -> crate::private::ClassConfig;
165
166 #[doc(hidden)]
167 fn __before_ready(&mut self);
168
169 #[doc(hidden)]
170 fn __default_virtual_call(
171 _method_name: &str,
172 #[cfg(since_api = "4.4")] _hash: u32,
173 ) -> sys::GDExtensionClassCallVirtual {
174 None
175 }
176}
177
178/// Auto-implemented for all engine-provided enums.
179pub trait EngineEnum: Copy {
180 fn try_from_ord(ord: i32) -> Option<Self>;
181
182 /// Ordinal value of the enumerator, as specified in Godot.
183 /// This is not necessarily unique.
184 fn ord(self) -> i32;
185
186 fn from_ord(ord: i32) -> Self {
187 Self::try_from_ord(ord)
188 .unwrap_or_else(|| panic!("ordinal {ord} does not map to any enumerator"))
189 }
190
191 /// The name of the enumerator, as it appears in Rust.
192 ///
193 /// Note that **this may not match the Rust constant name.** In case of multiple constants with the same ordinal value, this method returns
194 /// the first one in the order of definition. For example, [`LayoutDirection::LOCALE.as_str()`][crate::classes::window::LayoutDirection::LOCALE]
195 /// (ord 1) returns `"APPLICATION_LOCALE"`, because that happens to be the first constant with ordinal `1`.
196 /// See [`all_constants()`][Self::all_constants] for a more robust and general approach to introspection of enum constants.
197 ///
198 /// If the value does not match one of the known enumerators, the empty string is returned.
199 fn as_str(&self) -> &'static str;
200
201 /// The equivalent name of the enumerator, as specified in Godot.
202 ///
203 /// If the value does not match one of the known enumerators, the empty string is returned.
204 ///
205 /// # Deprecation
206 /// Design change is due to the fact that Godot enums may have multiple constants with the same ordinal value, and `godot_name()` cannot
207 /// always return a unique name for it. So there are cases where this method returns unexpected results.
208 ///
209 /// To keep the old -- possibly incorrect -- behavior, you can write the following function. However, it runs in linear rather than constant
210 /// time (which is often OK, given that there are very few constants per enum).
211 /// ```
212 /// use godot::obj::EngineEnum;
213 ///
214 /// fn godot_name<T: EngineEnum + Eq + PartialEq + 'static>(value: T) -> &'static str {
215 /// T::all_constants()
216 /// .iter()
217 /// .find(|c| c.value() == value)
218 /// .map(|c| c.godot_name())
219 /// .unwrap_or("") // Previous behavior.
220 /// }
221 /// ```
222 #[deprecated = "Moved to introspection API, see `EngineEnum::all_constants()` and `EnumConstant::godot_name()`"]
223 fn godot_name(&self) -> &'static str;
224
225 /// Returns a slice of distinct enum values.
226 ///
227 /// This excludes `MAX` constants at the end (existing only to express the number of enumerators) and deduplicates aliases,
228 /// providing only meaningful enum values. See [`all_constants()`][Self::all_constants] for a complete list of all constants.
229 ///
230 /// Enables iteration over distinct enum variants:
231 /// ```no_run
232 /// use godot::classes::window;
233 /// use godot::obj::EngineEnum;
234 ///
235 /// for mode in window::Mode::values() {
236 /// println!("* {}: {}", mode.as_str(), mode.ord());
237 /// }
238 /// ```
239 fn values() -> &'static [Self];
240
241 /// Returns metadata for all enum constants.
242 ///
243 /// This includes all constants as they appear in the enum definition, including duplicates and `MAX` constants.
244 /// For a list of useful, distinct values, use [`values()`][Self::values].
245 ///
246 /// Enables introspection of available constants:
247 /// ```no_run
248 /// use godot::classes::window;
249 /// use godot::obj::EngineEnum;
250 ///
251 /// for constant in window::Mode::all_constants() {
252 /// println!("* window::Mode.{} (original {}) has ordinal value {}.",
253 /// constant.rust_name(),
254 /// constant.godot_name(),
255 /// constant.value().ord()
256 /// );
257 /// }
258 /// ```
259 fn all_constants() -> &'static [EnumConstant<Self>];
260}
261
262/// Auto-implemented for all engine-provided bitfields.
263pub trait EngineBitfield: Copy {
264 fn try_from_ord(ord: u64) -> Option<Self>;
265
266 /// Ordinal value of the bit flag, as specified in Godot.
267 fn ord(self) -> u64;
268
269 fn from_ord(ord: u64) -> Self {
270 Self::try_from_ord(ord)
271 .unwrap_or_else(|| panic!("ordinal {ord} does not map to any valid bit flag"))
272 }
273
274 // TODO consolidate API: named methods vs. | & ! etc.
275 fn is_set(self, flag: Self) -> bool {
276 self.ord() & flag.ord() != 0
277 }
278
279 /// Returns metadata for all bitfield constants.
280 ///
281 /// This includes all constants as they appear in the bitfield definition.
282 ///
283 /// Enables introspection of available constants:
284 /// ```no_run
285 /// use godot::global::KeyModifierMask;
286 /// use godot::obj::EngineBitfield;
287 ///
288 /// for constant in KeyModifierMask::all_constants() {
289 /// println!("* KeyModifierMask.{} (original {}) has ordinal value {}.",
290 /// constant.rust_name(),
291 /// constant.godot_name(),
292 /// constant.value().ord()
293 /// );
294 /// }
295 /// ```
296 fn all_constants() -> &'static [EnumConstant<Self>];
297}
298
299/// Trait for enums that can be used as indices in arrays.
300///
301/// The conditions for a Godot enum to be "index-like" are:
302/// - Contains an enumerator ending in `_MAX`, which has the highest ordinal (denotes the size).
303/// - All other enumerators are consecutive integers inside `0..max` (no negative ordinals, no gaps).
304///
305/// Duplicates are explicitly allowed, to allow for renamings/deprecations. The order in which Godot exposes
306/// the enumerators in the JSON is irrelevant.
307pub trait IndexEnum: EngineEnum {
308 /// Number of **distinct** enumerators in the enum.
309 ///
310 /// All enumerators are guaranteed to be in the range `0..ENUMERATOR_COUNT`, so you can use them
311 /// as indices in an array of size `ENUMERATOR_COUNT`.
312 ///
313 /// Keep in mind that two enumerators with the same ordinal are only counted once.
314 const ENUMERATOR_COUNT: usize;
315
316 /// Converts the enumerator to `usize`, which can be used as an array index.
317 ///
318 /// Note that two enumerators may have the same index, if they have the same ordinal.
319 fn to_index(self) -> usize {
320 self.ord() as usize
321 }
322}
323
324/// Trait that is automatically implemented for user classes containing a `Base<T>` field.
325///
326/// Gives direct access to the containing `Gd<Self>` from `self`.
327///
328/// # Usage as a bound
329///
330/// In order to call `base()` or `base_mut()` within a function or on a type you define, you need a `WithBaseField<Base = T>` bound,
331/// where `T` is the base class of your type.
332///
333/// ```no_run
334/// # use godot::prelude::*;
335/// # use godot::obj::WithBaseField;
336/// fn some_fn<T>(value: &T)
337/// where
338/// T: WithBaseField<Base = Node3D>,
339/// {
340/// let base = value.base();
341/// let pos = base.get_position();
342/// }
343/// ```
344///
345// Possible alternative for builder APIs, although even less ergonomic: Base<T> could be Base<T, Self> and return Gd<Self>.
346#[diagnostic::on_unimplemented(
347 message = "Class `{Self}` requires a `Base<T>` field",
348 label = "missing field `_base: Base<...>` in struct declaration",
349 note = "a base field is required to access the base from within `self`, as well as for #[signal], #[rpc] and #[func(virtual)]",
350 note = "see also: https://godot-rust.github.io/book/register/classes.html#the-base-field"
351)]
352pub trait WithBaseField: GodotClass + Bounds<Declarer = bounds::DeclUser> {
353 /// Returns the `Gd` pointer containing this object.
354 ///
355 /// This is intended to be stored or passed to engine methods. You cannot call `bind()` or `bind_mut()` on it, while the method
356 /// calling `to_gd()` is still running; that would lead to a double borrow panic.
357 fn to_gd(&self) -> Gd<Self>;
358
359 /// Returns a reference to the `Base` stored by this object.
360 fn base_field(&self) -> &Base<Self::Base>;
361
362 /// Returns a shared reference suitable for calling engine methods on this object.
363 ///
364 /// Holding a shared guard prevents other code paths from obtaining a _mutable_ reference to `self`, as such it is recommended to drop the
365 /// guard as soon as you no longer need it.
366 ///
367 /// # Examples
368 ///
369 /// ```no_run
370 /// use godot::prelude::*;
371 ///
372 /// #[derive(GodotClass)]
373 /// #[class(init, base = Node)]
374 /// struct MyClass {
375 /// base: Base<Node>,
376 /// }
377 ///
378 /// #[godot_api]
379 /// impl INode for MyClass {
380 /// fn process(&mut self, _delta: f32) {
381 /// let name = self.base().get_name();
382 /// godot_print!("name is {name}");
383 /// }
384 /// }
385 ///
386 /// # pub struct Test;
387 ///
388 /// # #[gdextension]
389 /// # unsafe impl ExtensionLibrary for Test {}
390 /// ```
391 ///
392 /// However, we cannot call methods that require `&mut Base`, such as
393 /// [`Node::add_child()`](crate::classes::Node::add_child).
394 ///
395 /// ```compile_fail
396 /// use godot::prelude::*;
397 ///
398 /// #[derive(GodotClass)]
399 /// #[class(init, base = Node)]
400 /// struct MyClass {
401 /// /// base: Base<Node>,
402 /// }
403 ///
404 /// #[godot_api]
405 /// impl INode for MyClass {
406 /// fn process(&mut self, _delta: f32) {
407 /// let node = Node::new_alloc();
408 /// // fails because `add_child` requires a mutable reference.
409 /// self.base().add_child(&node);
410 /// }
411 /// }
412 ///
413 /// # pub struct Test;
414 ///
415 /// # #[gdextension]
416 /// # unsafe impl ExtensionLibrary for Test {}
417 /// ```
418 ///
419 /// For this, use [`base_mut()`](WithBaseField::base_mut()) instead.
420 fn base(&self) -> BaseRef<'_, Self> {
421 let gd = self.base_field().to_gd();
422
423 BaseRef::new(gd, self)
424 }
425
426 /// Returns a mutable reference suitable for calling engine methods on this object.
427 ///
428 /// This method will allow you to call back into the same object from Godot, unlike what would happen
429 /// if you used [`to_gd()`](WithBaseField::to_gd). You have to keep the `BaseRef` guard bound for the entire duration the engine might
430 /// re-enter a function of your class. The guard temporarily absorbs the `&mut self` reference, which allows for an additional mutable
431 /// reference to be acquired.
432 ///
433 /// Holding a mutable guard prevents other code paths from obtaining _any_ reference to `self`, as such it is recommended to drop the
434 /// guard as soon as you no longer need it.
435 ///
436 /// # Examples
437 ///
438 /// ```no_run
439 /// use godot::prelude::*;
440 ///
441 /// #[derive(GodotClass)]
442 /// #[class(init, base = Node)]
443 /// struct MyClass {
444 /// base: Base<Node>,
445 /// }
446 ///
447 /// #[godot_api]
448 /// impl INode for MyClass {
449 /// fn process(&mut self, _delta: f32) {
450 /// let node = Node::new_alloc();
451 /// self.base_mut().add_child(&node);
452 /// }
453 /// }
454 ///
455 /// # pub struct Test;
456 ///
457 /// # #[gdextension]
458 /// # unsafe impl ExtensionLibrary for Test {}
459 /// ```
460 ///
461 /// We can call back into `self` through Godot:
462 ///
463 /// ```
464 /// use godot::prelude::*;
465 ///
466 /// #[derive(GodotClass)]
467 /// #[class(init, base = Node)]
468 /// struct MyClass {
469 /// base: Base<Node>,
470 /// }
471 ///
472 /// #[godot_api]
473 /// impl INode for MyClass {
474 /// fn process(&mut self, _delta: f32) {
475 /// self.base_mut().call("other_method", &[]);
476 /// }
477 /// }
478 ///
479 /// #[godot_api]
480 /// impl MyClass {
481 /// #[func]
482 /// fn other_method(&mut self) {}
483 /// }
484 ///
485 /// # pub struct Test;
486 ///
487 /// # #[gdextension]
488 /// # unsafe impl ExtensionLibrary for Test {}
489 /// ```
490 #[allow(clippy::let_unit_value)]
491 fn base_mut(&mut self) -> BaseMut<'_, Self> {
492 let base_gd = self.base_field().to_gd();
493
494 let gd = self.to_gd();
495 // SAFETY:
496 // - We have a `Gd<Self>` so, provided that `storage_unbounded` succeeds, the associated instance
497 // storage has been created.
498 //
499 // - Since we can get a `&'a Base<Self::Base>` from `&'a self`, that must mean we have a Rust object
500 // somewhere that has this base object. The only way to have such a base object is by being the
501 // Rust object referenced by that base object. I.e. this storage's user-instance is that Rust
502 // object. That means this storage cannot be destroyed for the lifetime of that Rust object. And
503 // since we have a reference to the base object derived from that Rust object, then that Rust
504 // object must outlive `'a`. And so the storage cannot be destroyed during the lifetime `'a`.
505 let storage = unsafe {
506 gd.raw
507 .storage_unbounded()
508 .expect("we have a `Gd<Self>` so the raw should not be null")
509 };
510
511 let guard = storage.get_inaccessible(self);
512
513 BaseMut::new(base_gd, guard)
514 }
515}
516
517// Dummy traits to still allow bounds and imports.
518#[cfg(before_api = "4.2")] #[cfg_attr(published_docs, doc(cfg(before_api = "4.2")))]
519pub trait WithSignals: GodotClass {}
520#[cfg(before_api = "4.2")] #[cfg_attr(published_docs, doc(cfg(before_api = "4.2")))]
521pub trait WithUserSignals: WithSignals + WithBaseField {}
522
523/// Implemented for all classes with registered signals, both engine- and user-declared.
524///
525/// This trait enables the [`Gd::signals()`] method.
526///
527/// User-defined classes with `#[signal]` additionally implement [`WithUserSignals`].
528#[cfg(since_api = "4.2")]
529// Inherits bound makes some up/downcasting in signals impl easier.
530pub trait WithSignals: GodotClass + Inherits<crate::classes::Object> {
531 /// The associated struct listing all signals of this class.
532 ///
533 /// Parameters:
534 /// - `'c` denotes the lifetime during which the class instance is borrowed and its signals can be modified.
535 /// - `C` is the concrete class on which the signals are provided. This can be different than `Self` in case of derived classes
536 /// (e.g. a user-defined node) connecting/emitting signals of a base class (e.g. `Node`).
537 type SignalCollection<'c, C>
538 where
539 C: WithSignals;
540
541 /// Whether the representation needs to be able to hold just `Gd` (for engine classes) or `UserSignalObject` (for user classes).
542 // Note: this cannot be in Declarer (Engine/UserDecl) as associated type `type SignalObjectType<'c, T: WithSignals>`,
543 // because the user impl has the additional requirement T: WithUserSignals.
544 #[doc(hidden)]
545 type __SignalObj<'c>: SignalObject<'c>;
546 // type __SignalObj<'c, C>: SignalObject<'c>
547 // where
548 // C: WithSignals + 'c;
549
550 /// Create from existing `Gd`, to enable `Gd::signals()`.
551 ///
552 /// Only used for constructing from a concrete class, so `C = Self` in the return type.
553 ///
554 /// Takes by reference and not value, to retain lifetime chain.
555 #[doc(hidden)]
556 fn __signals_from_external(external: &Gd<Self>) -> Self::SignalCollection<'_, Self>;
557}
558
559/// Implemented for user-defined classes with at least one `#[signal]` declaration.
560///
561/// Allows to access signals from within the class, as `self.signals()`. This requires a `Base<T>` field.
562#[cfg(since_api = "4.2")] #[cfg_attr(published_docs, doc(cfg(since_api = "4.2")))]
563pub trait WithUserSignals: WithSignals + WithBaseField {
564 /// Access user-defined signals of the current object `self`.
565 ///
566 /// For classes that have at least one `#[signal]` defined, returns a collection of signal names. Each returned signal has a specialized
567 /// API for connecting and emitting signals in a type-safe way. If you need to access signals from outside (given a `Gd` pointer), use
568 /// [`Gd::signals()`] instead.
569 ///
570 /// If you haven't already, read the [book chapter about signals](https://godot-rust.github.io/book/register/signals.html) for a
571 /// walkthrough.
572 ///
573 /// # Provided API
574 ///
575 /// The returned collection provides a method for each signal, with the same name as the corresponding `#[signal]`. \
576 /// For example, if you have...
577 /// ```ignore
578 /// #[signal]
579 /// fn damage_taken(&mut self, amount: i32);
580 /// ```
581 /// ...then you can access the signal as `self.signals().damage_taken()`, which returns an object with the following API:
582 /// ```ignore
583 /// // Connects global or associated function, or a closure.
584 /// fn connect(f: impl FnMut(i32));
585 ///
586 /// // Connects a &mut self method or closure on the emitter object.
587 /// fn connect_self(f: impl FnMut(&mut Self, i32));
588 ///
589 /// // Connects a &mut self method or closure on another object.
590 /// fn connect_other<C>(f: impl FnMut(&mut C, i32));
591 ///
592 /// // Emits the signal with the given arguments.
593 /// fn emit(amount: i32);
594 /// ```
595 ///
596 /// See [`TypedSignal`](crate::registry::signal::TypedSignal) for more information.
597 fn signals(&mut self) -> Self::SignalCollection<'_, Self>;
598}
599
600/// Extension trait for all reference-counted classes.
601pub trait NewGd: GodotClass {
602 /// Return a new, ref-counted `Gd` containing a default-constructed instance.
603 ///
604 /// `MyClass::new_gd()` is equivalent to `Gd::<MyClass>::default()`.
605 ///
606 /// # Panics
607 /// If `Self` is user-defined and its default constructor `init()` panics, that panic is propagated.
608 fn new_gd() -> Gd<Self>;
609}
610
611impl<T> NewGd for T
612where
613 T: cap::GodotDefault + Bounds<Memory = bounds::MemRefCounted>,
614{
615 fn new_gd() -> Gd<Self> {
616 Gd::default()
617 }
618}
619
620/// Extension trait for all manually managed classes.
621pub trait NewAlloc: GodotClass {
622 /// Return a new, manually-managed `Gd` containing a default-constructed instance.
623 ///
624 /// The result must be manually managed, e.g. by attaching it to the scene tree or calling `free()` after usage.
625 /// Failure to do so will result in memory leaks.
626 ///
627 /// # Panics
628 /// If `Self` is user-defined and its default constructor `init()` panics, that panic is propagated to the caller.
629 #[must_use]
630 fn new_alloc() -> Gd<Self>;
631}
632
633impl<T> NewAlloc for T
634where
635 T: cap::GodotDefault + Bounds<Memory = bounds::MemManual>,
636{
637 fn new_alloc() -> Gd<Self> {
638 use crate::obj::bounds::Declarer as _;
639
640 <Self as Bounds>::Declarer::create_gd()
641 }
642}
643
644// ----------------------------------------------------------------------------------------------------------------------------------------------
645
646/// Capability traits, providing dedicated functionalities for Godot classes
647pub mod cap {
648 use super::*;
649 use crate::builtin::{StringName, Variant};
650 use crate::meta::PropertyInfo;
651 use crate::obj::{Base, Bounds, Gd};
652 use std::any::Any;
653
654 /// Trait for all classes that are default-constructible from the Godot engine.
655 ///
656 /// Enables the `MyClass.new()` syntax in GDScript, and allows the type to be used by the editor, which often default-constructs objects.
657 ///
658 /// This trait is automatically implemented for the following classes:
659 /// - User defined classes if either:
660 /// - they override an `init()` method
661 /// - they have `#[class(init)]` attribute
662 /// - Engine classes if:
663 /// - they are reference-counted and constructible (i.e. provide a `new()` method).
664 ///
665 /// This trait is not manually implemented, and you cannot call any methods. You can use it as a bound, but typically you'd use
666 /// it indirectly through [`Gd::default()`][crate::obj::Gd::default()]. Note that `Gd::default()` has an additional requirement on
667 /// being reference-counted, meaning not every `GodotDefault` class can automatically be used with `Gd::default()`.
668 #[diagnostic::on_unimplemented(
669 message = "Class `{Self}` requires either an `init` constructor, or explicit opt-out",
670 label = "needs `init`",
671 note = "to provide a default constructor, use `#[class(init)]` or implement an `init` method",
672 note = "to opt out, use `#[class(no_init)]`",
673 note = "see also: https://godot-rust.github.io/book/register/constructors.html"
674 )]
675 pub trait GodotDefault: GodotClass {
676 /// Provides a default smart pointer instance.
677 ///
678 /// Semantics:
679 /// - For user-defined classes, this calls `T::init()` or the generated init-constructor.
680 /// - For engine classes, this calls `T::new()`.
681 #[doc(hidden)]
682 fn __godot_default() -> Gd<Self> {
683 // This is a bit hackish, but the alternatives are:
684 // 1. Separate trait `GodotUserDefault` for user classes, which then proliferates through all APIs and makes abstraction harder.
685 // 2. Repeatedly implementing __godot_default() that forwards to something like Gd::default_user_instance(). Possible, but this
686 // will make the step toward builder APIs more difficult, as users would need to re-implement this as well.
687 debug_assert_eq!(
688 std::any::TypeId::of::<<Self as Bounds>::Declarer>(),
689 std::any::TypeId::of::<bounds::DeclUser>(),
690 "__godot_default() called on engine class; must be overridden for engine classes"
691 );
692
693 Gd::default_instance()
694 }
695
696 /// Only provided for user classes.
697 #[doc(hidden)]
698 fn __godot_user_init(_base: Base<Self::Base>) -> Self {
699 unreachable!(
700 "__godot_user_init() called on engine class; must be overridden for user classes"
701 )
702 }
703 }
704
705 // TODO Evaluate whether we want this public or not
706 #[doc(hidden)]
707 pub trait GodotToString: GodotClass {
708 #[doc(hidden)]
709 fn __godot_to_string(&self) -> GString;
710 }
711
712 // TODO Evaluate whether we want this public or not
713 #[doc(hidden)]
714 pub trait GodotNotification: GodotClass {
715 #[doc(hidden)]
716 fn __godot_notification(&mut self, what: i32);
717 }
718
719 // TODO Evaluate whether we want this public or not
720 #[doc(hidden)]
721 pub trait GodotRegisterClass: GodotClass {
722 #[doc(hidden)]
723 fn __godot_register_class(builder: &mut ClassBuilder<Self>);
724 }
725
726 #[doc(hidden)]
727 pub trait GodotGet: GodotClass {
728 #[doc(hidden)]
729 fn __godot_get_property(&self, property: StringName) -> Option<Variant>;
730 }
731
732 #[doc(hidden)]
733 pub trait GodotSet: GodotClass {
734 #[doc(hidden)]
735 fn __godot_set_property(&mut self, property: StringName, value: Variant) -> bool;
736 }
737
738 #[doc(hidden)]
739 pub trait GodotGetPropertyList: GodotClass {
740 #[doc(hidden)]
741 fn __godot_get_property_list(&mut self) -> Vec<crate::meta::PropertyInfo>;
742 }
743
744 #[doc(hidden)]
745 pub trait GodotPropertyGetRevert: GodotClass {
746 #[doc(hidden)]
747 fn __godot_property_get_revert(&self, property: StringName) -> Option<Variant>;
748 }
749
750 #[doc(hidden)]
751 #[cfg(since_api = "4.2")] #[cfg_attr(published_docs, doc(cfg(since_api = "4.2")))]
752 pub trait GodotValidateProperty: GodotClass {
753 #[doc(hidden)]
754 fn __godot_validate_property(&self, property: &mut PropertyInfo);
755 }
756
757 /// Auto-implemented for `#[godot_api] impl MyClass` blocks
758 pub trait ImplementsGodotApi: GodotClass {
759 #[doc(hidden)]
760 fn __register_methods();
761 #[doc(hidden)]
762 fn __register_constants();
763 #[doc(hidden)]
764 fn __register_rpcs(_: &mut dyn Any) {}
765 }
766
767 pub trait ImplementsGodotExports: GodotClass {
768 #[doc(hidden)]
769 fn __register_exports();
770 }
771
772 /// Auto-implemented for `#[godot_api] impl XyVirtual for MyClass` blocks
773 pub trait ImplementsGodotVirtual: GodotClass {
774 // Cannot use #[cfg(since_api = "4.4")] #[cfg_attr(published_docs, doc(cfg(since_api = "4.4")))] on the `hash` parameter, because the doc-postprocessing generates #[doc(cfg)],
775 // which isn't valid in parameter position.
776
777 #[cfg(before_api = "4.4")] #[cfg_attr(published_docs, doc(cfg(before_api = "4.4")))]
778 #[doc(hidden)]
779 fn __virtual_call(name: &str) -> sys::GDExtensionClassCallVirtual;
780
781 #[cfg(since_api = "4.4")] #[cfg_attr(published_docs, doc(cfg(since_api = "4.4")))]
782 #[doc(hidden)]
783 fn __virtual_call(name: &str, hash: u32) -> sys::GDExtensionClassCallVirtual;
784 }
785}