gdnative_core/export/
class.rs

1use crate::export::user_data::UserData;
2use crate::export::{class_registry, ClassBuilder};
3use crate::object::ownership::{Ownership, Shared, Unique};
4use crate::object::{GodotObject, Instance, Instanciable, TRef};
5
6/// Trait used for describing and initializing a Godot script class.
7///
8/// This trait is used to provide data and functionality to the
9/// "data-part" of the class, such as name, initialization and information
10/// about exported properties.
11///
12/// A derive macro is available for this trait. See documentation on the
13/// `NativeClass` macro for detailed usage and examples.
14///
15/// For exported methods, see the [`NativeClassMethods`] trait.
16///
17/// [`NativeClassMethods`]: ./trait.NativeClassMethods.html
18pub trait NativeClass: Sized + 'static {
19    /// Base type of the class.
20    ///
21    /// In Godot, scripting languages can define "script instances" which can be
22    /// attached to objects. Because of the dynamic nature, the intended "inheritance"
23    /// is not easily implementable properly.
24    ///
25    /// Instead, delegation is used and most calls to a Godot object query the script instance
26    /// first. This way, some methods can be "overwritten" and new ones can be exposed.
27    ///
28    /// This only works when using so called "variant calls", since the querying of the script
29    /// instance is performed there.
30    /// When not using variant calls, any direct(*) calls have to be made to the Godot object
31    /// directly.
32    ///
33    /// The base type describes the "most general" type of object this script class can be
34    /// attached to.
35    ///
36    /// *(\*)*: GDNative enables use of "ptrcall"s, which are wrappers for function pointers.
37    /// Those do not do explicit checks for script implementations **unless the method
38    /// implementation does**.
39    type Base: GodotObject;
40
41    /// User-data wrapper type of the class.
42    ///
43    /// See module-level documentation on `user_data` for more info.
44    type UserData: UserData<Target = Self>;
45
46    /// Function that creates a value of `Self`, used for the script-instance. The default
47    /// implementation simply panics.
48    ///
49    /// This function has a reference to the owner object as a parameter, which can be used to
50    /// set state on the owner upon creation or to query values
51    ///
52    /// It is possible to declare script classes without zero-argument constructors. Instances
53    /// of such scripts can only be created from Rust using `Instance::emplace`. See
54    /// documentation on `Instance::emplace` for an example.
55    #[inline]
56    fn nativeclass_init(_owner: TRef<'_, Self::Base, Shared>) -> Self {
57        panic!(
58            "{} does not have a zero-argument constructor",
59            class_registry::class_name_or_default::<Self>()
60        )
61    }
62
63    /// Register any exported properties to Godot.
64    #[inline]
65    fn nativeclass_register_properties(_builder: &ClassBuilder<Self>) {}
66
67    /// Convenience method to create an `Instance<Self, Unique>`. This is a new `Self::Base`
68    /// with the script attached.
69    ///
70    /// If `Self::Base` is manually-managed, then the resulting `Instance` must be passed to
71    /// the engine or manually freed with `Instance::free`. Otherwise, the base object will be
72    /// leaked.
73    ///
74    /// Must be called after the library is initialized.
75    #[inline]
76    fn new_instance() -> Instance<Self, Unique>
77    where
78        Self::Base: Instanciable,
79    {
80        Instance::new()
81    }
82
83    /// Convenience method to emplace `self` into an `Instance<Self, Unique>`. This is a new
84    /// `Self::Base` with the script attached.
85    ///
86    /// If `Self::Base` is manually-managed, then the resulting `Instance` must be passed to
87    /// the engine or manually freed with `Instance::free`. Otherwise, the base object will be
88    /// leaked.
89    ///
90    /// Must be called after the library is initialized.
91    #[inline]
92    fn emplace(self) -> Instance<Self, Unique>
93    where
94        Self::Base: Instanciable,
95    {
96        Instance::emplace(self)
97    }
98}
99
100/// A NativeScript "class" that is statically named. [`NativeClass`] types that implement this
101/// trait can be registered using  [`InitHandle::add_class`].
102///
103/// This trait will be renamed to [`Monomorphized`] in a future version since its purpose has
104/// grown beyond simply providing a static type name.
105pub trait StaticallyNamed: NativeClass {
106    /// The name of the class.
107    ///
108    /// This name must be unique for the dynamic library. For generic or library code where this
109    /// is hard to satisfy, consider using [`InitHandle::add_class_as`] to provide a name
110    /// at registration time instead.
111    const CLASS_NAME: &'static str;
112
113    /// Function that registers methods specific to this monomorphization.
114    #[inline]
115    fn nativeclass_register_monomorphized(_builder: &ClassBuilder<Self>) {}
116}
117
118/// Trait used to provide information of Godot-exposed methods of a script class.
119pub trait NativeClassMethods: NativeClass {
120    /// Function that registers all exposed methods to Godot.
121    ///
122    fn nativeclass_register(builder: &ClassBuilder<Self>);
123}
124
125/// Trait for types that can be used as the `owner` arguments of exported methods. This trait
126/// is sealed and has no public interface.
127///
128/// # Safety
129///
130/// Whenever a NativeScript methods is called, it's assumed that the owner is safe to use.
131/// When calling a method that may call non-thread-safe methods on its owner from non-Rust
132/// code, the official [thread-safety guidelines][thread-safety] must be followed to prevent
133/// undefined behavior.
134///
135/// [thread-safety]: https://docs.godotengine.org/en/stable/tutorials/threads/thread_safe_apis.html
136pub trait OwnerArg<'a, T: GodotObject, Own: Ownership + 'static>: private::Sealed {
137    #[doc(hidden)]
138    fn from_safe_ref(owner: TRef<'a, T, Own>) -> Self;
139}
140
141impl<'a, T> private::Sealed for &'a T where T: GodotObject {}
142impl<'a, T, Own> OwnerArg<'a, T, Own> for &'a T
143where
144    T: GodotObject,
145    Own: Ownership + 'static,
146{
147    #[inline]
148    fn from_safe_ref(owner: TRef<'a, T, Own>) -> Self {
149        owner.as_ref()
150    }
151}
152
153impl<'a, T, Own> private::Sealed for TRef<'a, T, Own>
154where
155    T: GodotObject,
156    Own: Ownership + 'static,
157{
158}
159impl<'a, T, Own> OwnerArg<'a, T, Own> for TRef<'a, T, Own>
160where
161    T: GodotObject,
162    Own: Ownership + 'static,
163{
164    #[inline]
165    fn from_safe_ref(owner: TRef<'a, T, Own>) -> Self {
166        owner
167    }
168}
169
170mod private {
171    pub trait Sealed {}
172}