Skip to content

Conversation

@dsnopek
Copy link
Contributor

@dsnopek dsnopek commented Mar 14, 2025

This adds a GDExtension interface function, that allows a GDExtension to register a callback, that can be called by the Godot editor to determine which classes it's using.

I created this to help @YeldhamDev with the work he's doing to allow recompiling Godot with only the classes used by a particular project.

It worked for me in a quick test!

I'd appreciate feedback on the name of the new function: editor_register_get_used_classes_callback

It ends up with quite a few prefixes and suffixes in there. :-) I put "editor" since the only use I can think of for this is in the editor, but it wouldn't really be a problem to allow this always?

PR godotengine/godot-cpp#1743 implements this for godot-cpp

@dsnopek dsnopek force-pushed the gdextension-get-used-classes branch from 03334ff to f5d8724 Compare March 14, 2025 17:54
@dsnopek dsnopek requested a review from YeldhamDev March 14, 2025 17:56
@Bromeon
Copy link
Contributor

Bromeon commented Mar 14, 2025

This adds a GDExtension interface function, that allows a GDExtension to register a callback, that can be called by the Godot editor to determine which classes it's using.

Could you elaboratate what "used" means here, and maybe also mention in the C API documentation?
Some questions:

  1. When is this called? On startup? On shutdown? Anytime the extension is loaded?
  2. Should the binding dynamically track which classes are accessed? Determining it statically may require some linker tricks which probably work for C++ and maybe Rust, but not for Swift, Kotlin or Go?
  3. You likely mean "Godot classes" (not user-defined ones from GDScript, C# or GDExtension), but it would be good to highlight this.

I looked briefly at the godot-cpp implementation, but I'm not familiar with instance_binding_callbacks or what it exactly represents 🤔


I'd appreciate feedback on the name of the new function: editor_register_get_used_classes_callback

It ends up with quite a few prefixes and suffixes in there. :-) I put "editor" since the only use I can think of for this is in the editor, but it wouldn't really be a problem to allow this always?

Yes, the "editor" part seems a bit off to me, as well 😉 without that, I think the name sounds good!

@YeldhamDev
Copy link
Member

@Bromeon This is going be used for the Compilation Configuration Profile editor to generate build profiles. Those can dictate classes to be disabled, and it scans the project to see what classes are unused.

@dsnopek
Copy link
Contributor Author

dsnopek commented Mar 14, 2025

1. When is this called? On startup? On shutdown? Anytime the extension is loaded?

As needed. But most frequently, not at all :-)

The one use case we have for this right now is in the editor, in "Tools" -> "Engine Compilation Configuration Editor..." when the user clicks "Detect from Project". This would allow that feature to loop over the GDExtensions that are loaded, see which classes are used, and make sure those are enabled on the profile it generates.

2. Should the binding dynamically track which classes are accessed? Determining it statically may require some linker tricks which probably work for C++ and maybe Rust, but not for Swift, Kotlin or Go?

Not dynamically, this would be any class that the GDExtension may use. The idea is that any classes that aren't used by anything can be compiled out of a custom engine build for that specific project. If there's even the possibility that the class may be used, then it should be included on the list of used classes.

In godot-cpp, we do a trick where we try to get the linker to remove any unused classes, but it's not very good and always over-estimates which classes are used. But the developer can also provide a build_profile.json to SCons that will cause only the requested classes to be generated at all. Anyway, via which ever method, it'll return all the classes it knows about, which will be a subset of all available classes.

3. You likely mean "Godot classes" (not user-defined ones from GDScript, C# or GDExtension), but it would be good to highlight this.

I mean classes in ClassDB. So, classes from the engine, but it could also be classes from other GDExtensions (if you generated the extension_api.json with other extensions loaded) because we actually can't tell the difference. :-)

I'll attempt to update the docs in gdextension_interface.h to clarify these points somewhat.

Yes, the "editor" part seems a bit off to me, as well 😉 without that, I think the name sounds good!

Yeah, it would certainly sound better if "editor" was dropped, and it's such a small thing, it wouldn't hurt to have it available always. But only the editor will ever call the callback, and it seems weird not to recognize that somehow. I guess I could just put that in the description rather than the name.

@Bromeon
Copy link
Contributor

Bromeon commented Mar 14, 2025

Yeah, it would certainly sound better if "editor" was dropped, and it's such a small thing, it wouldn't hurt to have it available always. But only the editor will ever call the callback, and it seems weird not to recognize that somehow. I guess I could just put that in the description rather than the name.

Ah, I just saw that the surrounding functions also have the editor_ prefix. Maybe it makes sense to keep for consistency.

Thanks for elaborating the use case!
I'm not familiar with that workflow, is it documented somewhere?

Also, do you have a link for build_profile.json examples? Maybe something similar can make sense for other bindings 👀

@dsnopek
Copy link
Contributor Author

dsnopek commented Mar 14, 2025

I'm not familiar with that workflow, is it documented somewhere?

Not that I know about. It was never fully finished - that's what YelhamDev is working on

Also, do you have a link for build_profile.json examples? Maybe something similar can make sense for other bindings 👀

Here's two examples from real projects:

Copy link
Member

@YeldhamDev YeldhamDev left a comment

Choose a reason for hiding this comment

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

Tested on my end, and everything works. Will add the tie-in code to #103719 once this is merged.

@dsnopek dsnopek force-pushed the gdextension-get-used-classes branch from f5d8724 to 5758ce4 Compare March 17, 2025 13:52
@dsnopek
Copy link
Contributor Author

dsnopek commented Mar 17, 2025

@Bromeon I updated the docs in gdextension_interface.h to hopefully clarify the points you had asked about. Please let me know if it looks OK to you!

@Repiteo Repiteo modified the milestones: 4.x, 4.5 Mar 17, 2025
@Bromeon
Copy link
Contributor

Bromeon commented Mar 17, 2025

Thanks! The following parts are still not in the doc, I think they're important to mention (in condensed form) though?

The one use case we have for this right now is in the editor, in "Tools" -> "Engine Compilation Configuration Editor..." when the user clicks "Detect from Project". This would allow that feature to loop over the GDExtensions that are loaded, see which classes are used, and make sure those are enabled on the profile it generates.

Not dynamically, this would be any class that the GDExtension may use. The idea is that any classes that aren't used by anything can be compiled out of a custom engine build for that specific project. If there's even the possibility that the class may be used, then it should be included on the list of used classes.

TLDR:

  • where it is used (editor workflow)
  • that the extension should provide those statically (shouldn't depend on when the callback is invoked)

@dsnopek dsnopek force-pushed the gdextension-get-used-classes branch from 5758ce4 to 02acd4c Compare March 17, 2025 18:20
Copy link
Contributor

@Bromeon Bromeon left a comment

Choose a reason for hiding this comment

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

Minor typo, otherwise looks good! I'll approve already 🙂

@dsnopek dsnopek force-pushed the gdextension-get-used-classes branch from 02acd4c to 2dff9fe Compare March 17, 2025 20:27
@Repiteo Repiteo merged commit 1b631ed into godotengine:master Mar 17, 2025
20 checks passed
@Repiteo
Copy link
Contributor

Repiteo commented Mar 17, 2025

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants