Skip to content

Commit a73c7ed

Browse files
committed
Update documentation for macros
1 parent e674857 commit a73c7ed

File tree

1 file changed

+67
-17
lines changed

1 file changed

+67
-17
lines changed

gdnative-derive/src/lib.rs

Lines changed: 67 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,44 @@ mod utils;
1717
mod varargs;
1818
mod variant;
1919

20-
/// Collects method signatures of all functions in a `NativeClass` that have the `#[method]` attribute and registers them with Godot.
20+
/// Collects method signatures of all functions in a `NativeClass` that have the `#[method]`
21+
/// attribute and registers them with Godot.
2122
///
22-
/// **Important**: Only one `impl` block per struct may be attributed with `#[methods]`.
23+
/// The `#[methods]` attribute can be used with both `impl Type` and `impl Trait for Type`
24+
/// blocks. The semantics change depending on whether a mix-in name is provided for the block.
2325
///
24-
/// For more context, please refer to [gdnative::derive::NativeClass](NativeClass).
26+
/// ## Universal `impl` blocks: `#[methods]`
27+
///
28+
/// An `impl` block that doesn't have a `mixin` parameter is universal. Universal `#[methods]`
29+
/// blocks **must not overlap**. Usually, this means that **only one** `impl` block per struct
30+
/// may be universal.
31+
///
32+
/// When applied to a generic `impl`, the `impl` block must apply to **all** monomorphizations
33+
/// of the type, i.e. be *universal*.
34+
///
35+
/// One applicable universal block must be present for each type one wishes to use as a
36+
/// `NativeClass`. Universal blocks are always registered automatically.
37+
///
38+
/// ## Mix-ins: `#[methods(mixin = "Name")]`
39+
///
40+
/// When given a name with the `mixin` argument, a block behaves instead as a mix-in block.
41+
/// `#[method(mixin = "Name")]` creates an opaque type called `Name` under the current scope,
42+
/// that can be manually registered to any type the `impl` block covers. This can be done in
43+
/// a `register_with` callback with `builder.mixin::<MyMixin>()`.
44+
///
45+
/// Unlike universal blocks, mix-in blocks have a **many-to-many** relationship with the types
46+
/// they are registered to. Any number of mix-ins can be applied to any number of compatible
47+
/// types. This can be useful for reusing generics `impl`s, or organizing code for big interfaces.
48+
///
49+
/// Additionally, the attribute accepts the following arguments:
50+
///
51+
/// - `#[methods(pub)]`<br>
52+
/// Mix-in types are private by default. The `pub` argument makes them public instead.
2553
///
2654
/// ## Example
2755
///
56+
/// ### Universal
57+
///
2858
/// ```
2959
/// use gdnative::prelude::*;
3060
///
@@ -42,6 +72,30 @@ mod variant;
4272
/// }
4373
///
4474
/// ```
75+
///
76+
/// ### Mix-in
77+
///
78+
/// ```
79+
/// use gdnative::prelude::*;
80+
///
81+
/// #[derive(NativeClass)]
82+
/// #[inherit(Reference)]
83+
/// #[register_with(register_foo)]
84+
/// #[no_constructor]
85+
/// struct Foo {}
86+
///
87+
/// fn register_foo(builder: &ClassBuilder<Foo>) {
88+
/// builder.mixin::<FooMixin>();
89+
/// }
90+
///
91+
/// #[methods(mixin = "FooMixin")]
92+
/// impl Foo {
93+
/// #[method]
94+
/// fn foo(&self, #[base] _base: &Reference, bar: i64) -> i64 {
95+
/// bar
96+
/// }
97+
/// }
98+
/// ```
4599
#[proc_macro_attribute]
46100
pub fn methods(meta: TokenStream, input: TokenStream) -> TokenStream {
47101
let args =
@@ -217,7 +271,9 @@ pub fn profiled(meta: TokenStream, input: TokenStream) -> TokenStream {
217271
/// ### `#[methods]`
218272
/// Adds the necessary information to a an `impl` block to register the properties and methods with Godot.
219273
///
220-
/// **Important**: This needs to be added to one and only one `impl` block for a given `NativeClass`.
274+
/// One and only one universal `impl` block must be available for each `NativeClass`
275+
/// monomorphization, along with any number of additional mix-ins. See [`methods`](attr.methods.html)
276+
/// for more information.
221277
///
222278
/// ### `#[method]`
223279
/// Registers the attributed function signature to be used by Godot.
@@ -468,22 +524,16 @@ pub fn derive_native_class(input: TokenStream) -> TokenStream {
468524
///
469525
/// For more context, please refer to [gdnative::derive::NativeClass](NativeClass).
470526
///
471-
/// # Examples
527+
/// ## Type attributes
472528
///
473-
/// ```ignore
474-
/// #[derive(NativeClass)]
475-
/// struct Pair<T> {
476-
/// a: T,
477-
/// b: T,
478-
/// }
529+
/// The behavior of the attribute can be customized using additional attributes on the type
530+
/// alias. All type attributes are optional.
479531
///
480-
/// #[gdnative::derive::monomorphize]
481-
/// type IntPair = Pair<i32>;
532+
/// ### `#[register_with(path::to::function)]`
482533
///
483-
/// fn init(handle: InitHandle) {
484-
/// handle.add_class::<IntPair>();
485-
/// }
486-
/// ```
534+
/// Use a custom function to register signals, properties or methods, in addition
535+
/// to the one generated by a universal `#[methods]` block on the generic type.
536+
/// This can be used to register extra mix-ins that apply to the specific monomorphization.
487537
#[proc_macro_attribute]
488538
pub fn monomorphize(meta: TokenStream, input: TokenStream) -> TokenStream {
489539
let args = parse_macro_input!(meta as AttributeArgs);

0 commit comments

Comments
 (0)