Expose non-template versions of vararg methods
Godot version
4.3.stable
godot-cpp version
4.3
System information
MacOS 15.2
Issue description
For custom scripting support and other dynamic uses, it would be nice to expose vararg methods as non-templated.
Currently, the dynamic (non-template) version (<fn>_internal) for classes and utility_functions already exists, although marked private: . As for builtin_classes there are no equivalent, the closes thing would be the private _method_bindings struct but those are raw method pointers doesn't give us nice signature and return value handling.
If this suggestion is accepted, I can raise a PR to remove the private accessor for classes and utility_functions, and refactor builtin_classes bindings to expose the corresponding *_internal methods.
Steps to reproduce
N/A
Minimal reproduction project
N/A
I don't think we should make the *_internal() methods public. One of the core design goals of godot-cpp is to be API compatible with Godot's internal APIs as used by Godot modules, and Godot modules don't have those methods.
Would using object->callv("name", array_of_arguments) work for you?
Would using
object->callv("name", array_of_arguments)work for you?
Technically, this approach will work, though it does introduce some overhead. I was under the impression that all the necessary dynamic code is already in place, and that we would only need a flag in Python to expose it for those who require it.
I was under the impression that all the necessary dynamic code is already in place, and that we would only need a flag in Python to expose it for those who require it.
Like I said above, using the same API as Godot is a core design goal of godot-cpp. While there are existing inconsistencies, I don't think we should introduce any new ones, even optional ones.
I’d like to respectfully challenge the decision to keep the _internal vararg methods private and not expose non-template versions.
This creates a real roadblock for anyone trying to implement a new scripting language for Godot using godot-cpp. The templated call methods aren't usable in dynamic language contexts where argument types and counts aren't known at compile time. callv can't help here either—it only works on Object, which means it's not applicable for things like UtilityFunctions, Callable, or Signal.
From what I understand, even the official GDScript and C# integrations seem to rely on internal support for dynamic calls. While I don’t know their internals in depth, this suggests there's precedent and infrastructure in place for dynamic invocation that’s simply not exposed in godot-cpp. It makes little sense for godot-cpp to withhold the same low-level access from external language implementors, who have no workaround unless they start duplicating efforts around the GDExtension C API.
By keeping these methods private, godot-cpp effectively blocks third-party language implementors from reaching feature parity or even basic interop in some cases. Exposing these vararg methods would make the API much more flexible and open up support for scripting languages beyond what's officially maintained.
I hope this can be reconsidered—it's a relatively small change that would have a big impact for community extensibility.
It looks like there are non-templated versions of some of these methods in Godot, but under different names, for example:
Object::callp(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error)Object::emit_signalp(const StringName &p_name, const Variant **p_args, int p_argcount)Callable::callp(const Variant **p_arguments, int p_argcount, Variant &r_return_value, CallError &r_call_error)
I'm not sure if this applies to all the methods that you want access to, but it would definitely make sense to come up with a way to expose the ones that Godot has with the same name (which seems to be mostly with the p suffix). If there are any that don't have equivalents in Godot, then they should be added to Godot before we add them here.
It makes little sense for godot-cpp to withhold the same low-level access from external language implementors, who have no workaround unless they start duplicating efforts around the GDExtension C API.
One of the core design goals of godot-cpp is to be API compatible with Godot's internal APIs as used by Godot modules. We're slowly removing all the API differences that already exist - adding new differences is just adding a new bug that will need to be fixed later.
I think using the GDExtension C API and the helpers in godot::internal:: is a valid workaround. If you use stuff from godot::internal::, you are very explicitly opting into using things that aren't part of the public API surface, which doesn't need to be compatible with Godot. If there's an addition to godot::internal:: that would make what you want to do easier, I'd potentially be open to that
Also, using a patched version of godot-cpp is also a valid workaround. It's compiled into your extension, and so your customizations won't affect users of your extension. The project is Open Source, and one of the advantages of that is that you can make your changes anyway, even if the maintainers disagree with those changes :-)
Supporting *p methods in line with Godot's own API would essentially be sufficient, I think.
In most cases, it would just involve exposing the existing *_internal methods as *p, along with some minor refactoring for built-in classes like Callable and Signal.