Skip to content

Custom classes can't pass themselves into calls to other Godot APIs in their constructor #1039

@dsnopek

Description

@dsnopek

In SG Physics 2D, I'm using this pattern where the physics nodes pass this into function calls on the physics server in their constructors, for example:

SGCollisionObject2D::SGCollisionObject2D(RID p_rid) {
	SGPhysics2DServer *physics_server = SGPhysics2DServer::get_singleton();
	physics_server->collision_object_set_data(p_rid, this);
}

However, this causes lots of problems inside the physics server, when it tries to use the object with any Godot APIs, because the object itself hasn't had it's instance and instance binding set on the Godot engine side yet - that happens after the constructor is finished, in Wrapped::_postinitialize().

(One example of something that breaks: if you store the Object * in a Variant, and then take an Object * back out, it will be a new, different Object *! So, if the function you call in the constructor happens to take a Variant, it will do weird things, including possibly segfault.)

I'm not sure what the solution could be?

It would be great if the Wrapped constructor could set the instance and instance binding, because parent constructors are always run before their child classes constructors, but I'm not sure this wouldn't cause other problems?

It was PR #663 that originally moved this to Wrapped::_postinitialize(). Before that, it was done by generating a constructor in in the GDCLASS() macro, which we definitely don't want to go back to, as that blocked custom classes from making custom constructors altogether.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugThis has been identified as a bug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions