Skip to content

[Draft Feature] Hook System for Binding Generation#2023

Draft
Togira123 wants to merge 2 commits into
godotengine:masterfrom
Togira123:hook-mvp-v2
Draft

[Draft Feature] Hook System for Binding Generation#2023
Togira123 wants to merge 2 commits into
godotengine:masterfrom
Togira123:hook-mvp-v2

Conversation

@Togira123

@Togira123 Togira123 commented Jul 16, 2026

Copy link
Copy Markdown

This draft aims to collect more feedback and ideas on a hook system for binding generation. The core idea is that users should be able to extend/modify the way the bindings are generated. The current implementation adds a new command to SCons, called binding_hook_file, which takes a file path to a python file. The specified python file should define a class that extends BindingGeneratorHooks and is called BindingGeneratorHooksExtension. It can then override the methods provided there to modify the way the bindings are generated. As an example, there is custom_generator.py included in this draft (won't be included in the final PR), which adds names of signals as constants for each header file. It can be tested using scons binding_hook_file=custom_generator.py.

The current implementation was already discussed here: https://chat.godotengine.org/channel/gdextension/thread/2gR6bngEu57tWLQG9

@Togira123

Togira123 commented Jul 18, 2026

Copy link
Copy Markdown
Author

This second approach uses no SCons arguments, as suggested by @Ivorforce
The way this would work is the following:

Users that want to define their own hooks would still do so in a dedicated file, still extending BindingGeneratorHooks, as before. The way they pass it to SCons is they import the file in their own SConstruct file and then add it to the env exports like so:

from custom_generator import SignalGenerationHooks

and

env = SConscript("godot-cpp/SConstruct", {"env": env, "customs": customs, "binding_hooks": SignalGenerationHooks()})

This second snippet is similar to the thing that is already present in the template here: https://github.com/godotengine/godot-cpp-template/blob/8283d9632c00ba4654d4e3201f651df01ef51172/SConstruct#L38.
Essentially the user can just add one more export named binding_hooks. The naming is important, because godot-cpp's SConstruct will import the variable (and default to None if it is not supplied). It then adds it to its environment and can access the instance of the class that way.

Below you can find an example of a custom binding hook, this would be placed in the project's root directory so that godot-cpp is a direct subfolder. To work with the snippet above, name it custom_generator.py (it is basically the same code as from the previous commit, I just moved it out of the repo)

import sys

sys.path.insert(0, "godot-cpp")
from binding_generator_hooks import BindingGeneratorHooks


class SignalGenerationHooks(BindingGeneratorHooks):
    def alter_engine_class_header(self, class_api, lines):
        signals = []
        if "signals" in class_api:
            for signal_api in class_api["signals"]:
                name = signal_api["name"]
                signal_constant = "\tstatic constexpr char SIGNAL_" + name.upper() + '[] = "' + name + '";'
                signals.append(signal_constant)
            try:
                idx = lines.index("public:") + 1
                for signal_const in signals:
                    lines.insert(idx, signal_const)
                    idx += 1
            except ValueError:
                print("no public keyword found, not adding signals")
        return lines

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant