Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow ClassDB to create a Object without postinitialization for GDExtension. #91018

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

Daylily-Zeleen
Copy link
Contributor

@Daylily-Zeleen Daylily-Zeleen commented Apr 22, 2024

Currently, the flow of creating GDExtension object like this:

  1. Start instantiate a GDExtension object by ObjectGDExtension::create_instance in ClassDB.
  2. In the constructor of GDExtension object base class, Wrapped, will create its _owner godot object by ClassInfo::creation_func.
  3. In ClassInfo::creation_func, the owner godot object will notify NOTIFICATION_POSTINITIALIZE by Node::_postinitialize in the memnew in godot.
  4. After construction of GDExtension object is completed, it will notify NOTIFICATION_POSTINITIALIZE by Wrapped::_postinitialize in the memnew in GDExtension .

This will bring two issues:

  1. The GDExtension object owner already be postinitialized before it is constructed. It means that a GDExtension Node can't add an internal Node in its constructor like in godot, because it owner's flag data.in_constructor already be cleared.
  2. The postinitialization of GDExtension object owner will be do twice, because notify NOTIFICATION_POSTINITIALIZE in GDExtension is through its owner.

This pr do these things:

  1. Seperate Object's initialization and postinitialization.
  2. Allow ClassDB create a Object without postinitialization to be a GDExtension object owner, it will be postinitialized after constructing the GDExtension object completly.
  3. Modify GodotSharp to fit above changes.

Fixes #91023

@Daylily-Zeleen
Copy link
Contributor Author

@AThousandShips I think this pr should be add a bug label.

  1. The GDExtension object owner already be postinitialized before it is constructed. It means that a GDExtension Node can't add an internal Node in its constructor like in godot, because it owner's flag data.in_constructor already be cleared.

Due to this reason, the edior will crash when we copying a gdextenion Node if it have a internal node (be add in constructor but not be marked as internal).

@AThousandShips
Copy link
Member

AThousandShips commented Apr 22, 2024

How could the node be created in the constructor and not be marked as internal? It won't be created if duplicated in this case, that would be the bug instead, this shouldn't be needed

Or rather they aren't internal if they're created that way

But in either way this would be an improvement, as the user should consider this limitation instead id say, the same goes for scripts

@Daylily-Zeleen
Copy link
Contributor Author

Daylily-Zeleen commented Apr 22, 2024

How could the node be created in the constructor and not be marked as internal? It won't be created if duplicated in this case, that would be the bug instead, this shouldn't be needed

I mean that the GDExtension node(A) have a node(B) which be added in A's constructor, the B should be an internal node. But currently, the B is not mark as an internal node, because when A adding B, the flag data.in_constructor of A's owner node already be cleared.

So if we copy A in editor, the B would not be skiped correctly and lead crash.

@AThousandShips
Copy link
Member

AThousandShips commented Apr 22, 2024

That should be handled by the extension IMO, just like it would have to be if you do it in GDScript, in my opinion that's a limitation, a missing feature, not a bug, especially as changing this breaks code that does handle that, so would need to be adjusted for

Edit: Also this would be unnecessary for that part if this gets merged:

Edit: I'll mark it as a bug but will keep it for 4.x for the time being to discuss the practical sides of the changes and how they affect existing code

@AThousandShips

This comment was marked as outdated.

@Daylily-Zeleen
Copy link
Contributor Author

Daylily-Zeleen commented Apr 23, 2024

I rename instantiate_extension_owner to instantiate_without_postinitialization, it seems that GDScript class have the same problem, may be we can use this new method to handle and sent NOTIFICATION_POSTINITIALIZE after _init() in GDScript (may be used in C#, too).

I think this can keep the consistency between multiple programming languages, and at least can help to solves the problem of editor crash caused by the duplication of custom nodes which running in the editor (a GDExtension node or GDScrip node with @tool flag) when they have internal nodes (GDExtension(c++ binding) node can be solved, GDScript node need more efforts).

@AThousandShips
Copy link
Member

I think the other option, being less invasive, might be safer, and the extension team would be best suited to decide what milestone to direct this to, depending on the impact of the changes to initialization

While crashes should be avoided the exact solution and cause and safe use should be discussed, to provide the best solution

@Daylily-Zeleen Daylily-Zeleen force-pushed the daylily-zeleen/optionally_postinitialization_for_extension_owner branch 2 times, most recently from 42a0011 to 204f87a Compare April 24, 2024 11:10
core/object/class_db.h Outdated Show resolved Hide resolved
core/object/class_db.h Outdated Show resolved Hide resolved
core/object/class_db.cpp Outdated Show resolved Hide resolved
core/extension/gdextension_interface.h Outdated Show resolved Hide resolved
@Daylily-Zeleen Daylily-Zeleen force-pushed the daylily-zeleen/optionally_postinitialization_for_extension_owner branch from 204f87a to 43185f9 Compare April 24, 2024 13:09
@Daylily-Zeleen Daylily-Zeleen force-pushed the daylily-zeleen/optionally_postinitialization_for_extension_owner branch 3 times, most recently from 7a99a0e to 48aa6c8 Compare May 4, 2024 18:54
@Daylily-Zeleen
Copy link
Contributor Author

Daylily-Zeleen commented May 4, 2024

Accroding to @dsnopek's comment, I add GDExtensionClassCreationInfo4 and GDExtensionClassCreateInstance2.

If we can merge this pr in 4.3, I think we should merge GDExtensionClassCreationInfo4 into GDExtensionClassCreationInfo3.

I would try to implement similar feature for #91019 later.

Copy link
Contributor

@dsnopek dsnopek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your continued work on this!

If we can merge this pr in 4.3, I think we should merge GDExtensionClassCreationInfo4 into GDExtensionClassCreationInfo3.

I think we should save this for 4.4 - Godot 4.3 is basically in feature freeze at this point (with a couple of specific possible exceptions, but this PR isn't among them).

I would try to implement similar feature for #91019 later.

At this point, I think I personally favor the approach in this PR over the other one. It would be nice to get some feedback from other GDExtension team members, though.

core/object/class_db.cpp Outdated Show resolved Hide resolved
core/object/class_db.h Outdated Show resolved Hide resolved
core/object/object.cpp Outdated Show resolved Hide resolved
core/extension/gdextension_interface.h Outdated Show resolved Hide resolved
core/extension/gdextension_interface.h Outdated Show resolved Hide resolved
core/extension/gdextension_interface.h Outdated Show resolved Hide resolved
core/extension/gdextension_interface.h Outdated Show resolved Hide resolved
@dsnopek dsnopek removed this from the 4.x milestone May 16, 2024
@dsnopek dsnopek added this to the 4.4 milestone May 16, 2024
@Daylily-Zeleen Daylily-Zeleen force-pushed the daylily-zeleen/optionally_postinitialization_for_extension_owner branch 2 times, most recently from f03388f to fca783c Compare May 18, 2024 15:24
@dsnopek dsnopek removed the bug label May 18, 2024
Copy link
Contributor

@dsnopek dsnopek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! This is looking great to me now :-)

However, we should wait until the Godot 4.4 development cycle starts to merge this.

@dsnopek dsnopek requested a review from raulsntos May 18, 2024 16:19
@Daylily-Zeleen Daylily-Zeleen force-pushed the daylily-zeleen/optionally_postinitialization_for_extension_owner branch from fca783c to c780be2 Compare May 18, 2024 17:21
Copy link
Member

@raulsntos raulsntos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes to GodotSharp look good to me.

Does this need a follow-up in godot-cpp? As I understand it, this is an alternative to godotengine/godot-cpp#1447 so should that be reverted after merging this one? Or, to put it another way, what should GDExtension language bindings do regarding the POSTINITIALIZED notification after this PR is merged?

core/object/class_db.h Outdated Show resolved Hide resolved
@dsnopek
Copy link
Contributor

dsnopek commented May 20, 2024

Does this need a follow-up in godot-cpp? As I understand it, this is an alternative to godotengine/godot-cpp#1447 so should that be reverted after merging this one? Or, to put it another way, what should GDExtension language bindings do regarding the POSTINITIALIZED notification after this PR is merged?

Yep! Once a GDExtension binding switches to using classdb_construct_object2(), it'll be required to send NOTIFICATION_POSTINITAILIZE to the object after it's been constructed. We'll need to update godot-cpp to do this (which will include effectively reverting godotengine/godot-cpp#1447), but that'll only be for Godot 4.4+. Existing GDExtensions built for Godot <=4.3 which use classdb_construct_object() (without the 2) will continue working as they have

@Daylily-Zeleen Daylily-Zeleen force-pushed the daylily-zeleen/optionally_postinitialization_for_extension_owner branch from c780be2 to 0c42997 Compare May 20, 2024 14:35
@Daylily-Zeleen Daylily-Zeleen requested a review from a team as a code owner May 20, 2024 14:35
@Daylily-Zeleen Daylily-Zeleen force-pushed the daylily-zeleen/optionally_postinitialization_for_extension_owner branch from 0c42997 to 3cbd25f Compare May 20, 2024 14:42
@Daylily-Zeleen Daylily-Zeleen requested a review from a team as a code owner May 20, 2024 14:42
@Daylily-Zeleen Daylily-Zeleen force-pushed the daylily-zeleen/optionally_postinitialization_for_extension_owner branch from 3cbd25f to 4c220d6 Compare May 20, 2024 14:51
@Daylily-Zeleen Daylily-Zeleen requested review from a team as code owners May 20, 2024 14:51
@Daylily-Zeleen Daylily-Zeleen force-pushed the daylily-zeleen/optionally_postinitialization_for_extension_owner branch 3 times, most recently from ac0f302 to 3e28cf2 Compare May 20, 2024 15:31
core/crypto/crypto.h Outdated Show resolved Hide resolved
core/crypto/crypto.cpp Outdated Show resolved Hide resolved
core/object/class_db.h Outdated Show resolved Hide resolved
@Daylily-Zeleen Daylily-Zeleen force-pushed the daylily-zeleen/optionally_postinitialization_for_extension_owner branch from 3e28cf2 to 874a1b1 Compare May 23, 2024 15:19
@Daylily-Zeleen Daylily-Zeleen force-pushed the daylily-zeleen/optionally_postinitialization_for_extension_owner branch from 874a1b1 to bda2f97 Compare May 23, 2024 15:30
Copy link
Contributor

@dsnopek dsnopek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! This is looking really great to me :-)

(Reminder: Please don't merge this until the Godot 4.4 development cycle opens)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants