Expand description
Customizable user-data wrappers.
§NativeClass
and user-data
In Godot Engine, scripted behavior is attached to base objects through “script instances”:
objects that store script state, and allow dynamic dispatch of overridden methods. GDNative
exposes this to native languages as a void *
pointer, known as “user-data”, that may point
to anything defined by the native library in question.
Godot is written in C++, and unlike Rust, it doesn’t have the same strict reference aliasing
constraints. This user-data pointer can be aliased mutably, and called freely from different
threads by the engine or other scripts. Thus, to maintain safety, wrapper types are to be used
to make sure that the Rust rules for references are always held for the self
argument, and
no UB can occur because we freed owner
or put another script on it.
§Choosing a wrapper type
The default user data wrapper used by derive macro, when no user_data
attribute is present,
is defined as the type alias DefaultUserData<T>
. Currently, it is LocalCellData<T>
. This
may change in the future, and changes to it will not be considered breaking changes.
To choose another wrapper type, put the #[user_data]
attribute on your NativeScript
type
if you are using the derive macro:
#[derive(NativeClass)]
#[inherit(gdnative::api::Node)]
#[user_data(gdnative::export::user_data::MutexData<HelloWorld>)]
struct HelloWorld;
…or, if you are implementing NativeScript
manually, set the UserData
associated type
to the type you choose.
§Which wrapper to use?
§Use a MutexData<T>
when:
- You don’t want to handle locks explicitly.
- Your
NativeClass
type is onlySend
, but notSync
.
§Use a RwLockData<T>
when:
- You don’t want to handle locks explicitly.
- Some of your exported methods take
&self
, and you don’t need them to be exclusive. - Your
NativeClass
type isSend + Sync
.
§Use a ArcData<T>
when:
- You want safety for your methods, but can’t tolerate lock overhead on each method call.
- You want fine grained lock control for parallelism.
- All your exported methods take
&self
. - Your
NativeClass
type isSend + Sync
.
§Use a LocalCellData<T>
when:
- Your
NativeClass
type is notSend
, and you will only ever use it from the thread where it’s originally created.
§Use Aether<T>
when:
- Your
NativeClass
type is a zero-sized type (ZST) that isCopy + Default
. - You don’t need to do anything special in
Drop
.
Structs§
- Aether
- Special user-data wrapper intended for zero-sized types, that does not perform any
allocation or synchronization at runtime. Does not implement
MapMut
. - ArcData
- User-data wrapper encapsulating a
Arc<T>
. Does not implementMapMut
. - Default
Lock Policy - Default lock policy that may change in future versions.
- Local
Cell Data - User-data wrapper analogous to a
Arc<RefCell<T>>
, that is restricted to the thread where it was originally created. The destructor ofT
is not guaranteed to be run if this is actually shared across multiple threads. - Mutex
Data - User-data wrapper encapsulating a
Arc<Mutex<T>>
. - Once
- Special user-data wrapper intended for objects that can only be used once. Only
implements
MapOwned
. - RwLock
Data - User-data wrapper encapsulating a
Arc<RwLock<T>>
. - Value
Taken
Enums§
- Deadlock
Policy - Policies to deal with potential deadlocks
- Infallible
- Error type indicating that an operation can’t fail.
- Local
Cell Error - Error indicating that a borrow has failed.
- Lock
Failed - Error indicating that a lock wasn’t obtained.
Traits§
- Lock
Options - Trait defining associated constants for locking wrapper options
- Map
- Trait for wrappers that can be mapped immutably.
- MapMut
- Trait for wrappers that can be mapped mutably.
- MapOwned
- Trait for wrappers that can be mapped once.
- User
Data - Trait for customizable user-data wrappers.
Type Aliases§
- Default
User Data - The default user data wrapper used by derive macro, when no
user_data
attribute is present. This may change in the future.