class factory for self-registration of classes
Hi, I've started working on a class factory for my own project that would allow classes to self register without having to manually always add register_class instructions to godot_nativescript_init, and I was actually wondering if submitting it to the official godot-cpp repository would be considered a good thing
as I feel like this could be useful for a lot of users but I don't know if something like this is considered as not wanted in the official repository
right now the way I implemented it makes it so to register a class it must inherit from a generic class and call the REGISTER_CLASS(className) macro in the cpp
for instance for a GDTest class
header
#ifndef GDTEST_H
#define GDTEST_H
#include "ClassFactory.h"
#include <Godot.hpp>
#include <Sprite.hpp>
namespace godot
{
class GDTest : public Sprite, public ClassFactory<GDTest>
{
GODOT_CLASS(GDTest, Sprite)
public:
static void _register_methods();
GDTest() = default;
~GDTest() = default;
void _init(); // our initializer called by Godot
private:
float time_passed;
};
}
#endif
cpp
#include "gdtest.h"
REGISTER_CLASS(godot::GDTest);
void GDTest::_register_methods()
{
register_method("_init", &godot::GDTest::_init);
}
void GDTest::_init()
{
Godot::print("Hello World !");
}
the class GDTest will register itself without a need to modify the godot_nativescript_init
the godot_nativescript_init just needs to contain this
extern "C" void GDN_EXPORT godot_nativescript_init(void *handle) {
godot::Godot::nativescript_init(handle);
ClassFactoryManager::register_classes();
}
If it is wanted I could work on a pull request to integrate it to godot-cpp
the good part is that it even allows to auto generate the gdns files as well
Would like to point out that if the factory generates the .gdns files, then the module will know where the scripts are. This could potentially bring a temporary solution to #430.
https://github.com/SeleDreams/gdnative_class_factory I have made a public repository implementing my system
it both self registers classes but also automatically generates the gdns files
One thing that I'd need to know is if there is any way to determine whether it is running in editor or not from the godot_nativescript_init function
as it's a static function that isn't a node i can't find a way to do it as i can't just get the tree
Edit: found it it was pretty hidden bool editor = godot::Engine::get_singleton()->is_editor_hint();
That looks useful but I have several concerns about it:
-
It is intrusive. Requiring to inherit a base class everywhere makes use of multiple inheritance just for a problem that can be solved at build time. An alternative is to parse header files for the
GODOT_CLASSmacro in a build script, as this won't require any change to the classes. -
It is a run-time solution. I believe this should be solved at build time. It seems like this will also write GDNS files in the exported game because they are packed and then won't be found (which I believe is why you wanted to check the editor flag, but again this IMO should not be a problem to solve at runtime).
-
In Godot 4.0 it is planned to get rid of the need to use
.gdnsfiles and use their name instead, so most of the hassle is going away. Although it can be a temporary solution in 3.x -
More like implementation details: I dont feel it helps much when you no longer need a line in
godot_nativescript_initbut yet need to add a base class + another line in your .cpp file, in addition toGODOT_CLASS. If it was part ofGODOT_CLASSit would remove the inheritance requirement, although it would still need the extra line in .cpp. Also, some classes may need to be registered differently (tool mode).
I can't really tell if core devs would want this officially in the library but I don't like the current solution personally.
That looks useful but I have several concerns about it:
1. It is intrusive. Requiring to inherit a base class everywhere makes use of multiple inheritance just for a problem that can be solved at build time. An alternative is to parse header files for the `GODOT_CLASS` macro in a build script, as this won't require any change to the classes. 2. It is a run-time solution. I believe this should be solved at build time. It seems like this will also write GDNS files in the exported game because they are packed and then won't be found (which I believe is why you wanted to check the editor flag, but again this IMO should not be a problem to solve at runtime). 3. In Godot 4.0 it is planned to get rid of the need to use `.gdns` files and use their name instead, so most of the hassle is going away. Although it can be a temporary solution in 3.x 4. More like implementation details: I dont feel it helps much when you no longer need a line in `godot_nativescript_init` but yet need to add a base class + another line in your .cpp file, in addition to `GODOT_CLASS`. If it was part of `GODOT_CLASS` it would remove the inheritance requirement, although it would still need the extra line in .cpp. Also, some classes may need to be registered differently (tool mode).I can't really tell if core devs would want this officially in the library but I don't like the current solution personally.
I am not sure about how this could be achieved with a build time solution that doesn't rely on a specific build system, I guess some constexpr could maybe be used but I don't have much experience with them
when it comes to the godot_nativescript_init, it still helps not from a perspective of content to add but modularity, managing a monolithic function of register_class is way more complex than having the classes register themselves it allows to easily structure the project in a modular manner without needing to include absolutely all the game components in the gdlibrary.cpp