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}