@@ -444,8 +444,6 @@ pub fn derive_godot_class(input: TokenStream) -> TokenStream {
444
444
445
445
/// Proc-macro attribute to be used with `impl` blocks of [`#[derive(GodotClass)]`][GodotClass] structs.
446
446
///
447
- /// See also [book chapter _Registering functions_](https://godot-rust.github.io/book/register/functions.html) and following.
448
- ///
449
447
/// Can be used in two ways:
450
448
/// ```no_run
451
449
/// # use godot::prelude::*;
@@ -462,57 +460,77 @@ pub fn derive_godot_class(input: TokenStream) -> TokenStream {
462
460
/// impl INode for MyClass { /* ... */ }
463
461
/// ```
464
462
///
465
- /// The second case works by implementing the corresponding trait `I<Base> ` for the base class of your class
463
+ /// The second case works by implementing the corresponding trait `I* ` for the base class of your class
466
464
/// (for example `IRefCounted` or `INode3D`). Then, you can add functionality such as:
467
465
/// * `init` constructors
468
466
/// * lifecycle methods like `ready` or `process`
469
467
/// * `on_notification` method
470
468
/// * `to_string` method
471
469
///
472
- /// Neither `#[godot_api]` attribute is required. For small data bundles inheriting `RefCounted`, you may be fine with
470
+ /// Neither of the two `#[godot_api]` blocks is required. For small data bundles inheriting `RefCounted`, you may be fine with
473
471
/// accessing properties directly from GDScript.
474
472
///
475
- /// # Examples
473
+ /// See also [book chapter _Registering functions_](https://godot-rust.github.io/book/register/functions.html) and following.
476
474
///
477
- /// ## `RefCounted` as a base, overridden `init`
475
+ /// **Table of contents**
476
+ /// - [Constructors](#constructors)
477
+ /// - [User-defined `init`](#user-defined-init)
478
+ /// - [Generated `init`](#generated-init)
479
+ /// - [Lifecycle functions](#lifecycle-functions)
480
+ /// - [User-defined functions](#user-defined-functions)
481
+ /// - [Associated functions and methods](#associated-functions-and-methods)
482
+ /// - [Virtual methods](#virtual-methods)
483
+ /// - [Constants and signals](#signals)
478
484
///
479
- /// ```no_run
480
- ///# use godot::prelude::*;
485
+ /// # Constructors
486
+ ///
487
+ /// Note that `init` (the Godot default constructor) can be either provided by overriding it, or generated with a `#[class(init)]` attribute
488
+ /// on the struct. Classes without `init` cannot be instantiated from GDScript.
481
489
///
490
+ /// ## User-defined `init`
491
+ ///
492
+ /// ```no_run
493
+ /// # use godot::prelude::*;
482
494
/// #[derive(GodotClass)]
483
495
/// // no #[class(init)] here, since init() is overridden below.
484
496
/// // #[class(base=RefCounted)] is implied if no base is specified.
485
497
/// struct MyStruct;
486
498
///
487
499
/// #[godot_api]
488
- /// impl MyStruct {
489
- /// #[func]
490
- /// pub fn hello_world(&mut self) {
491
- /// godot_print!("Hello World!")
492
- /// }
493
- /// }
494
- ///
495
- /// #[godot_api]
496
500
/// impl IRefCounted for MyStruct {
497
501
/// fn init(_base: Base<RefCounted>) -> Self {
498
502
/// MyStruct
499
503
/// }
500
504
/// }
501
505
/// ```
502
506
///
503
- /// Note that `init` can be either provided by overriding it, or generated with a `#[class(init)]` attribute on the struct.
504
- /// Classes without `init` cannot be instantiated from GDScript.
507
+ /// ## Generated `init`
505
508
///
506
- /// ## `Node` as a base, generated ` init`
509
+ /// This initializes the `Base<T>` field, and every other field with either `Default::default()` or the value specified in `#[ init(default = ...)]`.
507
510
///
508
511
/// ```no_run
509
- ///# use godot::prelude::*;
510
- ///
512
+ /// # use godot::prelude::*;
511
513
/// #[derive(GodotClass)]
512
514
/// #[class(init, base=Node)]
513
515
/// pub struct MyNode {
514
516
/// base: Base<Node>,
517
+ ///
518
+ /// #[init(default = 42)]
519
+ /// some_integer: i64,
515
520
/// }
521
+ /// ```
522
+ ///
523
+ ///
524
+ /// # Lifecycle functions
525
+ ///
526
+ /// You can override the lifecycle functions `ready`, `process`, `physics_process` and so on, by implementing the trait corresponding to the
527
+ /// base class.
528
+ ///
529
+ /// ```no_run
530
+ /// # use godot::prelude::*;
531
+ /// #[derive(GodotClass)]
532
+ /// #[class(init, base=Node)]
533
+ /// pub struct MyNode;
516
534
///
517
535
/// #[godot_api]
518
536
/// impl INode for MyNode {
@@ -521,6 +539,93 @@ pub fn derive_godot_class(input: TokenStream) -> TokenStream {
521
539
/// }
522
540
/// }
523
541
/// ```
542
+ ///
543
+ ///
544
+ /// # User-defined functions
545
+ ///
546
+ /// You can use the `#[func]` attribute to declare your own functions. These are exposed to Godot and callable from GDScript.
547
+ ///
548
+ /// ## Associated functions and methods
549
+ ///
550
+ /// If `#[func]` functions are called from the engine, they implicitly bind the surrounding `Gd<T>` pointer: `Gd::bind()` in case of `&self`,
551
+ /// `Gd::bind_mut()` in case of `&mut self`. To avoid that, use `#[func(gd_self)]`, which requires an explicit first argument of type `Gd<T>`.
552
+ ///
553
+ /// Functions without a receiver become static functions in Godot. They can be called from GDScript using `MyStruct.static_function()`.
554
+ /// If they return `Gd<Self>`, they are effectively constructors that allow taking arguments.
555
+ ///
556
+ /// ```no_run
557
+ /// # use godot::prelude::*;
558
+ /// #[derive(GodotClass)]
559
+ /// #[class(init)]
560
+ /// struct MyStruct {
561
+ /// field: i64,
562
+ /// base: Base<RefCounted>,
563
+ /// }
564
+ ///
565
+ /// #[godot_api]
566
+ /// impl MyStruct {
567
+ /// #[func]
568
+ /// pub fn hello_world(&mut self) {
569
+ /// godot_print!("Hello World!")
570
+ /// }
571
+ ///
572
+ /// #[func]
573
+ /// pub fn static_function(constructor_arg: i64) -> Gd<Self> {
574
+ /// Gd::from_init_fn(|base| {
575
+ /// MyStruct { field: constructor_arg, base }
576
+ /// })
577
+ /// }
578
+ ///
579
+ /// #[func(gd_self)]
580
+ /// pub fn explicit_receiver(mut this: Gd<Self>, other_arg: bool) {
581
+ /// // Only bind Gd pointer if needed.
582
+ /// if other_arg {
583
+ /// this.bind_mut().field = 55;
584
+ /// }
585
+ /// }
586
+ /// }
587
+ /// ```
588
+ ///
589
+ /// ## Virtual methods
590
+ ///
591
+ /// Functions with the `#[func(virtual)]` attribute are virtual functions, meaning attached scripts can override them.
592
+ ///
593
+ /// ```no_run
594
+ /// # #[cfg(since_api = "4.3")]
595
+ /// # mod conditional {
596
+ /// # use godot::prelude::*;
597
+ /// #[derive(GodotClass)]
598
+ /// #[class(init)]
599
+ /// struct MyStruct {
600
+ /// // Virtual functions require base object.
601
+ /// base: Base<RefCounted>,
602
+ /// }
603
+ ///
604
+ /// #[godot_api]
605
+ /// impl MyStruct {
606
+ /// #[func(virtual)]
607
+ /// fn language(&self) -> GString {
608
+ /// "Rust".into()
609
+ /// }
610
+ /// }
611
+ /// # }
612
+ /// ```
613
+ ///
614
+ /// In GDScript:
615
+ /// ```gdscript
616
+ /// extends MyStruct
617
+ ///
618
+ /// func language():
619
+ /// return "GDScript"
620
+ /// ```
621
+ ///
622
+ /// Now, `obj.language()` from Rust will dynamically dispatch the call.
623
+ ///
624
+ /// Make sure you understand the limitations in the [tutorial](https://godot-rust.github.io/book/register/virtual-functions.html).
625
+ ///
626
+ /// # Constants and signals
627
+ ///
628
+ /// Please refer to [the book](https://godot-rust.github.io/book/register/constants.html).
524
629
#[ proc_macro_attribute]
525
630
pub fn godot_api ( _meta : TokenStream , input : TokenStream ) -> TokenStream {
526
631
translate ( input, class:: attribute_godot_api)
0 commit comments