Trait WithBaseField

Source
pub trait WithBaseField: GodotClass + Bounds<Declarer = DeclUser> {
    // Required methods
    fn to_gd(&self) -> Gd<Self>;
    fn base_field(&self) -> &Base<Self::Base>;

    // Provided methods
    fn base(&self) -> BaseRef<'_, Self> { ... }
    fn base_mut(&mut self) -> BaseMut<'_, Self> { ... }
}
Expand description

Trait that is automatically implemented for user classes containing a Base<T> field.

Gives direct access to the containing Gd<Self> from self.

§Usage as a bound

In order to call base() or base_mut() within a function or on a type you define, you need a WithBaseField<Base = T> bound, where T is the base class of your type.

fn some_fn<T>(value: &T)
where
    T: WithBaseField<Base = Node3D>,
{
    let base = value.base();
    let pos = base.get_position();
}

Required Methods§

Source

fn to_gd(&self) -> Gd<Self>

Returns the Gd pointer containing this object.

This is intended to be stored or passed to engine methods. You cannot call bind() or bind_mut() on it, while the method calling to_gd() is still running; that would lead to a double borrow panic.

Source

fn base_field(&self) -> &Base<Self::Base>

Returns a reference to the Base stored by this object.

Provided Methods§

Source

fn base(&self) -> BaseRef<'_, Self>

Returns a shared reference suitable for calling engine methods on this object.

Holding a shared guard prevents other code paths from obtaining a mutable reference to self, as such it is recommended to drop the guard as soon as you no longer need it.

§Examples
use godot::prelude::*;

#[derive(GodotClass)]
#[class(init, base = Node)]
struct MyClass {
    base: Base<Node>,
}

#[godot_api]
impl INode for MyClass {
    fn process(&mut self, _delta: f32) {
        let name = self.base().get_name();
        godot_print!("name is {name}");
    }
}

However, we cannot call methods that require &mut Base, such as Node::add_child().

use godot::prelude::*;

#[derive(GodotClass)]
#[class(init, base = Node)]
struct MyClass {
    ///     base: Base<Node>,
}

#[godot_api]
impl INode for MyClass {
    fn process(&mut self, _delta: f32) {
        let node = Node::new_alloc();
        // fails because `add_child` requires a mutable reference.
        self.base().add_child(&node);
    }
}

For this, use base_mut() instead.

Source

fn base_mut(&mut self) -> BaseMut<'_, Self>

Returns a mutable reference suitable for calling engine methods on this object.

This method will allow you to call back into the same object from Godot, unlike what would happen if you used to_gd(). You have to keep the BaseRef guard bound for the entire duration the engine might re-enter a function of your class. The guard temporarily absorbs the &mut self reference, which allows for an additional mutable reference to be acquired.

Holding a mutable guard prevents other code paths from obtaining any reference to self, as such it is recommended to drop the guard as soon as you no longer need it.

§Examples
use godot::prelude::*;

#[derive(GodotClass)]
#[class(init, base = Node)]
struct MyClass {
    base: Base<Node>,
}

#[godot_api]
impl INode for MyClass {
    fn process(&mut self, _delta: f32) {
        let node = Node::new_alloc();
        self.base_mut().add_child(&node);
    }
}

We can call back into self through Godot:

use godot::prelude::*;

#[derive(GodotClass)]
#[class(init, base = Node)]
struct MyClass {
    base: Base<Node>,
}

#[godot_api]
impl INode for MyClass {
    fn process(&mut self, _delta: f32) {
        self.base_mut().call("other_method", &[]);
    }
}

#[godot_api]
impl MyClass {
    #[func]
    fn other_method(&mut self) {}
}

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementors§