Description
When initializing an object in Godot, it is a fairly common pattern in c++ to do most of the setup in the init
function. But as of #497 and #501, it is now impossible to directly use the Base
object to do anything (at least without using #[doc(hidden)]
functions). That means that in order to call any methods on base to set up the class, you'd need to first create the Self
object and then use a method like WithBaseField::to_gd
, like this:
fn init(base: Base<Self::Base>) -> Self {
let self_ = Self { .., base };
self_.to_gd().some_method();
}
However this means that every field in Self
has some sensible default, that doesn't require any calls to the base object. It would be nice to provide an official solution for this pattern.
This was initially discussed in this discord thread https://discord.com/channels/723850269347283004/1193536016968073236, i will summarize the solutions we discussed here.
Possible Solutions
- Make
Base
'sto_gd
method public. This method is currently#[doc(hidden)]
, but using it solves the issue. However the reason it is hidden is because it may cause confusion in most other functions, where it may be unclear if people should useself.base.to_gd()
orself.to_gd()
or evenself.base_mut()
. As well as what the difference is. So if we do this we should likely rename it to make it more clear. - Have a "transport base" and a "stored base". Here we would add a new type (the transport base) that can be used to call methods on base, and it is what is passed to
init
. Whereas the stored base is what we currently have and is what is stored in the struct. This would however require us adding a new type that is only used in this one situation. - Pass in a
Gd
of base to the init function. This might however be confusing as both theBase
andGd
point to the same thing, and people might be tempted to store the wrong object in the struct. - Add a post-init function (possibly replacing the original init function). This does make it easy to do initialization using the base object, however it doesn't solve the issue that every field needs a sensible default.
I am currently inclined to go with the first option, to make to_gd
public. It seems the simplest to me and giving it a new name with good documentation would hopefully solve the confusion issue.