Skip to content

Support using Base for initialization in init function #557

Open
@lilizoey

Description

@lilizoey

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

  1. Make Base's to_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 use self.base.to_gd() or self.to_gd() or even self.base_mut(). As well as what the difference is. So if we do this we should likely rename it to make it more clear.
  2. 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.
  3. Pass in a Gd of base to the init function. This might however be confusing as both the Base and Gd point to the same thing, and people might be tempted to store the wrong object in the struct.
  4. 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.

Metadata

Metadata

Assignees

Labels

c: registerRegister classes, functions and other symbols to GDScriptfeatureAdds functionality to the library

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions