godot-cpp
godot-cpp copied to clipboard
not able to pass arguments to object during construction
Unless I'm mistaken, it appears to not be possible to pass arguments to a constructor (new/_init) from gdscript.
one would think you could bind _init and pass arguments to new() from GDscript but that does not seem to be the case.
This is kind of a big deal since it breaks RAII which is one of the most fundamental features of C++. Having to call a function after a class is built, or it is malformed, is not good.
If this is currently possible, it should be added to the example as it will be used by nearly everyone who uses c++.
Related to https://github.com/godotengine/godot-proposals/issues/1513.
Which Godot version are you using? Which class is your extension extending from?
Godot v4 Beta7 (godot-cpp f1d501f)
Extending from Node.
Using this code, which compiles and links perfectly:
class TileDataInterface : public godot::Node {
GDCLASS(TileDataInterface, godot::Node)
protected:
static void _bind_methods();
TileData* tileData = nullptr;
public:
TileDataInterface(){};
~TileDataInterface(){};
void _init(int id, int tileType);
};
void TileDataInterface::_bind_methods(){
ClassDB::bind_method(D_METHOD("_init", "a", "b"), &TileDataInterface::_init, DEFVAL(0), DEFVAL(0));
}
void TileDataInterface::_init(int id, int tileType){
tileData = new TileData((TileId)id, (TileType)tileType);
}
produces this error in GDScript
var data = TileDataInterface.new(0, 0)
Too many arguments for "new()" call. Expected at most 0 but received 2.
Still not possible. It would be useful in some cases.
I am curious, what if you declared the TileDataInterface class with two constructors, making one private, i.e.:
private:
TileDataInterface() {}
public:
TileDataInterface(int id, int tileType)
In this case, drop the _init method in favor of the class' ctor, does that work?
Is this possible yet with GDExtensions or not?
No, it's still not possible.
Side note: Is this even possible for classes added in Godot modules? The only classes I can think of with proper constructors are variant types, like Vector3(), etc, but I haven't gone digging into the code yet.
Side note: Is this even possible for classes added in Godot modules?
Yes, see Label for an example:
memnew(Label("Hello world!"))
However, these (optional) parameters can't be exposed for nodes in the scripting API.