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 godot_ffi as sys;
9
10use crate::builder::ClassBuilder;
11use crate::builtin::GString;
12use crate::init::InitLevel;
13use crate::meta::ClassId;
14use crate::meta::inspect::EnumConstant;
15use crate::obj::{Base, BaseMut, BaseRef, BorrowedGd, Bounds, Gd, bounds};
16use crate::signal::SignalObject;
17use crate::storage::Storage;
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 /// Globally unique class ID, linked to the name under which the class is registered in Godot.
38 ///
39 /// The name may deviate from the Rust struct name: `HttpRequest::class_id().to_cow_str() == "HTTPRequest"`.
40 fn class_id() -> ClassId;
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 `Base`.
49 ///
50 /// This is reflexive, i.e `Self` inherits from itself.
51 ///
52 /// See also [`Inherits`] for a trait bound.
53 fn inherits<Base: GodotClass>() -> bool {
54 if Self::class_id() == Base::class_id() {
55 true
56 } else if Self::Base::class_id() == <NoBase>::class_id() {
57 false
58 } else {
59 Self::Base::inherits::<Base>()
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_id() -> ClassId {
75 ClassId::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 /// True iff `Self == Base`.
139 ///
140 /// Exists because something like C++'s [`std::is_same`](https://en.cppreference.com/w/cpp/types/is_same.html) is notoriously difficult
141 /// in stable Rust, due to lack of specialization.
142 const IS_SAME_CLASS: bool = false;
143}
144
145// SAFETY: Every class is a subclass of itself.
146unsafe impl<T: GodotClass> Inherits<T> for T {
147 const IS_SAME_CLASS: bool = true;
148}
149
150/// Trait that defines a `T` -> `dyn Trait` relation for use in [`DynGd`][crate::obj::DynGd].
151///
152/// You should typically not implement this manually, but use the [`#[godot_dyn]`](../register/attr.godot_dyn.html) macro.
153#[diagnostic::on_unimplemented(
154 message = "`{Trait}` needs to be a trait object linked with class `{Self}` in the library",
155 note = "you can use `#[godot_dyn]` on `impl Trait for Class` to auto-generate `impl Implements<dyn Trait> for Class`"
156)]
157// 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,
158// 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.
159// This should be safe, since lifetimes are checked throughout and the class instance remains in place (pinned) inside a DynGd.
160pub trait AsDyn<Trait>: GodotClass
161where
162 Trait: ?Sized + 'static,
163{
164 fn dyn_upcast(&self) -> &Trait;
165 fn dyn_upcast_mut(&mut self) -> &mut Trait;
166}
167
168/// Implemented for all user-defined classes, providing extensions on the raw object to interact with `Gd`.
169#[doc(hidden)]
170pub trait UserClass: Bounds<Declarer = bounds::DeclUser> {
171 #[doc(hidden)]
172 fn __config() -> crate::private::ClassConfig;
173
174 #[doc(hidden)]
175 fn __before_ready(&mut self);
176
177 #[doc(hidden)]
178 fn __default_virtual_call(
179 _method_name: &str,
180 #[cfg(since_api = "4.4")] _hash: u32,
181 ) -> sys::GDExtensionClassCallVirtual {
182 None
183 }
184}
185
186/// Auto-implemented for all engine-provided enums.
187///
188/// # Future direction: `GodotEnum` unification
189/// Currently engine enums implement this trait with `all_constants()` returning `&[EnumConstant<Self>]`, while user enums provide
190/// metadata through `GodotShape::Enum` with `&[EnumeratorShape]`. A future `GodotEnum` trait could unify both, providing a single
191/// interface for enumerator introspection, constant registration via `classdb_register_extension_class_integer_constant` (which
192/// also accepts `p_is_bitfield`), and shared `GodotShape` construction. This would let user enums opt-in to the same capabilities
193/// as engine enums (GDScript name resolution, editor integration).
194pub trait EngineEnum: Copy + 'static {
195 fn try_from_ord(ord: i32) -> Option<Self>;
196
197 /// Ordinal value of the enumerator, as specified in Godot.
198 /// This is not necessarily unique.
199 fn ord(self) -> i32;
200
201 fn from_ord(ord: i32) -> Self {
202 Self::try_from_ord(ord)
203 .unwrap_or_else(|| panic!("ordinal {ord} does not map to any enumerator"))
204 }
205
206 /// The name of the enumerator, as it appears in Rust.
207 ///
208 /// Note that **this may not match the Rust constant name.** In case of multiple constants with the same ordinal value, this method returns
209 /// the first one in the order of definition. For example, [`LayoutDirection::LOCALE.as_str()`][crate::classes::window::LayoutDirection::LOCALE]
210 /// (ord 1) returns `"APPLICATION_LOCALE"`, because that happens to be the first constant with ordinal `1`.
211 /// See [`all_constants()`][Self::all_constants] for a more robust and general approach to introspection of enum constants.
212 ///
213 /// If the value does not match one of the known enumerators, the empty string is returned.
214 fn as_str(&self) -> &'static str;
215
216 /// Returns a slice of distinct enum values.
217 ///
218 /// This excludes `MAX` constants at the end (existing only to express the number of enumerators) and deduplicates aliases,
219 /// providing only meaningful enum values. See [`all_constants()`][Self::all_constants] for a complete list of all constants.
220 ///
221 /// Enables iteration over distinct enum variants:
222 /// ```no_run
223 /// use godot::classes::window;
224 /// use godot::obj::EngineEnum;
225 ///
226 /// for mode in window::Mode::values() {
227 /// println!("* {}: {}", mode.as_str(), mode.ord());
228 /// }
229 /// ```
230 fn values() -> &'static [Self];
231
232 /// Returns metadata for all enum constants.
233 ///
234 /// This includes all constants as they appear in the enum definition, including duplicates and `MAX` constants.
235 /// For a list of useful, distinct values, use [`values()`][Self::values].
236 ///
237 /// Enables introspection of available constants:
238 /// ```no_run
239 /// use godot::classes::window;
240 /// use godot::obj::EngineEnum;
241 ///
242 /// for constant in window::Mode::all_constants() {
243 /// println!("* window::Mode.{} (original {}) has ordinal value {}.",
244 /// constant.rust_name(),
245 /// constant.godot_name(),
246 /// constant.value().ord()
247 /// );
248 /// }
249 /// ```
250 fn all_constants() -> &'static [EnumConstant<Self>];
251}
252
253/// Auto-implemented for all engine-provided bitfields.
254pub trait EngineBitfield: Copy + 'static {
255 fn try_from_ord(ord: u64) -> Option<Self>;
256
257 /// Ordinal value of the bit flag, as specified in Godot.
258 fn ord(self) -> u64;
259
260 fn from_ord(ord: u64) -> Self {
261 Self::try_from_ord(ord)
262 .unwrap_or_else(|| panic!("ordinal {ord} does not map to any valid bit flag"))
263 }
264
265 // TODO consolidate API: named methods vs. | & ! etc.
266 fn is_set(self, flag: Self) -> bool {
267 self.ord() & flag.ord() != 0
268 }
269
270 /// Returns metadata for all bitfield constants.
271 ///
272 /// This includes all constants as they appear in the bitfield definition.
273 ///
274 /// Enables introspection of available constants:
275 /// ```no_run
276 /// use godot::global::KeyModifierMask;
277 /// use godot::obj::EngineBitfield;
278 ///
279 /// for constant in KeyModifierMask::all_constants() {
280 /// println!("* KeyModifierMask.{} (original {}) has ordinal value {}.",
281 /// constant.rust_name(),
282 /// constant.godot_name(),
283 /// constant.value().ord()
284 /// );
285 /// }
286 /// ```
287 fn all_constants() -> &'static [EnumConstant<Self>];
288
289 /// Returns the flag(s) from `self` combined with the flag(s) from `add_flags` arg.
290 fn with(self, add_flags: Self) -> Self {
291 Self::from_ord(self.ord() | add_flags.ord())
292 }
293
294 /// Returns the flag(s) from `self`, except for any that were present in the `remove_flags` arg.
295 fn without(self, remove_flags: Self) -> Self {
296 Self::from_ord(self.ord() & !remove_flags.ord())
297 }
298}
299
300/// Trait for enums that can be used as indices in arrays.
301///
302/// The conditions for a Godot enum to be "index-like" are:
303/// - Contains an enumerator ending in `_MAX`, which has the highest ordinal (denotes the size).
304/// - All other enumerators are consecutive integers inside `0..max` (no negative ordinals, no gaps).
305///
306/// Duplicates are explicitly allowed, to allow for renamings/deprecations. The order in which Godot exposes
307/// the enumerators in the JSON is irrelevant.
308pub trait IndexEnum: EngineEnum {
309 /// Number of **distinct** enumerators in the enum.
310 ///
311 /// All enumerators are guaranteed to be in the range `0..ENUMERATOR_COUNT`, so you can use them
312 /// as indices in an array of size `ENUMERATOR_COUNT`.
313 ///
314 /// Keep in mind that two enumerators with the same ordinal are only counted once.
315 const ENUMERATOR_COUNT: usize;
316
317 /// Converts the enumerator to `usize`, which can be used as an array index.
318 ///
319 /// Note that two enumerators may have the same index, if they have the same ordinal.
320 fn to_index(self) -> usize {
321 self.ord() as usize
322 }
323}
324
325/// Trait that is automatically implemented for user classes containing a `Base<T>` field.
326///
327/// Gives direct access to the containing `Gd<Self>` from `self`.
328///
329/// # Usage as a bound
330///
331/// In order to call `base()` or `base_mut()` within a function or on a type you define, you need a `WithBaseField<Base = T>` bound,
332/// where `T` is the base class of your type.
333///
334/// ```no_run
335/// # use godot::prelude::*;
336/// # use godot::obj::WithBaseField;
337/// fn some_fn<T>(value: &T)
338/// where
339/// T: WithBaseField<Base = Node3D>,
340/// {
341/// let base = value.base();
342/// let pos = base.get_position();
343/// }
344/// ```
345///
346// Possible alternative for builder APIs, although even less ergonomic: Base<T> could be Base<T, Self> and return Gd<Self>.
347#[diagnostic::on_unimplemented(
348 message = "Class `{Self}` requires a `Base<T>` field",
349 label = "missing field `_base: Base<...>` in struct declaration",
350 note = "a base field is required to access the base from within `self`, as well as for #[signal], #[rpc] and #[func(virtual)]",
351 note = "see also: https://godot-rust.github.io/book/register/classes.html#the-base-field"
352)]
353pub trait WithBaseField: GodotClass + Bounds<Declarer = bounds::DeclUser> {
354 /// Returns the `Gd` pointer containing this object.
355 ///
356 /// This is intended to be stored or passed to engine methods. You cannot call `bind()` or `bind_mut()` on it, while the method
357 /// calling `to_gd()` is still running; that would lead to a double borrow panic.
358 ///
359 /// # Panics
360 /// If called during initialization (the `init()` function or `Gd::from_init_fn()`). Use [`Base::to_init_gd()`] instead.
361 fn to_gd(&self) -> Gd<Self>;
362
363 /// Returns a reference to the `Base` stored by this object.
364 #[doc(hidden)]
365 fn base_field(&self) -> &Base<Self::Base>;
366
367 /// Returns a shared reference guard, suitable for calling `&self` engine methods on this object.
368 ///
369 /// Holding a shared guard prevents other code paths from obtaining a _mutable_ reference to `self`, as such it is recommended to drop the
370 /// guard as soon as you no longer need it.
371 ///
372 /// # Examples
373 ///
374 /// ```no_run
375 /// use godot::prelude::*;
376 ///
377 /// #[derive(GodotClass)]
378 /// #[class(init, base=Node)]
379 /// struct MyClass {
380 /// base: Base<Node>,
381 /// }
382 ///
383 /// #[godot_api]
384 /// impl INode for MyClass {
385 /// fn process(&mut self, _delta: f32) {
386 /// let name = self.base().get_name();
387 /// godot_print!("name is {name}");
388 /// }
389 /// }
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 BaseRef::new(self.base_field().constructed_borrowed())
422 }
423
424 /// Returns an exclusive reference guard, suitable for calling `&self`/`&mut self` engine methods on this object.
425 ///
426 /// This method will allow you to call back into the same object from Godot -- something that [`to_gd()`][Self::to_gd] does not allow.
427 /// You have to keep the `BaseMut` guard bound for the entire duration the engine might re-enter a function of your class. The guard
428 /// temporarily absorbs the `&mut self` reference, which allows for an additional exclusive (mutable) reference to be acquired.
429 ///
430 /// Holding an exclusive guard prevents other code paths from obtaining _any_ reference to `self`, as such it is recommended to drop the
431 /// guard as soon as you no longer need it.
432 ///
433 /// # Examples
434 ///
435 /// ```no_run
436 /// # use godot::prelude::*;
437 /// #[derive(GodotClass)]
438 /// #[class(init, base = Node)]
439 /// struct MyClass {
440 /// base: Base<Node>,
441 /// }
442 ///
443 /// #[godot_api]
444 /// impl INode for MyClass {
445 /// fn process(&mut self, _delta: f32) {
446 /// let node = Node::new_alloc();
447 /// self.base_mut().add_child(&node);
448 /// }
449 /// }
450 ///
451 /// # pub struct Test;
452 ///
453 /// # #[gdextension]
454 /// # unsafe impl ExtensionLibrary for Test {}
455 /// ```
456 ///
457 /// We can call back into `self` through Godot:
458 ///
459 /// ```no_run
460 /// # use godot::prelude::*;
461 /// #[derive(GodotClass)]
462 /// #[class(init, base=Node)]
463 /// struct MyClass {
464 /// base: Base<Node>,
465 /// }
466 ///
467 /// #[godot_api]
468 /// impl INode for MyClass {
469 /// fn process(&mut self, _delta: f32) {
470 /// self.base_mut().call("other_method", &[]);
471 /// }
472 /// }
473 ///
474 /// #[godot_api]
475 /// impl MyClass {
476 /// #[func]
477 /// fn other_method(&mut self) {}
478 /// }
479 /// ```
480 ///
481 /// Rust's borrow checking rules are enforced if you try to overlap `base_mut()` calls:
482 /// ```compile_fail
483 /// # use godot::prelude::*;
484 /// # #[derive(GodotClass)]
485 /// # #[class(init)]
486 /// # struct MyStruct {
487 /// # base: Base<RefCounted>,
488 /// # }
489 /// # impl MyStruct {
490 /// // error[E0499]: cannot borrow `*self` as mutable more than once at a time
491 ///
492 /// fn method(&mut self) {
493 /// let mut a = self.base_mut();
494 /// // ---- first mutable borrow occurs here
495 /// let mut b = self.base_mut();
496 /// // ^^^^ second mutable borrow occurs here
497 /// }
498 /// # }
499 /// ```
500 #[allow(clippy::let_unit_value)]
501 fn base_mut(&mut self) -> BaseMut<'_, Self> {
502 // We need to acquire this first, as the mut-borrow below will block all other access. A raw pointer (not a BorrowedGd tied to
503 // &self) is needed, since any shared borrow of self would conflict with that mut-borrow.
504 let base_ptr = self.base_field().constructed_obj_sys();
505
506 let gd = self.to_gd();
507
508 // SAFETY:
509 // - We have a `Gd<Self>` so, provided that `storage_unbounded` succeeds, the associated instance
510 // storage has been created.
511 //
512 // - Since we can get a `&'a Base<Self::Base>` from `&'a self`, that must mean we have a Rust object
513 // somewhere that has this base object. The only way to have such a base object is by being the
514 // Rust object referenced by that base object. I.e. this storage's user-instance is that Rust
515 // object. That means this storage cannot be destroyed for the lifetime of that Rust object. And
516 // since we have a reference to the base object derived from that Rust object, then that Rust
517 // object must outlive `'a`. And so the storage cannot be destroyed during the lifetime `'a`.
518 let storage = unsafe {
519 gd.raw
520 .storage_unbounded()
521 .expect("we have Gd<Self>; its RawGd should not be null")
522 };
523
524 let guard = storage.get_inaccessible(self);
525
526 // SAFETY: `base_ptr` is the base object of this instance, and BaseMut::new() unifies the BorrowedGd's lifetime with `guard`'s
527 // borrow of the instance -- which keeps the object alive for that entire lifetime.
528 let borrowed_gd = unsafe { BorrowedGd::from_obj_sys(base_ptr) };
529
530 BaseMut::new(borrowed_gd, guard)
531 }
532
533 /// Defers the given closure to run during [idle time](https://docs.godotengine.org/en/stable/classes/class_object.html#class-object-method-call-deferred).
534 ///
535 /// This is a type-safe alternative to [`Object::call_deferred()`][crate::classes::Object::call_deferred]. The closure receives
536 /// `&mut Self` allowing direct access to Rust fields and methods.
537 ///
538 /// See also [`Gd::run_deferred()`] to defer logic outside of `self`.
539 ///
540 /// # Panics
541 /// If called outside the main thread.
542 fn run_deferred<F>(&mut self, mut_self_method: F)
543 where
544 F: FnOnce(&mut Self) + 'static,
545 {
546 // We need to copy the Gd, because the lifetime of `&mut self` does not extend throughout the closure, which will only be called
547 // deferred. It might even be freed in-between, causing panic on bind_mut().
548 self.to_gd().run_deferred(mut_self_method)
549 }
550
551 /// Defers the given closure to run during [idle time](https://docs.godotengine.org/en/stable/classes/class_object.html#class-object-method-call-deferred).
552 ///
553 /// This is a type-safe alternative to [`Object::call_deferred()`][crate::classes::Object::call_deferred]. The closure receives
554 /// `Gd<Self>`, which can be used to call engine methods or [`bind()`][Gd::bind]/[`bind_mut()`][Gd::bind_mut] to access the Rust object.
555 ///
556 /// See also [`Gd::run_deferred_gd()`] to defer logic outside of `self`.
557 ///
558 /// # Panics
559 /// If called outside the main thread.
560 fn run_deferred_gd<F>(&mut self, gd_function: F)
561 where
562 F: FnOnce(Gd<Self>) + 'static,
563 {
564 self.to_gd().run_deferred_gd(gd_function)
565 }
566}
567
568/// Implemented for all classes with registered signals, both engine- and user-declared.
569///
570/// This trait enables the [`Gd::signals()`] method.
571///
572/// User-defined classes with `#[signal]` additionally implement [`WithUserSignals`].
573// Inherits bound makes some up/downcasting in signals impl easier.
574pub trait WithSignals: Inherits<crate::classes::Object> {
575 /// The associated struct listing all signals of this class.
576 ///
577 /// Parameters:
578 /// - `'c` denotes the lifetime during which the class instance is borrowed and its signals can be modified.
579 /// - `C` is the concrete class on which the signals are provided. This can be different than `Self` in case of derived classes
580 /// (e.g. a user-defined node) connecting/emitting signals of a base class (e.g. `Node`).
581 type SignalCollection<'c, C>
582 where
583 C: WithSignals;
584
585 /// Whether the representation needs to be able to hold just `Gd` (for engine classes) or `UserSignalObject` (for user classes).
586 // Note: this cannot be in Declarer (Engine/UserDecl) as associated type `type SignalObjectType<'c, T: WithSignals>`,
587 // because the user impl has the additional requirement T: WithUserSignals.
588 #[doc(hidden)]
589 type __SignalObj<'c>: SignalObject<'c>;
590 // type __SignalObj<'c, C>: SignalObject<'c>
591 // where
592 // C: WithSignals + 'c;
593
594 /// Create from existing `Gd`, to enable `Gd::signals()`.
595 ///
596 /// Only used for constructing from a concrete class, so `C = Self` in the return type.
597 ///
598 /// Takes by reference and not value, to retain lifetime chain.
599 #[doc(hidden)]
600 fn __signals_from_external(external: &Gd<Self>) -> Self::SignalCollection<'_, Self>;
601}
602
603/// Implemented for user-defined classes with at least one `#[signal]` declaration.
604///
605/// Allows to access signals from within the class, as `self.signals()`. This requires a `Base<T>` field.
606pub trait WithUserSignals: WithSignals + WithBaseField {
607 /// Access user-defined signals of the current object `self`.
608 ///
609 /// For classes that have at least one `#[signal]` defined, returns a collection of signal names. Each returned signal has a specialized
610 /// API for connecting and emitting signals in a type-safe way. If you need to access signals from outside (given a `Gd` pointer), use
611 /// [`Gd::signals()`] instead.
612 ///
613 /// If you haven't already, read the [book chapter about signals](https://godot-rust.github.io/book/register/signals.html) for a
614 /// walkthrough.
615 ///
616 /// # Provided API
617 /// The returned collection provides a method for each signal, with the same name as the corresponding `#[signal]`. \
618 /// For example, if you have...
619 /// ```ignore
620 /// #[signal]
621 /// fn damage_taken(&mut self, amount: i32);
622 /// ```
623 /// ...then you can access the signal as `self.signals().damage_taken()`, which returns an object with the following API:
624 /// ```ignore
625 /// // Connects global or associated function, or a closure.
626 /// fn connect(f: impl FnMut(i32));
627 ///
628 /// // Connects a &mut self method or closure on the emitter object.
629 /// fn connect_self(f: impl FnMut(&mut Self, i32));
630 ///
631 /// // Connects a &mut self method or closure on another object.
632 /// fn connect_other<C>(f: impl FnMut(&mut C, i32));
633 ///
634 /// // Emits the signal with the given arguments.
635 /// fn emit(amount: i32);
636 /// ```
637 ///
638 /// See [`TypedSignal`][crate::signal::TypedSignal] for more information.
639 fn signals(&mut self) -> Self::SignalCollection<'_, Self>;
640}
641
642/// Implemented for user-defined classes with at least one `#[rpc]` declaration.
643///
644/// Allows accessing type-safe RPCs from within the class, as `self.rpcs()`. This requires a `Base<T>` field and a `Node`-derived class.
645/// To access RPCs from outside (given a `Gd` pointer), use [`Gd::rpcs()`] instead.
646// `Inherits<Node>` supertrait makes the up-casting to `Node` in the RPC implementation possible, and avoids repeating the bound in
647// generic user code. There is no scenario where user-defined RPCs can be used if the class isn't `Node`-based.
648pub trait WithUserRpcs: WithBaseField + Inherits<crate::classes::Node> {
649 /// The associated struct listing all RPCs of this class.
650 ///
651 /// `'c` denotes the lifetime during which the class instance is borrowed and its RPCs can be called.
652 type RpcCollection<'c>;
653
654 /// Access type-safe RPCs of the current object `self`.
655 ///
656 /// For classes that have at least one `#[rpc]` defined, returns a collection with one method per RPC. If you need to access RPCs from
657 /// outside (given a `Gd` pointer), use [`Gd::rpcs()`] instead.
658 ///
659 /// # Provided API
660 /// The returned collection provides a method for each RPC, with the same name as the corresponding `#[rpc]`. \
661 /// For example, the following RPC:
662 ///
663 /// ```ignore
664 /// #[rpc]
665 /// fn say_hello_to(&mut self, to: String) {
666 /// godot_print!("hello, {to}");
667 /// }
668 /// ```
669 ///
670 /// can be called with:
671 ///
672 /// ```ignore
673 /// my_node.rpcs().say_hello_to("world".to_string()).call();
674 /// my_node.rpcs().say_hello_to("world".to_string()).call_id(1); // call RPC on specific peer
675 /// ```
676 fn rpcs(&mut self) -> Self::RpcCollection<'_>;
677
678 /// Create from existing `Gd`, to enable [`Gd::rpcs()`].
679 ///
680 /// Only used for constructing from a concrete class, so `C = Self`. Takes by reference to retain the lifetime chain.
681 #[doc(hidden)]
682 fn __rpcs_from_external(external: &Gd<Self>) -> Self::RpcCollection<'_>;
683}
684
685/// Extension trait for all reference-counted classes.
686pub trait NewGd: GodotClass {
687 /// Return a new, ref-counted `Gd` containing a default-constructed instance.
688 ///
689 /// `MyClass::new_gd()` is equivalent to `Gd::<MyClass>::default()`.
690 ///
691 /// # Panics
692 /// If `Self` is user-defined and its default constructor `init()` panics, that panic is propagated.
693 fn new_gd() -> Gd<Self>;
694}
695
696impl<T> NewGd for T
697where
698 T: cap::GodotDefault + Bounds<Memory = bounds::MemRefCounted>,
699{
700 fn new_gd() -> Gd<Self> {
701 Gd::default()
702 }
703}
704
705/// Extension trait for all manually managed classes.
706pub trait NewAlloc: GodotClass {
707 /// Return a new, manually-managed `Gd` containing a default-constructed instance.
708 ///
709 /// The result must be manually managed, e.g. by attaching it to the scene tree or calling `free()` after usage.
710 /// Failure to do so will result in memory leaks.
711 ///
712 /// # Panics
713 /// If `Self` is user-defined and its default constructor `init()` panics, that panic is propagated to the caller.
714 #[must_use]
715 fn new_alloc() -> Gd<Self>;
716}
717
718/// Trait for singleton classes in Godot.
719///
720/// There is only one instance of each singleton class in the engine, accessible through [`singleton()`][Self::singleton].
721pub trait Singleton: GodotClass {
722 // Note: we cannot return &'static mut Self, as this would be very easy to mutably alias. Returning &'static Self is possible, but we'd
723 // lose the whole mutability information (even if that is best-effort and not strict Rust mutability, it makes the API much more usable).
724 // As long as the user has multiple Gd smart pointers to the same singletons, only the internal raw pointers are aliased.
725 // See also Deref/DerefMut impl for Gd.
726
727 /// Returns the singleton instance.
728 ///
729 /// # Panics
730 /// If called during global init/deinit of godot-rust, and the singleton in question is not yet available.
731 /// You can check this with [`init::is_singleton_available::<Self>()`][crate::init::is_singleton_available].
732 /// See also [`ExtensionLibrary`](../init/trait.ExtensionLibrary.html#availability-of-godot-apis-during-init-and-deinit).
733 fn singleton() -> Gd<Self>;
734}
735
736/// Trait for user-defined singleton classes in Godot.
737///
738/// Implementing this trait allows accessing a registered singleton instance through [`singleton()`][Singleton::singleton].
739/// User singletons should be registered under their class name – otherwise some Godot components (for example GDScript before 4.4) might have trouble handling them,
740/// and the editor might crash when using `T::singleton()`.
741///
742/// There should be only one instance of a given singleton class in the engine, valid as long as the library is loaded.
743/// Therefore, user singletons are limited to classes with manual memory management (ones not inheriting from `RefCounted`).
744///
745/// # Registration
746///
747/// godot-rust provides a way to register given class as an Engine Singleton with [`#[class(singleton)]`](../prelude/derive.GodotClass.html#user-engine-singletons).
748///
749/// Alternatively, a user singleton can be registered manually:
750///
751/// ```no_run
752/// # use godot::prelude::*;
753/// # use godot::classes::Engine;
754/// #[derive(GodotClass)]
755/// #[class(init, base = Object)]
756/// struct MyEngineSingleton {}
757///
758/// // Provides blanket implementation allowing to use MyEngineSingleton::singleton().
759/// // Ensures that `MyEngineSingleton` is a valid singleton (i.e., a non-refcounted GodotClass).
760/// impl UserSingleton for MyEngineSingleton {}
761///
762/// struct MyExtension;
763///
764/// #[gdextension]
765/// unsafe impl ExtensionLibrary for MyExtension {
766/// fn on_stage_init(stage: InitStage) {
767/// // Singleton should be registered before the MainLoop startup – otherwise it won't be recognized by the GDScriptParser.
768/// if stage == InitStage::Scene {
769/// let obj = MyEngineSingleton::new_alloc();
770/// Engine::singleton()
771/// .register_singleton(&MyEngineSingleton::class_id().to_string_name(), &obj);
772/// }
773/// }
774///
775/// fn on_stage_deinit(stage: InitStage) {
776/// if stage == InitStage::Scene {
777/// let obj = MyEngineSingleton::singleton();
778/// Engine::singleton()
779/// .unregister_singleton(&MyEngineSingleton::class_id().to_string_name());
780/// obj.free();
781/// }
782/// }
783/// }
784/// ```
785// For now exists mostly as a marker trait and a way to provide blanket implementation for `Singleton` trait.
786pub trait UserSingleton:
787 GodotClass + Bounds<Declarer = bounds::DeclUser, Memory = bounds::MemManual>
788{
789 /// Per-type cache for [`cached_singleton`](crate::classes::cached_singleton), or `None` to opt out.
790 ///
791 /// `#[class(singleton)]` overrides this with a `static`; manual `impl UserSingleton` keeps the default `None`, since its registration
792 /// lifetime is not guaranteed to match the cache invariants. Dispatch lives here because the blanket `Singleton` impl below cannot specialize.
793 #[doc(hidden)]
794 fn __singleton_cache() -> Option<&'static crate::private::SingletonCache> {
795 None
796 }
797}
798
799impl<T> Singleton for T
800where
801 T: UserSingleton + Inherits<crate::classes::Object>,
802{
803 fn singleton() -> Gd<T> {
804 // Note: under all safeguard levels, both paths will panic if the singleton can't be retrieved.
805 // Both functions called below are unsafe: they require the passed class name to name `T`'s class -- guaranteed by ::class_id().
806 let make_class_name = || T::class_id().to_string_name();
807
808 match T::__singleton_cache() {
809 // SAFETY: a cache is only present for `#[class(singleton)]`, whose level-gated registration matches the cache's stable-pointer
810 // invariant; `make_class_name` yields `T`'s class name.
811 Some(cache) => unsafe { crate::classes::cached_singleton::<T>(cache, make_class_name) },
812
813 // SAFETY: `make_class_name` yields `T`'s class name.
814 None => unsafe { crate::classes::singleton_unchecked_type(&make_class_name()) },
815 }
816 }
817}
818
819impl<T> NewAlloc for T
820where
821 T: cap::GodotDefault + Bounds<Memory = bounds::MemManual>,
822{
823 fn new_alloc() -> Gd<Self> {
824 use crate::obj::bounds::Declarer as _;
825
826 <Self as Bounds>::Declarer::create_gd()
827 }
828}
829
830// ----------------------------------------------------------------------------------------------------------------------------------------------
831
832/// Capability traits, providing dedicated functionalities for Godot classes
833///
834/// The `__godot_*` methods are named after the user-facing `I*` virtual; see [`crate::registry`] for the naming rule across all layers.
835pub mod cap {
836 use std::any::Any;
837
838 use super::*;
839 use crate::builtin::{StringName, Variant};
840 use crate::obj::{Base, Gd};
841 use crate::registry::info::PropertyInfo;
842 use crate::storage::{IntoVirtualMethodReceiver, VirtualMethodReceiver};
843
844 /// Trait for all classes that are default-constructible from the Godot engine.
845 ///
846 /// Enables the `MyClass.new()` syntax in GDScript, and allows the type to be used by the editor, which often default-constructs objects.
847 ///
848 /// This trait is automatically implemented for the following classes:
849 /// - User defined classes if either:
850 /// - they override an `init()` method
851 /// - they have `#[class(init)]` attribute
852 /// - Engine classes if:
853 /// - they are reference-counted and constructible (i.e. provide a `new()` method).
854 ///
855 /// This trait is not manually implemented, and you cannot call any methods. You can use it as a bound, but typically you'd use
856 /// it indirectly through [`Gd::default()`][crate::obj::Gd::default()]. Note that `Gd::default()` has an additional requirement on
857 /// being reference-counted, meaning not every `GodotDefault` class can automatically be used with `Gd::default()`.
858 #[diagnostic::on_unimplemented(
859 message = "Class `{Self}` requires either an `init` constructor, or explicit opt-out",
860 label = "needs `init`",
861 note = "to provide a default constructor, use `#[class(init)]` or implement an `init` method",
862 note = "to opt out, use `#[class(no_init)]`",
863 note = "see also: https://godot-rust.github.io/book/register/constructors.html"
864 )]
865 pub trait GodotDefault: GodotClass {
866 /// Provides a default smart pointer instance.
867 ///
868 /// Semantics:
869 /// - For user-defined classes, this calls `T::init()` or the generated init-constructor.
870 /// - For engine classes, this calls `T::new()`.
871 #[doc(hidden)]
872 fn __godot_default() -> Gd<Self> {
873 // This is a bit hackish, but the alternatives are:
874 // 1. Separate trait `GodotUserDefault` for user classes, which then proliferates through all APIs and makes abstraction harder.
875 // 2. Repeatedly implementing __godot_default() that forwards to something like Gd::default_user_instance(). Possible, but this
876 // will make the step toward builder APIs more difficult, as users would need to re-implement this as well.
877 sys::strict_assert_eq!(
878 std::any::TypeId::of::<<Self as Bounds>::Declarer>(),
879 std::any::TypeId::of::<bounds::DeclUser>(),
880 "__godot_default() called on engine class; must be overridden for engine classes"
881 );
882
883 Gd::default_instance()
884 }
885
886 /// Only provided for user classes.
887 #[doc(hidden)]
888 fn __godot_user_init(_base: Base<Self::Base>) -> Self {
889 unreachable!(
890 "__godot_user_init() called on engine class; must be overridden for user classes"
891 )
892 }
893 }
894
895 // TODO Evaluate whether we want this public or not
896 #[doc(hidden)]
897 pub trait GodotToString: GodotClass {
898 #[doc(hidden)]
899 type Recv: IntoVirtualMethodReceiver<Self>;
900
901 #[doc(hidden)]
902 fn __godot_to_string(this: VirtualMethodReceiver<Self>) -> GString;
903 }
904
905 // TODO Evaluate whether we want this public or not
906 #[doc(hidden)]
907 pub trait GodotNotification: GodotClass {
908 #[doc(hidden)]
909 fn __godot_on_notification(&mut self, what: i32);
910 }
911
912 // TODO Evaluate whether we want this public or not
913 #[doc(hidden)]
914 pub trait GodotRegisterClass: GodotClass {
915 #[doc(hidden)]
916 fn __godot_register_class(builder: &mut ClassBuilder<Self>);
917 }
918
919 #[doc(hidden)]
920 pub trait GodotGet: GodotClass {
921 #[doc(hidden)]
922 type Recv: IntoVirtualMethodReceiver<Self>;
923
924 #[doc(hidden)]
925 fn __godot_on_get(
926 this: VirtualMethodReceiver<Self>,
927 property: StringName,
928 ) -> Option<Variant>;
929 }
930
931 #[doc(hidden)]
932 pub trait GodotSet: GodotClass {
933 #[doc(hidden)]
934 type Recv: IntoVirtualMethodReceiver<Self>;
935
936 #[doc(hidden)]
937 fn __godot_on_set(
938 this: VirtualMethodReceiver<Self>,
939 property: StringName,
940 value: Variant,
941 ) -> bool;
942 }
943
944 #[doc(hidden)]
945 pub trait GodotGetPropertyList: GodotClass {
946 #[doc(hidden)]
947 type Recv: IntoVirtualMethodReceiver<Self>;
948
949 #[doc(hidden)]
950 fn __godot_on_get_property_list(
951 this: VirtualMethodReceiver<Self>,
952 ) -> Vec<crate::registry::info::PropertyInfo>;
953 }
954
955 #[doc(hidden)]
956 pub trait GodotPropertyGetRevert: GodotClass {
957 #[doc(hidden)]
958 type Recv: IntoVirtualMethodReceiver<Self>;
959
960 #[doc(hidden)]
961 fn __godot_on_property_get_revert(
962 this: VirtualMethodReceiver<Self>,
963 property: StringName,
964 ) -> Option<Variant>;
965 }
966
967 #[doc(hidden)]
968 pub trait GodotValidateProperty: GodotClass {
969 #[doc(hidden)]
970 type Recv: IntoVirtualMethodReceiver<Self>;
971
972 #[doc(hidden)]
973 fn __godot_on_validate_property(
974 this: VirtualMethodReceiver<Self>,
975 property: &mut PropertyInfo,
976 );
977 }
978
979 /// Auto-implemented for `#[godot_api] impl MyClass` blocks
980 pub trait ImplementsGodotApi: GodotClass {
981 #[doc(hidden)]
982 fn __register_methods();
983 #[doc(hidden)]
984 fn __register_constants();
985 #[doc(hidden)]
986 fn __register_rpcs(_: &mut dyn Any) {}
987 }
988
989 pub trait ImplementsGodotExports: GodotClass {
990 #[doc(hidden)]
991 fn __register_exports();
992 }
993
994 /// Auto-implemented for `#[godot_api] impl XyVirtual for MyClass` blocks
995 pub trait ImplementsGodotVirtual: GodotClass {
996 // 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)],
997 // which isn't valid in parameter position.
998
999 #[cfg(before_api = "4.4")] #[cfg_attr(published_docs, doc(cfg(before_api = "4.4")))]
1000 #[doc(hidden)]
1001 fn __virtual_call(name: &str) -> sys::GDExtensionClassCallVirtual;
1002
1003 #[cfg(since_api = "4.4")] #[cfg_attr(published_docs, doc(cfg(since_api = "4.4")))]
1004 #[doc(hidden)]
1005 fn __virtual_call(name: &str, hash: u32) -> sys::GDExtensionClassCallVirtual;
1006 }
1007}