Make extension instances create the corresponding godot object in their constructor #663
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This requires godotengine/godot#55470 to work.
First, the Godot object creation is the first step executed when creating an extension instance. This is done by making the default constructor call the parent one in the initialization list. The topmost Wrapped constructor thus call the Godot object creation as soon as possible (using
classdb_construct_object
).As we want to keep the possibility to create a default Constructor in a custom class (those using the
GDCLASS
macro), I could not pass the finalp_godot_class
parameter to theWrapped(const char *p_godot_class)
constructor with the actual class name. Instead, the name of the first class built-in to Godot is passed. This is thus enough to construct the Godot object, but not to finalize the initialization correctly.As a consequence, i used the same trick as we have in Godot, by modifying the
memnew
macro so that it sets the object instance after the object is created. Thememnew
calls a_postinitialize
function, that registers the instance to the object usinggodot::internal::gdn_interface->object_set_instance(_owner, _get_class(), this);
. There, the_get_class
function is available, which allow finally setting up the object correctly.Note: this cannot be done in the Wrapped constructor as, at that point, the virtual functions are not initialized yet. So calling _get_class() in the Wrapped constructor would not compile.
Finally, to avoid users creating object without using
memnew
, I madeoperator=
private. The same trick is used in godot so that should not be a problem.