Module user_data

Source
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 only Send, but not Sync.

§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 is Send + 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 is Send + Sync.

§Use a LocalCellData<T> when:

  • Your NativeClass type is not Send, 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 is Copy + 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 implement MapMut.
DefaultLockPolicy
Default lock policy that may change in future versions.
LocalCellData
User-data wrapper analogous to a Arc<RefCell<T>>, that is restricted to the thread where it was originally created. The destructor of T is not guaranteed to be run if this is actually shared across multiple threads.
MutexData
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.
RwLockData
User-data wrapper encapsulating a Arc<RwLock<T>>.
ValueTaken

Enums§

DeadlockPolicy
Policies to deal with potential deadlocks
Infallible
Error type indicating that an operation can’t fail.
LocalCellError
Error indicating that a borrow has failed.
LockFailed
Error indicating that a lock wasn’t obtained.

Traits§

LockOptions
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.
UserData
Trait for customizable user-data wrappers.

Type Aliases§

DefaultUserData
The default user data wrapper used by derive macro, when no user_data attribute is present. This may change in the future.