Open 0x53A opened 4 days ago
#[godot_api]
annotated impl
blocks are very different from regular Rust impl
blocks. They define several extra traits and register all contained symbols. You can check the generated code with cargo expand
to get an idea :slightly_smiling_face:
Supporting multiple impl
blocks is probably quite hard to implement with the current trait-based approach, and has the potential to make global registration more complex. The benefit however is "only" cosmetic (code organization) -- while important, I'm not sure if it stands in a good balance with implementation and maintenance effort.
Are you interested in investigating the feasibility? We could of course give you some guidance in the code.
The benefit however is "only" cosmetic (code organization) -- while important, I'm not sure if it stands in a good balance with implementation and maintenance effort.
I'd like to add one practical use case which comes to mind - I think it makes significantly easier to add stuff to multiple Godot classes with declarative macros, as it makes possible to keep the main #[godot_api]
block, and then add macro_rules!
which will be able to expand independently into #[godot_api(secondary)]
blocks. The biggest advantage would be if there's no limit for the amount of #[godot_api(secondary)
blocks and no requirement to enumerate them.
This can help to simplify project-specific declarative macros which add traits to Godot classes and automatically expose trait methods to the engine, and apply such macros selectively. This case might be covered by builder API in future, though.
At the moment only one
#[godot_api]
impl block is allowed (and second one to implement the base class interface).The error message with multiple blocks is
Of course, the workaround is trivial, just put everything into one block, so this isn't important, but it would be really nice to have.
For code organization, I have been experimenting with a pattern where I define and implement a relative fine-grained trait in a node then create a godot function to wrap that trait.
Example what I'd like to do:
I don't yet know if this system of code organization makes sense, but that's beside the point.
My arguments why I would like to have multiple
#[godot_api]
blocks:1) I'd like to have the matching godot function right next to the trait implementation, instead of multiple pages below it, disjointed 2) Later I'd like to generate some of this wrapping code by macro, which would also be much easier if it could be split into different blocks 3) having multiple blocks would also allow to split the Node implementation into multiple files, if one were inclined to do so. (Personally I tend to prefer fewer larger files over many smaller ones, but taste differs)