diff --git a/src/intro/hello-world.md b/src/intro/hello-world.md index 545ff55..96dda1c 100644 --- a/src/intro/hello-world.md +++ b/src/intro/hello-world.md @@ -250,7 +250,6 @@ struct Player { speed: f64, angular_speed: f64, - #[base] base: Base } ``` @@ -268,12 +267,11 @@ Let's break this down. 4. We define two fields `speed` and `angular_speed` for the logic. These are regular Rust fields, no magic involved. More about their use later. -5. The `#[base]` attribute declares the `base` field, which allows `self` to access the base instance (via composition, as Rust does not have +5. The `Base` type is used for the `base` field, which allows `self` to access the base instance (via composition, as Rust does not have native inheritance). This enables two methods that can be accessed as `self.base()` and `self.base_mut()` on your type (through an extension trait). - - The field must have type `Base`. - - `T` must match the declared base class. For example, `#[class(base=Sprite2D)]` implies `Base`. + - `T` must match the declared base class. For example, `#[class(base=Sprite2D)]` implies `Base`. - The name can be freely chosen, but `base` is a common convention. - You do not _have to_ declare this field. If it is absent, you cannot access the base object from within `self`. This is often not a problem, e.g. in data bundles inheriting `RefCounted`. @@ -345,7 +343,7 @@ impl ISprite2D for Player { ``` GDScript uses property syntax here; Rust requires explicit method calls instead. Also, access to base class methods -- such as `rotate()` -in this example -- is done via the `#[base]` field. +in this example -- is done via `base()` and `base_mut()` methods. ```admonish warning title="Direct field access" Do not use the `self.base` field directly. Use `self.base()` or `self.base_mut()` instead, otherwise you won't be able to access and call diff --git a/src/intro/objects.md b/src/intro/objects.md index 96a319c..469feae 100644 --- a/src/intro/objects.md +++ b/src/intro/objects.md @@ -111,7 +111,7 @@ constructor list. fully-constructed `Player` instance. ``` -If your `T` contains a `#[base]` field, you cannot create a standalone `T` object -- you must encapsulate it in `Gd`. +If your `T` contains a `Base` field, you cannot create a standalone `T` object -- you must encapsulate it in `Gd`. You can also not extract a `T` from a `Gd` smart pointer anymore; since it has potentially been shared with the Godot engine, this would not be a safe operation. diff --git a/src/recipes/custom-resources.md b/src/recipes/custom-resources.md index f3d27a5..6e08be0 100644 --- a/src/recipes/custom-resources.md +++ b/src/recipes/custom-resources.md @@ -19,7 +19,6 @@ This workflow is similar to the [Hello World example][hello]: #[derive(GodotClass)] #[class(tool, init, base=Resource)] struct ResourceType { - #[base] base: Base, } ``` diff --git a/src/recipes/editor-plugin.md b/src/recipes/editor-plugin.md index 6c72944..0fcc280 100644 --- a/src/recipes/editor-plugin.md +++ b/src/recipes/editor-plugin.md @@ -24,7 +24,6 @@ you cannot introduce compile-time errors. #[derive(GodotClass)] #[class(tool, init, editor_plugin, base=EditorPlugin)] struct MyEditorPlugin { - #[base] base: Base, } diff --git a/src/recipes/engine-singleton.md b/src/recipes/engine-singleton.md index a6ebf1f..2f0824c 100644 --- a/src/recipes/engine-singleton.md +++ b/src/recipes/engine-singleton.md @@ -47,7 +47,6 @@ Defining a singleton is the same as registering a custom class. #[derive(GodotClass)] #[class(tool, init, base=Object)] struct MyEditorSingleton { - #[base] base: Base, } diff --git a/src/register/classes.md b/src/register/classes.md index df970f7..561d9b5 100644 --- a/src/register/classes.md +++ b/src/register/classes.md @@ -88,19 +88,15 @@ store the instance of the Godot superclass (base class) as a field in our `Monst struct Monster { name: String, hitpoints: i32, - - #[base] base: Base, } ``` -The `#[base]` attribute is currently necessary (as of January 2024), but will likely disappear in the future. - The important part is the `Base` type. `T` must match the base class you specified in the `#[class(base=...)]` attribute. You can also use the associated type `Self::Base` for `T`. -When you declare a base field in your struct, you can access the `Node` API through provided methods `self.base()` and `self.base_mut()`, but -more on this later. +When you declare a base field in your struct, the `#[derive]` procedural macro will automatically detect the `Base` type.[^inference] +This lets you access the `Node` API through provided methods `self.base()` and `self.base_mut()`, but more on this later. ## Default constructor @@ -121,8 +117,6 @@ You can use `#[class(init)]` to generate a constructor for you. This is limited struct Monster { name: String, hitpoints: i32, - - #[base] base: Base, } ``` @@ -157,8 +151,6 @@ We can provide a manually-defined constructor by overriding the trait's associat struct Monster { name: String, hitpoints: i32, - - #[base] base: Base, } @@ -190,6 +182,14 @@ More on this topic in the next chapter. You learned how to define a Rust class and register it with Godot. You now know how to select a base class and how to define a constructor. The next chapter will allow you to implement logic by providing functions. +
+ +--- + +[^inference] You can tweak the type detection using the `#[hint]` attribute, see [the corresponding docs][api-derive-godotclass-inference]. + + [api-derive-godotclass]: https://godot-rust.github.io/docs/gdext/master/godot/register/derive.GodotClass.html +[api-derive-godotclass-inference]: https://godot-rust.github.io/docs/gdext/master/godot/register/derive.GodotClass.html#fine-grained-inference-hints [api-godot-api]: https://godot-rust.github.io/docs/gdext/master/godot/register/attr.godot_api.html [godot-gdscript-classes]: https://docs.godotengine.org/en/stable/tutorials/scripting/gdscript/gdscript_basics.html#classes diff --git a/src/register/functions.md b/src/register/functions.md index a617183..1abc4bc 100644 --- a/src/register/functions.md +++ b/src/register/functions.md @@ -67,8 +67,6 @@ So let's implement `to_string()`, here again showing the class definition for qu struct Monster { name: String, hitpoints: i32, - - #[base] base: Base, }