Trait WithBaseField
pub trait WithBaseField: GodotClass<Declarer = DeclUser> + Bounds {
// Required method
fn to_gd(&self) -> Gd<Self>;
// 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§
fn to_gd(&self) -> Gd<Self>
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.
§Panics
If called during initialization (the init()
function or Gd::from_init_fn()
). Use Base::to_init_gd()
instead.
Provided Methods§
fn base(&self) -> BaseRef<'_, Self>
fn base(&self) -> BaseRef<'_, Self>
Returns a shared reference guard, suitable for calling &self
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.
fn base_mut(&mut self) -> BaseMut<'_, Self>
fn base_mut(&mut self) -> BaseMut<'_, Self>
Returns an exclusive reference guard, suitable for calling &self
/&mut self
engine methods on this object.
This method will allow you to call back into the same object from Godot – something that to_gd()
does not allow.
You have to keep the BaseMut
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 exclusive (mutable) reference to be acquired.
Holding an exclusive 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
#[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:
#[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) {}
}
Rust’s borrow checking rules are enforced if you try to overlap base_mut()
calls:
// error[E0499]: cannot borrow `*self` as mutable more than once at a time
fn method(&mut self) {
let mut a = self.base_mut();
// ---- first mutable borrow occurs here
let mut b = self.base_mut();
// ^^^^ second mutable borrow occurs here
}
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.