Derive Macro gdnative_derive::NativeClass

source ·
#[derive(NativeClass)]
{
    // Attributes available to this derive:
    #[inherit]
    #[register_with]
    #[no_constructor]
    #[user_data]
    #[property]
}
Expand description

Makes it possible to use a type as a NativeScript. Automatically registers the type if the inventory feature is enabled on supported platforms.

Type attributes

The behavior of the derive macro can be customized using attributes on the type deriving NativeClass. All type attributes are optional.

#[inherit(gdnative::api::BaseClass)]

Sets gdnative::api::BaseClass as the base class for the script. This must be a type from the generated Godot API (that implements GodotObject). All owner arguments of exported methods must be references (TRef, Ref, or &) to this type.

Inheritance from other scripts, either in Rust or other languages, is not supported.

If no #[inherit(...)] is provided, gdnative::api::Reference is used as a base class. This behavior is consistent with GDScript: omitting the extends keyword will inherit Reference.

#[user_data(gdnative::user_data::SomeWrapper<Self>)]

Use the given type as the user-data wrapper. See the module-level docs on gdnative::user_data for more information.

#[register_with(path::to::function)]

Use a custom function to register signals, properties or methods, in addition to the one generated by #[methods]:

use gdnative::prelude::*;
use gdnative::export::hint::{RangeHint, FloatHint};

#[derive(NativeClass)]
#[inherit(Reference)]
#[register_with(Self::my_register_function)]
struct Foo;

#[methods]
impl Foo {
    fn new(_: &Reference) -> Self {
        Self {}
    }
    fn my_register_function(builder: &ClassBuilder<Foo>) {
        builder.signal("my_sig").done();
        builder.property::<f32>("my_prop")
            .with_getter(|_, _| 42.0)
            .with_hint(FloatHint::Range(RangeHint::new(0.0, 100.0)))
            .done();
    }
}

#[no_constructor]

Indicates that this type has no zero-argument constructor. Instances of such scripts can only be created from Rust using Instance::emplace. Instance::new or ScriptName.new from GDScript will result in panics at runtime.

See documentation on Instance::emplace for an example on how this can be used.

Field attributes

All field attributes are optional.

#[property]

Convenience attribute to register a field as a property. Possible arguments for the attribute are:

  • path = "my_category/my_property_name"

    Puts the property under the my_category category and renames it to my_property_name in the inspector and for GDScript.

  • default = 42.0

    Sets the default value in the inspector for this property. The setter is not guaranteed to be called by the engine with the value.

  • get / get_ref / set

    Configure getter/setter for property. All of them can accept a path to specify a custom property accessor. For example, #[property(get = "Self::my_getter")] will use Self::my_getter as the getter.

    The difference of get and get_ref is that get will register the getter with with_getter function, which means your getter should return an owned value T, but get_ref use with_ref_getter to register getter. In this case, your custom getter should return a shared reference &T.

    Situations with custom getters/setters and no backing fields require the use of the type [Property<T>][gdnative::export::Property]. Consult its documentation for a deeper elaboration of property exporting.

  • no_editor

    Hides the property from the editor. Does not prevent it from being sent over network or saved in storage.

  • rpc = "selected_rpc"

    Sets the Multiplayer API RPC Mode for the property. See the #[method] documentation below for possible values and their semantics.

#[methods]

Adds the necessary information to a an impl block to register the properties and methods with Godot.

One and only one universal impl block must be available for each NativeClass monomorphization, along with any number of additional mix-ins. See methods for more information.

#[method]

Registers the attributed function signature to be used by Godot.

This attribute was formerly called #[export], but is not directly related to the concept of exporting in GDScript.

A valid function signature must have:

  • self, &self or &mut self as its first parameter, if applicable.
  • Up of one of each of the following special arguments, in any order, denoted by the attributes:
    • #[base] - A reference to the base/owner object. This may be &T or TRef<T>m where T refers to the type declared in #[inherit(T)] attribute for the NativeClass type.
    • #[async_ctx] - The async context, for async methods. See the async argument below.
  • Any number of required parameters, which must have the type Variant or must implement the FromVariant trait. FromVariant is implemented for most common types.
  • Any number of optional parameters annotated with #[opt]. Same rules as for required parameters apply. Optional parameters must appear at the end of the parameter list.
  • Return values must implement the OwnedToVariant trait (automatically implemented by ToVariant) or be a Variant type.
// Associated function
#[method]
fn foo();

// No access to base parameter
#[method]
fn foo(&self);

// Access base parameter as &T
#[method]
fn foo(&self, #[base] base: &Reference);

// Access base parameter as TRef<T>
#[method]
fn foo(&self, #[base] base: TRef<Reference>);

// Access only the async context. Both variations are valid.
#[method]
async fn foo(#[async_ctx] ctx: Arc<Context>);
#[method(async)]
fn foo(#[async_ctx] ctx: Arc<Context>) -> impl Future<Output = ()> + 'static;

// Access the base parameter as TRef<T>, and the async context. Both variations are valid.
// Note the absence of `async fn`s here: this is due to a current limitation in Rust's lifetime elision rules.
// See the `async` attribute argument down below for more details.
#[method(async)]
fn foo(&self, #[base] base: TRef<Reference>, #[async_ctx] ctx: Arc<Context>) -> impl Future<Output = ()> + 'static;
#[method(async)]
fn foo(&self, #[async_ctx] ctx: Arc<Context>, #[base] base: TRef<Reference>) -> impl Future<Output = ()> + 'static;

Note: Marking a function with #[method] does not have any effect unless inside an impl block that has the #[methods] attribute.

Possible arguments for this attribute are:

  • name = "overridden_function_name"

    Overrides the function name as the method name to be registered in Godot.

  • rpc = "selected_rpc"

    "selected_rpc" must be one of the following values, which refer to the associated Multiplayer API RPC Mode. See also the Rust type [export::RpcMode].

    • "disabled"
    • "remote"
    • "remote_sync"
    • "master"
    • "master_sync"
    • "puppet"
    • "puppet_sync"

    This enables you to set the Multiplayer API RPC Mode for the function. Refer to Godot’s Remote Procedure documentation for more details.

  • deref_return

    Allows you to return a type using its Deref representation. This can avoid extra intermediate copies for larger objects, by explicitly returning a reference (or in general, a type that dereferences to something that can be exported).

    For example:

    #[method(deref_return)]
    fn get_numbers(&self) -> std::cell::Ref<Vec<i32>> {
       // Assume self.cell is std::cell::RefCell<Vec<i32>>
       self.cell.borrow()
    }
  • async

    Marks the function as async. This is used for functions that aren’t async themselves, but return Futures instead. This is especially useful for working around Rust’s lifetime elision rules, which put the lifetime of &self into the return value for async fns. The impl Future syntax instead allows one to explicitly specify a 'static lifetime, as required by the async runtime:

    // This will NOT compile: Rust assumes that any futures returned by an `async fn` may only live as long as each of its
    // arguments, and there is no way to tell it otherwise. As a result, it will emit some cryptic complaints about lifetime.
    #[method]
    async fn answer(&self) -> i32 {
       42
    }
    
    // This, however, compiles, thanks to the explicit `'static` lifetime in the return signature.
    #[method(async)]
    fn answer(&self) -> impl Future<Output = i32> + 'static {
       async { 42 }
    }
    
Node virtual functions

This is a list of common Godot virtual functions that are automatically called via notifications.

It is assumed that every method is exported via #[method] attribute. The parameter #[base] base: &Node can be omitted if you don’t need it.

fn _ready(&self, #[base] base: &Node);

Called when both the node and its children have entered the scene tree.
See Godot docs for more information.

fn _enter_tree(&self, #[base] base: &Node);

Called when the node enters the scene tree.
See Godot docs for more information.

fn _exit_tree(&self, #[base] base: &Node);

Called when the node is removed from the scene tree.
See Godot docs for more information.

fn _get_configuration_warning(&self, #[base] base: &Node) -> GodotString;

The string returned from this method is displayed as a warning in the Scene Dock if the script that overrides it is a tool script.
See Godot docs for more information.

fn _process(&mut self, #[base] base: &Node, delta: f64);

Called during processing step of the main loop.
See Godot docs for more information.

fn _physics_process(&self, #[base] base: &Node, delta: f64);

Called during physics update, with a fixed timestamp.
See Godot docs for more information.

fn _input(&self, #[base] base: &Node, event: Ref<InputEvent>);

Called when there is an input event.
See Godot docs for more information.

fn _unhandled_input(&self, #[base] base: &Node, event: Ref<InputEvent>);

Called when an InputEvent hasn’t been consumed by _input() or any GUI.
See Godot docs for more information.

fn _unhandled_key_input (&self, #[base] base: &Node, event: Ref<InputKeyEvent>);

Called when an InputEventKey hasn’t been consumed by _input() or any GUI.
See Godot docs for more information.

Control virtual functions

This is a list of common Godot virtual functions that are automatically called via notifications.

fn _clips_input(&self, #[base] base: &Control) -> bool;

Returns whether _gui_input() should not be called for children controls outside this control’s rectangle.
See Godot docs for more information.

fn _get_minimum_size(&self, #[base] base: &Control) -> Vector2;

Returns the minimum size for this control.
See Godot docs for more information.

fn _gui_input(&self, #[base] base: &Control, event: Ref<InputEvent>);

Use this method to process and accept inputs on UI elements.
See Godot docs for more information.

fn _make_custom_tooltip(&self, #[base] base: &Control, for_text: String) -> Ref<Control>;

Returns a Control node that should be used as a tooltip instead of the default one.
See Godot docs for more information.