godotengine / godot-cpp

C++ bindings for the Godot script API
MIT License
1.74k stars 574 forks source link

How to cast node types? #104

Closed BastiaanOlij closed 6 years ago

BastiaanOlij commented 6 years ago

Ok this is an interesting one. On the GDNative side everything is a wrapper. In Godot Node::get_child returns a Node but if that node is a spatial it is safe to cast it to Spatial .

On the GDNative side it actually instantiates a Node wrapper class, not a Spatial wrapper class. While their data footprint is the same and we're mostly accessing static members it works casting it, but it feels wrong :)

We need a safer way to cast between types.

BastiaanOlij commented 6 years ago

I guess related to #92 ?

karroffel commented 6 years ago

Well currently there are no real "wrappers", only wrapper APIs. The bindings cheat a lot by re-using the this pointer to hold the actual pointer of the Godot classes. So if you cast then nothing happens at all. There is no direct access to anything, no virtual method lookups, there's never a need to dereference the this pointer, so it's perfectly safe to cast. The only thing that could happen is that ptrcalls could fail/crash, so it should still be checked.

karroffel commented 6 years ago

In the nativescript-1.1 branch this can be done like this

void SomeClass::test_method(godot::Object *object)
{
        godot::Reference *r = godot::Object::cast_to<godot::Reference>(object);
        if (r) {
                r->reference();
        }

        SomeCustomType *custom = godot::Object::cast_to<SomeCustomType>(object);
        if (custom) {
                custom->some_custom_method();
        }
}