Godot Version
4.2
Question
I’m a bit confused about the correct use of TypedArrays in gdextension. How can I expose them correctly to gdscript?
Consider a class MyClass : RefCounted
.
EDIT: Consider a class MyClass : Resource
.
I noticed godot defines a MAKE_TYPED_ARRAY
macro, which it uses to create the TypedArrray
implementations for it’s Variants
.
Is it necessary or beneficial to use this for our own types? For example: MAKE_TYPED_ARRAY(MyClass, Variant::OBJECT)
Does the TypedArray<MyClass>
type need to be registered to expose it?
And most of all, why do I still need to cast the bloody values because they seem to be returned as Variant despite the typing of the TypedArray
.
It’s all just a little confusing and not a lot of documentation seems to be out there.
See c++ - Creating a new array type compatible with `godot::Variant`? - Stack Overflow for some additional context.
EDIT: after some experimenting it seems like calling MAKE_TYPED_ARRAY(MyClass, Variant::OBJECT)
doesn’t seem to make much of a difference either way. At least not from the gdscript user perspective.
The same goes for registering TypedArray<MyClass>
I managed to expose a TypedArray<MyClass>
, and assigning an Array[MyClass]
from gdscript works just fine.
The editor however is a different story.
Consider the following:
//test.h
class TestObject : public Resource {
//...
};
class TypedArrayTest : public Resource {
GDCLASS(TypedArrayTest, Resource)
private:
TypedArray<TestObject> test_array;
protected:
static void _bind_methods();
public:
TypedArray<TestObject> get_test_array() const;
void set_test_array(const TypedArray<TestObject> p_value);
};
//test.cpp
void TypedArrayTest::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_test_array"), &TypedArrayTest::get_test_array);
ClassDB::bind_method(D_METHOD("set_test_array", "p_value"), &TypedArrayTest::set_test_array);
ClassDB::add_property("TypedArrayTest", PropertyInfo(Variant::ARRAY, "test_array"), "set_test_array", "get_test_array");
}
//implementation of get and set
So now we @export this in gdscript.
@export var test:TypedArrayTest
This works, but the array in the property editor shows up like an untyped array.
To assign an element, I first need to select Object
as a type. Next I need to assign New TestObject
instance to that element.
All this for just one element, that’s a bit cumbersome.
The editor does check the type though, so that is alright. You can’t assign any other type than Object
, or any other instance than TestObject
.
The most annoying part is that the editor shows the whole list of types in every step of this assignment.
Is there any way to limit this?
When you recreate this whole thing in plain gdscript, the editor does recognize @export var gd_test: Array[TestObjectGdsImplemetation]
corretly.
In this case he editor does display the intended behaviour. You can just assign new TestObjectGdsImplemetation
instances in one simple step, without going through all the nonsense I described above.
This leads me to believe it should be possible to achieve the same from GDExtension as well.