summaryrefslogtreecommitdiffstats
path: root/core/extension
diff options
context:
space:
mode:
Diffstat (limited to 'core/extension')
-rw-r--r--core/extension/extension_api_dump.cpp172
-rw-r--r--core/extension/gdnative_interface.cpp219
-rw-r--r--core/extension/gdnative_interface.h37
-rw-r--r--core/extension/native_extension.cpp32
-rw-r--r--core/extension/native_extension.h8
-rw-r--r--core/extension/native_extension_manager.cpp19
-rw-r--r--core/extension/native_extension_manager.h3
7 files changed, 391 insertions, 99 deletions
diff --git a/core/extension/extension_api_dump.cpp b/core/extension/extension_api_dump.cpp
index 660e215478..a8547a0090 100644
--- a/core/extension/extension_api_dump.cpp
+++ b/core/extension/extension_api_dump.cpp
@@ -38,6 +38,32 @@
#ifdef TOOLS_ENABLED
+static String get_type_name(const PropertyInfo &p_info) {
+ if (p_info.type == Variant::INT && (p_info.hint == PROPERTY_HINT_INT_IS_POINTER)) {
+ if (p_info.hint_string == "") {
+ return "void*";
+ } else {
+ return p_info.hint_string + "*";
+ }
+ }
+ if (p_info.type == Variant::INT && (p_info.usage & PROPERTY_USAGE_CLASS_IS_ENUM)) {
+ return String("enum::") + String(p_info.class_name);
+ }
+ if (p_info.class_name != StringName()) {
+ return p_info.class_name;
+ }
+ if (p_info.hint == PROPERTY_HINT_RESOURCE_TYPE) {
+ return p_info.hint_string;
+ }
+ if (p_info.type == Variant::NIL && (p_info.usage & PROPERTY_USAGE_NIL_IS_VARIANT)) {
+ return "Variant";
+ }
+ if (p_info.type == Variant::NIL) {
+ return "void";
+ }
+ return Variant::get_type_name(p_info.type);
+}
+
Dictionary NativeExtensionAPIDump::generate_extension_api() {
Dictionary api_dump;
@@ -60,20 +86,38 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() {
const uint32_t vec3_elems = 3;
const uint32_t ptrsize_32 = 4;
- const uint32_t ptrsize_64 = 4;
+ const uint32_t ptrsize_64 = 8;
static const char *build_config_name[4] = { "float_32", "float_64", "double_32", "double_64" };
{
//type sizes
- struct {
+ constexpr struct {
Variant::Type type;
uint32_t size_32_bits_real_float;
uint32_t size_64_bits_real_float;
uint32_t size_32_bits_real_double;
uint32_t size_64_bits_real_double;
+
+ // For compile-time size check.
+ constexpr uint32_t operator[](int index) const {
+ switch (index) {
+#ifndef REAL_T_IS_DOUBLE
+ case sizeof(uint32_t):
+ return size_32_bits_real_float;
+ case sizeof(uint64_t):
+ return size_64_bits_real_float;
+#else // REAL_T_IS_DOUBLE
+ case sizeof(uint32_t):
+ return size_32_bits_real_double;
+ case sizeof(uint64_t):
+ return size_64_bits_real_double;
+#endif
+ }
+ return -1;
+ }
} type_size_array[Variant::VARIANT_MAX + 1] = {
{ Variant::NIL, 0, 0, 0, 0 },
- { Variant::BOOL, sizeof(uint32_t), sizeof(uint32_t), sizeof(uint32_t), sizeof(uint32_t) },
+ { Variant::BOOL, sizeof(uint8_t), sizeof(uint8_t), sizeof(uint8_t), sizeof(uint8_t) },
{ Variant::INT, sizeof(int64_t), sizeof(int64_t), sizeof(int64_t), sizeof(int64_t) },
{ Variant::FLOAT, sizeof(double), sizeof(double), sizeof(double), sizeof(double) },
{ Variant::STRING, ptrsize_32, ptrsize_64, ptrsize_32, ptrsize_64 },
@@ -98,25 +142,62 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() {
{ Variant::SIGNAL, sizeof(Signal), sizeof(Signal), sizeof(Signal), sizeof(Signal) }, // Hardcoded align.
{ Variant::DICTIONARY, ptrsize_32, ptrsize_64, ptrsize_32, ptrsize_64 },
{ Variant::ARRAY, ptrsize_32, ptrsize_64, ptrsize_32, ptrsize_64 },
- { Variant::PACKED_BYTE_ARRAY, ptrsize_32, ptrsize_64, ptrsize_32, ptrsize_64 },
- { Variant::PACKED_INT32_ARRAY, ptrsize_32, ptrsize_64, ptrsize_32, ptrsize_64 },
- { Variant::PACKED_INT64_ARRAY, ptrsize_32, ptrsize_64, ptrsize_32, ptrsize_64 },
- { Variant::PACKED_FLOAT32_ARRAY, ptrsize_32, ptrsize_64, ptrsize_32, ptrsize_64 },
- { Variant::PACKED_FLOAT64_ARRAY, ptrsize_32, ptrsize_64, ptrsize_32, ptrsize_64 },
- { Variant::PACKED_STRING_ARRAY, ptrsize_32, ptrsize_64, ptrsize_32, ptrsize_64 },
- { Variant::PACKED_VECTOR2_ARRAY, ptrsize_32, ptrsize_64, ptrsize_32, ptrsize_64 },
- { Variant::PACKED_VECTOR3_ARRAY, ptrsize_32, ptrsize_64, ptrsize_32, ptrsize_64 },
- { Variant::PACKED_COLOR_ARRAY, ptrsize_32, ptrsize_64, ptrsize_32, ptrsize_64 },
+ { Variant::PACKED_BYTE_ARRAY, ptrsize_32 * 2, ptrsize_64 * 2, ptrsize_32 * 2, ptrsize_64 * 2 },
+ { Variant::PACKED_INT32_ARRAY, ptrsize_32 * 2, ptrsize_64 * 2, ptrsize_32 * 2, ptrsize_64 * 2 },
+ { Variant::PACKED_INT64_ARRAY, ptrsize_32 * 2, ptrsize_64 * 2, ptrsize_32 * 2, ptrsize_64 * 2 },
+ { Variant::PACKED_FLOAT32_ARRAY, ptrsize_32 * 2, ptrsize_64 * 2, ptrsize_32 * 2, ptrsize_64 * 2 },
+ { Variant::PACKED_FLOAT64_ARRAY, ptrsize_32 * 2, ptrsize_64 * 2, ptrsize_32 * 2, ptrsize_64 * 2 },
+ { Variant::PACKED_STRING_ARRAY, ptrsize_32 * 2, ptrsize_64 * 2, ptrsize_32 * 2, ptrsize_64 * 2 },
+ { Variant::PACKED_VECTOR2_ARRAY, ptrsize_32 * 2, ptrsize_64 * 2, ptrsize_32 * 2, ptrsize_64 * 2 },
+ { Variant::PACKED_VECTOR3_ARRAY, ptrsize_32 * 2, ptrsize_64 * 2, ptrsize_32 * 2, ptrsize_64 * 2 },
+ { Variant::PACKED_COLOR_ARRAY, ptrsize_32 * 2, ptrsize_64 * 2, ptrsize_32 * 2, ptrsize_64 * 2 },
{ Variant::VARIANT_MAX, sizeof(uint64_t) + sizeof(float) * 4, sizeof(uint64_t) + sizeof(float) * 4, sizeof(uint64_t) + sizeof(double) * 4, sizeof(uint64_t) + sizeof(double) * 4 },
};
+ // Validate sizes at compile time for the current build configuration.
+ static_assert(type_size_array[Variant::BOOL][sizeof(void *)] == sizeof(GDNativeBool), "Size of bool mismatch");
+ static_assert(type_size_array[Variant::INT][sizeof(void *)] == sizeof(GDNativeInt), "Size of int mismatch");
+ static_assert(type_size_array[Variant::FLOAT][sizeof(void *)] == sizeof(double), "Size of float mismatch");
+ static_assert(type_size_array[Variant::STRING][sizeof(void *)] == sizeof(String), "Size of String mismatch");
+ static_assert(type_size_array[Variant::VECTOR2][sizeof(void *)] == sizeof(Vector2), "Size of Vector2 mismatch");
+ static_assert(type_size_array[Variant::VECTOR2I][sizeof(void *)] == sizeof(Vector2i), "Size of Vector2i mismatch");
+ static_assert(type_size_array[Variant::RECT2][sizeof(void *)] == sizeof(Rect2), "Size of Rect2 mismatch");
+ static_assert(type_size_array[Variant::RECT2I][sizeof(void *)] == sizeof(Rect2i), "Size of Rect2i mismatch");
+ static_assert(type_size_array[Variant::VECTOR3][sizeof(void *)] == sizeof(Vector3), "Size of Vector3 mismatch");
+ static_assert(type_size_array[Variant::VECTOR3I][sizeof(void *)] == sizeof(Vector3i), "Size of Vector3i mismatch");
+ static_assert(type_size_array[Variant::TRANSFORM2D][sizeof(void *)] == sizeof(Transform2D), "Size of Transform2D mismatch");
+ static_assert(type_size_array[Variant::PLANE][sizeof(void *)] == sizeof(Plane), "Size of Plane mismatch");
+ static_assert(type_size_array[Variant::QUATERNION][sizeof(void *)] == sizeof(Quaternion), "Size of Quaternion mismatch");
+ static_assert(type_size_array[Variant::AABB][sizeof(void *)] == sizeof(AABB), "Size of AABB mismatch");
+ static_assert(type_size_array[Variant::BASIS][sizeof(void *)] == sizeof(Basis), "Size of Basis mismatch");
+ static_assert(type_size_array[Variant::TRANSFORM3D][sizeof(void *)] == sizeof(Transform3D), "Size of Transform3D mismatch");
+ static_assert(type_size_array[Variant::COLOR][sizeof(void *)] == sizeof(Color), "Size of Color mismatch");
+ static_assert(type_size_array[Variant::STRING_NAME][sizeof(void *)] == sizeof(StringName), "Size of StringName mismatch");
+ static_assert(type_size_array[Variant::NODE_PATH][sizeof(void *)] == sizeof(NodePath), "Size of NodePath mismatch");
+ static_assert(type_size_array[Variant::RID][sizeof(void *)] == sizeof(RID), "Size of RID mismatch");
+ static_assert(type_size_array[Variant::OBJECT][sizeof(void *)] == sizeof(Object *), "Size of Object mismatch");
+ static_assert(type_size_array[Variant::CALLABLE][sizeof(void *)] == sizeof(Callable), "Size of Callable mismatch");
+ static_assert(type_size_array[Variant::SIGNAL][sizeof(void *)] == sizeof(Signal), "Size of Signal mismatch");
+ static_assert(type_size_array[Variant::DICTIONARY][sizeof(void *)] == sizeof(Dictionary), "Size of Dictionary mismatch");
+ static_assert(type_size_array[Variant::ARRAY][sizeof(void *)] == sizeof(Array), "Size of Array mismatch");
+ static_assert(type_size_array[Variant::PACKED_BYTE_ARRAY][sizeof(void *)] == sizeof(PackedByteArray), "Size of PackedByteArray mismatch");
+ static_assert(type_size_array[Variant::PACKED_INT32_ARRAY][sizeof(void *)] == sizeof(PackedInt32Array), "Size of PackedInt32Array mismatch");
+ static_assert(type_size_array[Variant::PACKED_INT64_ARRAY][sizeof(void *)] == sizeof(PackedInt64Array), "Size of PackedInt64Array mismatch");
+ static_assert(type_size_array[Variant::PACKED_FLOAT32_ARRAY][sizeof(void *)] == sizeof(PackedFloat32Array), "Size of PackedFloat32Array mismatch");
+ static_assert(type_size_array[Variant::PACKED_FLOAT64_ARRAY][sizeof(void *)] == sizeof(PackedFloat64Array), "Size of PackedFloat64Array mismatch");
+ static_assert(type_size_array[Variant::PACKED_STRING_ARRAY][sizeof(void *)] == sizeof(PackedStringArray), "Size of PackedStringArray mismatch");
+ static_assert(type_size_array[Variant::PACKED_VECTOR2_ARRAY][sizeof(void *)] == sizeof(PackedVector2Array), "Size of PackedVector2Array mismatch");
+ static_assert(type_size_array[Variant::PACKED_VECTOR3_ARRAY][sizeof(void *)] == sizeof(PackedVector3Array), "Size of PackedVector3Array mismatch");
+ static_assert(type_size_array[Variant::PACKED_COLOR_ARRAY][sizeof(void *)] == sizeof(PackedColorArray), "Size of PackedColorArray mismatch");
+ static_assert(type_size_array[Variant::VARIANT_MAX][sizeof(void *)] == sizeof(Variant), "Size of Variant mismatch");
+
Array core_type_sizes;
for (int i = 0; i < 4; i++) {
Dictionary d;
d["build_configuration"] = build_config_name[i];
Array sizes;
- for (int j = 0; j < Variant::VARIANT_MAX; j++) {
+ for (int j = 0; j <= Variant::VARIANT_MAX; j++) {
Variant::Type t = type_size_array[j].type;
String name = t == Variant::VARIANT_MAX ? String("Variant") : Variant::get_type_name(t);
Dictionary d2;
@@ -356,6 +437,8 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() {
d["indexing_return_type"] = index_type == Variant::NIL ? String("Variant") : Variant::get_type_name(index_type);
}
+ d["is_keyed"] = Variant::ValidatedKeyedSetter(type);
+
{
//members
Array members;
@@ -403,6 +486,7 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() {
if (k != Variant::OP_NEGATE && k != Variant::OP_POSITIVE && k != Variant::OP_NOT && k != Variant::OP_BIT_NEGATE) {
d2["right_type"] = Variant::get_type_name(Variant::Type(j));
}
+ d2["return_type"] = Variant::get_type_name(Variant::get_operator_return_type(Variant::Operator(k), type, Variant::Type(j)));
operators.push_back(d2);
}
}
@@ -482,6 +566,10 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() {
d["constructors"] = constructors;
}
}
+ {
+ //destructor
+ d["has_destructor"] = Variant::has_destructor(type);
+ }
builtins.push_back(d);
}
@@ -572,7 +660,7 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() {
ClassDB::get_method_list(class_name, &method_list, true);
for (const MethodInfo &F : method_list) {
StringName method_name = F.name;
- if (F.flags & METHOD_FLAG_VIRTUAL) {
+ if ((F.flags & METHOD_FLAG_VIRTUAL) && !(F.flags & METHOD_FLAG_OBJECT_CORE)) {
//virtual method
const MethodInfo &mi = F;
Dictionary d2;
@@ -590,16 +678,8 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() {
if (i >= 0) {
d3["name"] = pinfo.name;
}
- if (pinfo.class_name != StringName()) {
- d3["type"] = String(pinfo.class_name);
- } else {
- Variant::Type type = pinfo.type;
- if (type == Variant::NIL) {
- d3["type"] = "Variant";
- } else {
- d3["type"] = Variant::get_type_name(type);
- }
- }
+
+ d3["type"] = get_type_name(pinfo);
if (i == -1) {
d2["return_value"] = d3;
@@ -641,16 +721,7 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() {
if (i >= 0) {
d3["name"] = pinfo.name;
}
- if (pinfo.class_name != StringName()) {
- d3["type"] = String(pinfo.class_name);
- } else {
- Variant::Type type = pinfo.type;
- if (type == Variant::NIL) {
- d3["type"] = "Variant";
- } else {
- d3["type"] = Variant::get_type_name(type);
- }
- }
+ d3["type"] = get_type_name(pinfo);
if (method->get_argument_meta(i) > 0) {
static const char *argmeta[11] = { "none", "int8", "int16", "int32", "int64", "uint8", "uint16", "uint32", "uint64", "float", "double" };
@@ -697,14 +768,7 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() {
for (int i = 0; i < F.arguments.size(); i++) {
Dictionary d3;
d3["name"] = F.arguments[i].name;
- Variant::Type type = F.arguments[i].type;
- if (F.arguments[i].class_name != StringName()) {
- d3["type"] = String(F.arguments[i].class_name);
- } else if (type == Variant::NIL) {
- d3["type"] = "Variant";
- } else {
- d3["type"] = Variant::get_type_name(type);
- }
+ d3["type"] = get_type_name(F.arguments[i]);
arguments.push_back(d3);
}
if (arguments.size()) {
@@ -732,16 +796,8 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() {
}
StringName property_name = F.name;
Dictionary d2;
+ d2["type"] = get_type_name(F);
d2["name"] = String(property_name);
-
- if (F.class_name != StringName()) {
- d2["type"] = String(F.class_name);
- } else if (F.type == Variant::NIL && F.usage & PROPERTY_USAGE_NIL_IS_VARIANT) {
- d2["type"] = "Variant";
- } else {
- d2["type"] = Variant::get_type_name(F.type);
- }
-
d2["setter"] = ClassDB::get_property_setter(class_name, F.name);
d2["getter"] = ClassDB::get_property_getter(class_name, F.name);
d2["index"] = ClassDB::get_property_index(class_name, F.name);
@@ -782,6 +838,20 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() {
}
}
+ {
+ Array native_structures;
+
+ {
+ Dictionary d;
+ d["name"] = "AudioFrame";
+ d["format"] = "float left,float right";
+
+ native_structures.push_back(d);
+ }
+
+ api_dump["native_structures"] = native_structures;
+ }
+
return api_dump;
}
diff --git a/core/extension/gdnative_interface.cpp b/core/extension/gdnative_interface.cpp
index 88fff342ee..de107b4156 100644
--- a/core/extension/gdnative_interface.cpp
+++ b/core/extension/gdnative_interface.cpp
@@ -74,8 +74,6 @@ static void gdnative_variant_destroy(GDNativeVariantPtr p_self) {
// variant type
-#define memnew_placement_custom(m_placement, m_class, m_constr) _post_initialize(new (m_placement, sizeof(m_class), "") m_constr)
-
static void gdnative_variant_call(GDNativeVariantPtr p_self, const GDNativeStringNamePtr p_method, const GDNativeVariantPtr *p_args, const GDNativeInt p_argcount, GDNativeVariantPtr r_return, GDNativeCallError *r_error) {
Variant *self = (Variant *)p_self;
const StringName *method = (const StringName *)p_method;
@@ -83,7 +81,7 @@ static void gdnative_variant_call(GDNativeVariantPtr p_self, const GDNativeStrin
Variant ret;
Callable::CallError error;
self->call(*method, args, p_argcount, ret, error);
- memnew_placement_custom(r_return, Variant, Variant(ret));
+ memnew_placement(r_return, Variant(ret));
if (r_error) {
r_error->error = (GDNativeCallErrorType)(error.error);
@@ -99,7 +97,7 @@ static void gdnative_variant_call_static(GDNativeVariantType p_type, const GDNat
Variant ret;
Callable::CallError error;
Variant::call_static(type, *method, args, p_argcount, ret, error);
- memnew_placement_custom(r_return, Variant, Variant(ret));
+ memnew_placement(r_return, Variant(ret));
if (r_error) {
r_error->error = (GDNativeCallErrorType)error.error;
@@ -164,7 +162,7 @@ static void gdnative_variant_get(const GDNativeVariantPtr p_self, const GDNative
const Variant *key = (const Variant *)p_key;
bool valid;
- memnew_placement_custom(r_ret, Variant, Variant(self->get(*key, &valid)));
+ memnew_placement(r_ret, Variant(self->get(*key, &valid)));
*r_valid = valid;
}
@@ -173,7 +171,7 @@ static void gdnative_variant_get_named(const GDNativeVariantPtr p_self, const GD
const StringName *key = (const StringName *)p_key;
bool valid;
- memnew_placement_custom(r_ret, Variant, Variant(self->get_named(*key, valid)));
+ memnew_placement(r_ret, Variant(self->get_named(*key, valid)));
*r_valid = valid;
}
@@ -182,7 +180,7 @@ static void gdnative_variant_get_keyed(const GDNativeVariantPtr p_self, const GD
const Variant *key = (const Variant *)p_key;
bool valid;
- memnew_placement_custom(r_ret, Variant, Variant(self->get_keyed(*key, valid)));
+ memnew_placement(r_ret, Variant(self->get_keyed(*key, valid)));
*r_valid = valid;
}
@@ -191,7 +189,7 @@ static void gdnative_variant_get_indexed(const GDNativeVariantPtr p_self, GDNati
bool valid;
bool oob;
- memnew_placement_custom(r_ret, Variant, Variant(self->get_indexed(p_index, valid, oob)));
+ memnew_placement(r_ret, Variant(self->get_indexed(p_index, valid, oob)));
*r_valid = valid;
*r_oob = oob;
}
@@ -222,7 +220,7 @@ static void gdnative_variant_iter_get(const GDNativeVariantPtr p_self, GDNativeV
Variant *iter = (Variant *)r_iter;
bool valid;
- memnew_placement_custom(r_ret, Variant, Variant(self->iter_next(*iter, valid)));
+ memnew_placement(r_ret, Variant(self->iter_next(*iter, valid)));
*r_valid = valid;
}
@@ -254,12 +252,12 @@ static void gdnative_variant_interpolate(const GDNativeVariantPtr p_a, const GDN
static void gdnative_variant_duplicate(const GDNativeVariantPtr p_self, GDNativeVariantPtr r_ret, GDNativeBool p_deep) {
const Variant *self = (const Variant *)p_self;
- memnew_placement_custom(r_ret, Variant, Variant(self->duplicate(p_deep)));
+ memnew_placement(r_ret, Variant(self->duplicate(p_deep)));
}
static void gdnative_variant_stringify(const GDNativeVariantPtr p_self, GDNativeStringPtr r_ret) {
const Variant *self = (const Variant *)p_self;
- memnew_placement_custom(r_ret, String, String(*self));
+ memnew_placement(r_ret, String(*self));
}
static GDNativeVariantType gdnative_variant_get_type(const GDNativeVariantPtr p_self) {
@@ -288,7 +286,7 @@ static GDNativeBool gdnative_variant_has_key(const GDNativeVariantPtr p_self, co
static void gdnative_variant_get_type_name(GDNativeVariantType p_type, GDNativeStringPtr r_ret) {
String name = Variant::get_type_name((Variant::Type)p_type);
- memnew_placement_custom(r_ret, String, String(name));
+ memnew_placement(r_ret, String(name));
}
static GDNativeBool gdnative_variant_can_convert(GDNativeVariantType p_from, GDNativeVariantType p_to) {
@@ -299,6 +297,161 @@ static GDNativeBool gdnative_variant_can_convert_strict(GDNativeVariantType p_fr
return Variant::can_convert_strict((Variant::Type)p_from, (Variant::Type)p_to);
}
+// Variant interaction.
+static GDNativeVariantFromTypeConstructorFunc gdnative_get_variant_from_type_constructor(GDNativeVariantType p_type) {
+ switch (p_type) {
+ case GDNATIVE_VARIANT_TYPE_BOOL:
+ return VariantTypeConstructor<bool>::variant_from_type;
+ case GDNATIVE_VARIANT_TYPE_INT:
+ return VariantTypeConstructor<int64_t>::variant_from_type;
+ case GDNATIVE_VARIANT_TYPE_FLOAT:
+ return VariantTypeConstructor<double>::variant_from_type;
+ case GDNATIVE_VARIANT_TYPE_STRING:
+ return VariantTypeConstructor<String>::variant_from_type;
+ case GDNATIVE_VARIANT_TYPE_VECTOR2:
+ return VariantTypeConstructor<Vector2>::variant_from_type;
+ case GDNATIVE_VARIANT_TYPE_VECTOR2I:
+ return VariantTypeConstructor<Vector2i>::variant_from_type;
+ case GDNATIVE_VARIANT_TYPE_RECT2:
+ return VariantTypeConstructor<Rect2>::variant_from_type;
+ case GDNATIVE_VARIANT_TYPE_RECT2I:
+ return VariantTypeConstructor<Rect2i>::variant_from_type;
+ case GDNATIVE_VARIANT_TYPE_VECTOR3:
+ return VariantTypeConstructor<Vector3>::variant_from_type;
+ case GDNATIVE_VARIANT_TYPE_VECTOR3I:
+ return VariantTypeConstructor<Vector3i>::variant_from_type;
+ case GDNATIVE_VARIANT_TYPE_TRANSFORM2D:
+ return VariantTypeConstructor<Transform2D>::variant_from_type;
+ case GDNATIVE_VARIANT_TYPE_PLANE:
+ return VariantTypeConstructor<Plane>::variant_from_type;
+ case GDNATIVE_VARIANT_TYPE_QUATERNION:
+ return VariantTypeConstructor<Quaternion>::variant_from_type;
+ case GDNATIVE_VARIANT_TYPE_AABB:
+ return VariantTypeConstructor<AABB>::variant_from_type;
+ case GDNATIVE_VARIANT_TYPE_BASIS:
+ return VariantTypeConstructor<Basis>::variant_from_type;
+ case GDNATIVE_VARIANT_TYPE_TRANSFORM3D:
+ return VariantTypeConstructor<Transform3D>::variant_from_type;
+ case GDNATIVE_VARIANT_TYPE_COLOR:
+ return VariantTypeConstructor<Color>::variant_from_type;
+ case GDNATIVE_VARIANT_TYPE_STRING_NAME:
+ return VariantTypeConstructor<StringName>::variant_from_type;
+ case GDNATIVE_VARIANT_TYPE_NODE_PATH:
+ return VariantTypeConstructor<NodePath>::variant_from_type;
+ case GDNATIVE_VARIANT_TYPE_RID:
+ return VariantTypeConstructor<RID>::variant_from_type;
+ case GDNATIVE_VARIANT_TYPE_OBJECT:
+ return VariantTypeConstructor<Object *>::variant_from_type;
+ case GDNATIVE_VARIANT_TYPE_CALLABLE:
+ return VariantTypeConstructor<Callable>::variant_from_type;
+ case GDNATIVE_VARIANT_TYPE_SIGNAL:
+ return VariantTypeConstructor<Signal>::variant_from_type;
+ case GDNATIVE_VARIANT_TYPE_DICTIONARY:
+ return VariantTypeConstructor<Dictionary>::variant_from_type;
+ case GDNATIVE_VARIANT_TYPE_ARRAY:
+ return VariantTypeConstructor<Array>::variant_from_type;
+ case GDNATIVE_VARIANT_TYPE_PACKED_BYTE_ARRAY:
+ return VariantTypeConstructor<PackedByteArray>::variant_from_type;
+ case GDNATIVE_VARIANT_TYPE_PACKED_INT32_ARRAY:
+ return VariantTypeConstructor<PackedInt32Array>::variant_from_type;
+ case GDNATIVE_VARIANT_TYPE_PACKED_INT64_ARRAY:
+ return VariantTypeConstructor<PackedInt64Array>::variant_from_type;
+ case GDNATIVE_VARIANT_TYPE_PACKED_FLOAT32_ARRAY:
+ return VariantTypeConstructor<PackedFloat32Array>::variant_from_type;
+ case GDNATIVE_VARIANT_TYPE_PACKED_FLOAT64_ARRAY:
+ return VariantTypeConstructor<PackedFloat64Array>::variant_from_type;
+ case GDNATIVE_VARIANT_TYPE_PACKED_STRING_ARRAY:
+ return VariantTypeConstructor<PackedStringArray>::variant_from_type;
+ case GDNATIVE_VARIANT_TYPE_PACKED_VECTOR2_ARRAY:
+ return VariantTypeConstructor<PackedVector2Array>::variant_from_type;
+ case GDNATIVE_VARIANT_TYPE_PACKED_VECTOR3_ARRAY:
+ return VariantTypeConstructor<PackedVector3Array>::variant_from_type;
+ case GDNATIVE_VARIANT_TYPE_PACKED_COLOR_ARRAY:
+ return VariantTypeConstructor<PackedColorArray>::variant_from_type;
+ case GDNATIVE_VARIANT_TYPE_NIL:
+ case GDNATIVE_VARIANT_TYPE_VARIANT_MAX:
+ ERR_FAIL_V_MSG(nullptr, "Getting Variant conversion function with invalid type");
+ }
+ ERR_FAIL_V_MSG(nullptr, "Getting Variant conversion function with invalid type");
+}
+
+static GDNativeTypeFromVariantConstructorFunc gdnative_get_type_from_variant_constructor(GDNativeVariantType p_type) {
+ switch (p_type) {
+ case GDNATIVE_VARIANT_TYPE_BOOL:
+ return VariantTypeConstructor<bool>::type_from_variant;
+ case GDNATIVE_VARIANT_TYPE_INT:
+ return VariantTypeConstructor<int64_t>::type_from_variant;
+ case GDNATIVE_VARIANT_TYPE_FLOAT:
+ return VariantTypeConstructor<double>::type_from_variant;
+ case GDNATIVE_VARIANT_TYPE_STRING:
+ return VariantTypeConstructor<String>::type_from_variant;
+ case GDNATIVE_VARIANT_TYPE_VECTOR2:
+ return VariantTypeConstructor<Vector2>::type_from_variant;
+ case GDNATIVE_VARIANT_TYPE_VECTOR2I:
+ return VariantTypeConstructor<Vector2i>::type_from_variant;
+ case GDNATIVE_VARIANT_TYPE_RECT2:
+ return VariantTypeConstructor<Rect2>::type_from_variant;
+ case GDNATIVE_VARIANT_TYPE_RECT2I:
+ return VariantTypeConstructor<Rect2i>::type_from_variant;
+ case GDNATIVE_VARIANT_TYPE_VECTOR3:
+ return VariantTypeConstructor<Vector3>::type_from_variant;
+ case GDNATIVE_VARIANT_TYPE_VECTOR3I:
+ return VariantTypeConstructor<Vector3i>::type_from_variant;
+ case GDNATIVE_VARIANT_TYPE_TRANSFORM2D:
+ return VariantTypeConstructor<Transform2D>::type_from_variant;
+ case GDNATIVE_VARIANT_TYPE_PLANE:
+ return VariantTypeConstructor<Plane>::type_from_variant;
+ case GDNATIVE_VARIANT_TYPE_QUATERNION:
+ return VariantTypeConstructor<Quaternion>::type_from_variant;
+ case GDNATIVE_VARIANT_TYPE_AABB:
+ return VariantTypeConstructor<AABB>::type_from_variant;
+ case GDNATIVE_VARIANT_TYPE_BASIS:
+ return VariantTypeConstructor<Basis>::type_from_variant;
+ case GDNATIVE_VARIANT_TYPE_TRANSFORM3D:
+ return VariantTypeConstructor<Transform3D>::type_from_variant;
+ case GDNATIVE_VARIANT_TYPE_COLOR:
+ return VariantTypeConstructor<Color>::type_from_variant;
+ case GDNATIVE_VARIANT_TYPE_STRING_NAME:
+ return VariantTypeConstructor<StringName>::type_from_variant;
+ case GDNATIVE_VARIANT_TYPE_NODE_PATH:
+ return VariantTypeConstructor<NodePath>::type_from_variant;
+ case GDNATIVE_VARIANT_TYPE_RID:
+ return VariantTypeConstructor<RID>::type_from_variant;
+ case GDNATIVE_VARIANT_TYPE_OBJECT:
+ return VariantTypeConstructor<Object *>::type_from_variant;
+ case GDNATIVE_VARIANT_TYPE_CALLABLE:
+ return VariantTypeConstructor<Callable>::type_from_variant;
+ case GDNATIVE_VARIANT_TYPE_SIGNAL:
+ return VariantTypeConstructor<Signal>::type_from_variant;
+ case GDNATIVE_VARIANT_TYPE_DICTIONARY:
+ return VariantTypeConstructor<Dictionary>::type_from_variant;
+ case GDNATIVE_VARIANT_TYPE_ARRAY:
+ return VariantTypeConstructor<Array>::type_from_variant;
+ case GDNATIVE_VARIANT_TYPE_PACKED_BYTE_ARRAY:
+ return VariantTypeConstructor<PackedByteArray>::type_from_variant;
+ case GDNATIVE_VARIANT_TYPE_PACKED_INT32_ARRAY:
+ return VariantTypeConstructor<PackedInt32Array>::type_from_variant;
+ case GDNATIVE_VARIANT_TYPE_PACKED_INT64_ARRAY:
+ return VariantTypeConstructor<PackedInt64Array>::type_from_variant;
+ case GDNATIVE_VARIANT_TYPE_PACKED_FLOAT32_ARRAY:
+ return VariantTypeConstructor<PackedFloat32Array>::type_from_variant;
+ case GDNATIVE_VARIANT_TYPE_PACKED_FLOAT64_ARRAY:
+ return VariantTypeConstructor<PackedFloat64Array>::type_from_variant;
+ case GDNATIVE_VARIANT_TYPE_PACKED_STRING_ARRAY:
+ return VariantTypeConstructor<PackedStringArray>::type_from_variant;
+ case GDNATIVE_VARIANT_TYPE_PACKED_VECTOR2_ARRAY:
+ return VariantTypeConstructor<PackedVector2Array>::type_from_variant;
+ case GDNATIVE_VARIANT_TYPE_PACKED_VECTOR3_ARRAY:
+ return VariantTypeConstructor<PackedVector3Array>::type_from_variant;
+ case GDNATIVE_VARIANT_TYPE_PACKED_COLOR_ARRAY:
+ return VariantTypeConstructor<PackedColorArray>::type_from_variant;
+ case GDNATIVE_VARIANT_TYPE_NIL:
+ case GDNATIVE_VARIANT_TYPE_VARIANT_MAX:
+ ERR_FAIL_V_MSG(nullptr, "Getting Variant conversion function with invalid type");
+ }
+ ERR_FAIL_V_MSG(nullptr, "Getting Variant conversion function with invalid type");
+}
+
// ptrcalls
static GDNativePtrOperatorEvaluator gdnative_variant_get_ptr_operator_evaluator(GDNativeVariantOperator p_operator, GDNativeVariantType p_type_a, GDNativeVariantType p_type_b) {
return (GDNativePtrOperatorEvaluator)Variant::get_ptr_operator_evaluator(Variant::Operator(p_operator), Variant::Type(p_type_a), Variant::Type(p_type_b));
@@ -316,6 +469,9 @@ static GDNativePtrBuiltInMethod gdnative_variant_get_ptr_builtin_method(GDNative
static GDNativePtrConstructor gdnative_variant_get_ptr_constructor(GDNativeVariantType p_type, int32_t p_constructor) {
return (GDNativePtrConstructor)Variant::get_ptr_constructor(Variant::Type(p_type), p_constructor);
}
+static GDNativePtrDestructor gdnative_variant_get_ptr_destructor(GDNativeVariantType p_type) {
+ return (GDNativePtrDestructor)Variant::get_ptr_destructor(Variant::Type(p_type));
+}
static void gdnative_variant_construct(GDNativeVariantType p_type, GDNativeVariantPtr p_base, const GDNativeVariantPtr *p_args, int32_t p_argument_count, GDNativeCallError *r_error) {
memnew_placement(p_base, Variant);
@@ -350,7 +506,7 @@ static GDNativePtrKeyedChecker gdnative_variant_get_ptr_keyed_checker(GDNativeVa
return (GDNativePtrKeyedChecker)Variant::get_member_ptr_keyed_checker(Variant::Type(p_type));
}
static void gdnative_variant_get_constant_value(GDNativeVariantType p_type, const char *p_constant, GDNativeVariantPtr r_ret) {
- memnew_placement_custom(r_ret, Variant, Variant(Variant::get_constant_value(Variant::Type(p_type), p_constant)));
+ memnew_placement(r_ret, Variant(Variant::get_constant_value(Variant::Type(p_type), p_constant)));
}
static GDNativePtrUtilityFunction gdnative_variant_get_ptr_utility_function(const char *p_function, GDNativeInt p_hash) {
StringName function = p_function;
@@ -507,7 +663,23 @@ static const char32_t *gdnative_string_operator_index_const(const GDNativeString
/* OBJECT API */
-static void gdnative_object_method_bind_ptrcall(GDNativeMethodBindPtr p_method_bind, GDNativeObjectPtr p_instance, const GDNativeTypePtr *p_args, GDNativeTypePtr p_ret) {
+static void gdnative_object_method_bind_call(const GDNativeMethodBindPtr p_method_bind, GDNativeObjectPtr p_instance, const GDNativeVariantPtr *p_args, GDNativeInt p_arg_count, GDNativeVariantPtr r_return, GDNativeCallError *r_error) {
+ MethodBind *mb = (MethodBind *)p_method_bind;
+ Object *o = (Object *)p_instance;
+ const Variant **args = (const Variant **)p_args;
+ Callable::CallError error;
+
+ Variant ret = mb->call(o, args, p_arg_count, error);
+ memnew_placement(r_return, Variant(ret));
+
+ if (r_error) {
+ r_error->error = (GDNativeCallErrorType)(error.error);
+ r_error->argument = error.argument;
+ r_error->expected = error.expected;
+ }
+}
+
+static void gdnative_object_method_bind_ptrcall(const GDNativeMethodBindPtr p_method_bind, GDNativeObjectPtr p_instance, const GDNativeTypePtr *p_args, GDNativeTypePtr p_ret) {
MethodBind *mb = (MethodBind *)p_method_bind;
Object *o = (Object *)p_instance;
mb->ptrcall(o, (const void **)p_args, p_ret);
@@ -521,11 +693,16 @@ static GDNativeObjectPtr gdnative_global_get_singleton(const char *p_name) {
return (GDNativeObjectPtr)Engine::get_singleton()->get_singleton_object(String(p_name));
}
-static void *gdnative_object_get_instance_binding(GDNativeObjectPtr p_instance, void *p_token, GDNativeInstanceBindingCallbacks *p_callbacks) {
+static void *gdnative_object_get_instance_binding(GDNativeObjectPtr p_instance, void *p_token, const GDNativeInstanceBindingCallbacks *p_callbacks) {
Object *o = (Object *)p_instance;
return o->get_instance_binding(p_token, p_callbacks);
}
+static void gdnative_object_set_instance_binding(GDNativeObjectPtr p_instance, void *p_token, void *p_binding, const GDNativeInstanceBindingCallbacks *p_callbacks) {
+ Object *o = (Object *)p_instance;
+ o->set_instance_binding(p_token, p_binding, p_callbacks);
+}
+
static GDNativeObjectPtr gdnative_object_get_instance_from_id(GDObjectInstanceID p_instance_id) {
return (GDNativeObjectPtr)ObjectDB::get_instance(ObjectID(p_instance_id));
}
@@ -626,15 +803,15 @@ void gdnative_setup_interface(GDNativeInterface *p_interface) {
gdni.variant_can_convert = gdnative_variant_can_convert;
gdni.variant_can_convert_strict = gdnative_variant_can_convert_strict;
- //ptrcalls
-#if 0
- GDNativeVariantFromTypeConstructorFunc (*get_variant_from_type_constructor)(GDNativeVariantType p_type);
- GDNativeTypeFromVariantConstructorFunc (*get_variant_to_type_constructor)(GDNativeVariantType p_type);
-#endif
+ gdni.get_variant_from_type_constructor = gdnative_get_variant_from_type_constructor;
+ gdni.get_variant_to_type_constructor = gdnative_get_type_from_variant_constructor;
+
+ // ptrcalls.
gdni.variant_get_ptr_operator_evaluator = gdnative_variant_get_ptr_operator_evaluator;
gdni.variant_get_ptr_builtin_method = gdnative_variant_get_ptr_builtin_method;
gdni.variant_get_ptr_constructor = gdnative_variant_get_ptr_constructor;
+ gdni.variant_get_ptr_destructor = gdnative_variant_get_ptr_destructor;
gdni.variant_construct = gdnative_variant_construct;
gdni.variant_get_ptr_setter = gdnative_variant_get_ptr_setter;
gdni.variant_get_ptr_getter = gdnative_variant_get_ptr_getter;
@@ -668,10 +845,12 @@ void gdnative_setup_interface(GDNativeInterface *p_interface) {
/* OBJECT */
+ gdni.object_method_bind_call = gdnative_object_method_bind_call;
gdni.object_method_bind_ptrcall = gdnative_object_method_bind_ptrcall;
gdni.object_destroy = gdnative_object_destroy;
gdni.global_get_singleton = gdnative_global_get_singleton;
gdni.object_get_instance_binding = gdnative_object_get_instance_binding;
+ gdni.object_set_instance_binding = gdnative_object_set_instance_binding;
gdni.object_cast_to = gdnative_object_cast_to;
gdni.object_get_instance_from_id = gdnative_object_get_instance_from_id;
diff --git a/core/extension/gdnative_interface.h b/core/extension/gdnative_interface.h
index 3e69a28d59..3a5b04429c 100644
--- a/core/extension/gdnative_interface.h
+++ b/core/extension/gdnative_interface.h
@@ -39,6 +39,11 @@
#include <stdint.h>
#include <stdio.h>
+#ifndef __cplusplus
+typedef uint32_t char32_t;
+typedef uint16_t char16_t;
+#endif
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -140,12 +145,12 @@ typedef uint64_t GDObjectInstanceID;
/* VARIANT DATA I/O */
typedef enum {
- NATIVE_CALL_OK,
- NATIVE_CALL_ERROR_INVALID_METHOD,
- NATIVE_CALL_ERROR_INVALID_ARGUMENT, /* expected is variant type */
- NATIVE_CALL_ERROR_TOO_MANY_ARGUMENTS, /* expected is number of arguments */
- NATIVE_CALL_ERROR_TOO_FEW_ARGUMENTS, /* expected is number of arguments */
- NATIVE_CALL_ERROR_INSTANCE_IS_NULL,
+ GDNATIVE_CALL_OK,
+ GDNATIVE_CALL_ERROR_INVALID_METHOD,
+ GDNATIVE_CALL_ERROR_INVALID_ARGUMENT, /* expected is variant type */
+ GDNATIVE_CALL_ERROR_TOO_MANY_ARGUMENTS, /* expected is number of arguments */
+ GDNATIVE_CALL_ERROR_TOO_FEW_ARGUMENTS, /* expected is number of arguments */
+ GDNATIVE_CALL_ERROR_INSTANCE_IS_NULL,
} GDNativeCallErrorType;
@@ -160,6 +165,7 @@ typedef void (*GDNativeTypeFromVariantConstructorFunc)(GDNativeTypePtr, GDNative
typedef void (*GDNativePtrOperatorEvaluator)(const GDNativeTypePtr p_left, const GDNativeTypePtr p_right, GDNativeTypePtr r_result);
typedef void (*GDNativePtrBuiltInMethod)(GDNativeTypePtr p_base, const GDNativeTypePtr *p_args, GDNativeTypePtr r_return, int p_argument_count);
typedef void (*GDNativePtrConstructor)(GDNativeTypePtr p_base, const GDNativeTypePtr *p_args);
+typedef void (*GDNativePtrDestructor)(GDNativeTypePtr p_base);
typedef void (*GDNativePtrSetter)(GDNativeTypePtr p_base, const GDNativeTypePtr p_value);
typedef void (*GDNativePtrGetter)(const GDNativeTypePtr p_base, GDNativeTypePtr r_value);
typedef void (*GDNativePtrIndexedSetter)(GDNativeTypePtr p_base, GDNativeInt p_index, const GDNativeTypePtr p_value);
@@ -173,7 +179,7 @@ typedef GDNativeObjectPtr (*GDNativeClassConstructor)();
typedef void *(*GDNativeInstanceBindingCreateCallback)(void *p_token, void *p_instance);
typedef void (*GDNativeInstanceBindingFreeCallback)(void *p_token, void *p_instance, void *p_binding);
-typedef GDNativeBool (*GDNativeInstanceBindingReferenceCallback)(void *p_token, void *p_instance, GDNativeBool p_reference);
+typedef GDNativeBool (*GDNativeInstanceBindingReferenceCallback)(void *p_token, void *p_binding, GDNativeBool p_reference);
struct GDNativeInstanceBindingCallbacks {
GDNativeInstanceBindingCreateCallback create_callback;
@@ -206,6 +212,7 @@ typedef void (*GDNativeExtensionClassUnreference)(GDExtensionClassInstancePtr p_
typedef void (*GDNativeExtensionClassCallVirtual)(GDExtensionClassInstancePtr p_instance, const GDNativeTypePtr *p_args, GDNativeTypePtr r_ret);
typedef GDExtensionClassInstancePtr (*GDNativeExtensionClassCreateInstance)(void *p_userdata);
typedef void (*GDNativeExtensionClassFreeInstance)(void *p_userdata, GDExtensionClassInstancePtr p_instance);
+typedef void (*GDNativeExtensionClassObjectInstance)(GDExtensionClassInstancePtr p_instance, GDNativeObjectPtr p_object_instance);
typedef GDNativeExtensionClassCallVirtual (*GDNativeExtensionClassGetVirtual)(void *p_userdata, const char *p_name);
typedef struct {
@@ -219,7 +226,8 @@ typedef struct {
GDNativeExtensionClassUnreference unreference_func;
GDNativeExtensionClassCreateInstance create_instance_func; /* this one is mandatory */
GDNativeExtensionClassFreeInstance free_instance_func; /* this one is mandatory */
- GDNativeExtensionClassGetVirtual get_firtual_func;
+ GDNativeExtensionClassObjectInstance object_instance_func; /* this one is mandatory */
+ GDNativeExtensionClassGetVirtual get_virtual_func;
void *class_userdata;
} GDNativeExtensionClassCreationInfo;
@@ -256,8 +264,8 @@ typedef enum {
GDNATIVE_EXTENSION_METHOD_ARGUMENT_METADATA_REAL_IS_DOUBLE
} GDNativeExtensionClassMethodArgumentMetadata;
-typedef void (*GDNativeExtensionClassMethodCall)(GDExtensionClassInstancePtr p_instance, const GDNativeVariantPtr *p_args, const GDNativeInt p_argument_count, GDNativeVariantPtr r_return, GDNativeCallError *r_error);
-typedef void (*GDNativeExtensionClassMethodPtrCall)(GDExtensionClassInstancePtr p_instance, const GDNativeTypePtr *p_args, GDNativeTypePtr r_ret);
+typedef void (*GDNativeExtensionClassMethodCall)(void *method_userdata, GDExtensionClassInstancePtr p_instance, const GDNativeVariantPtr *p_args, const GDNativeInt p_argument_count, GDNativeVariantPtr r_return, GDNativeCallError *r_error);
+typedef void (*GDNativeExtensionClassMethodPtrCall)(void *method_userdata, GDExtensionClassInstancePtr p_instance, const GDNativeTypePtr *p_args, GDNativeTypePtr r_ret);
/* passing -1 as argument in the following functions refers to the return type */
typedef GDNativeVariantType (*GDNativeExtensionClassMethodGetArgumentType)(void *p_method_userdata, int32_t p_argument);
@@ -339,6 +347,7 @@ typedef struct {
GDNativePtrOperatorEvaluator (*variant_get_ptr_operator_evaluator)(GDNativeVariantOperator p_operator, GDNativeVariantType p_type_a, GDNativeVariantType p_type_b);
GDNativePtrBuiltInMethod (*variant_get_ptr_builtin_method)(GDNativeVariantType p_type, const char *p_method, GDNativeInt p_hash);
GDNativePtrConstructor (*variant_get_ptr_constructor)(GDNativeVariantType p_type, int32_t p_constructor);
+ GDNativePtrDestructor (*variant_get_ptr_destructor)(GDNativeVariantType p_type);
void (*variant_construct)(GDNativeVariantType p_type, GDNativeVariantPtr p_base, const GDNativeVariantPtr *p_args, int32_t p_argument_count, GDNativeCallError *r_error);
GDNativePtrSetter (*variant_get_ptr_setter)(GDNativeVariantType p_type, const char *p_member);
GDNativePtrGetter (*variant_get_ptr_getter)(GDNativeVariantType p_type, const char *p_member);
@@ -380,10 +389,12 @@ typedef struct {
/* OBJECT */
- void (*object_method_bind_ptrcall)(GDNativeMethodBindPtr p_method_bind, GDNativeObjectPtr p_instance, const GDNativeTypePtr *p_args, GDNativeTypePtr r_ret);
+ void (*object_method_bind_call)(const GDNativeMethodBindPtr p_method_bind, GDNativeObjectPtr p_instance, const GDNativeVariantPtr *p_args, GDNativeInt p_arg_count, GDNativeVariantPtr r_ret, GDNativeCallError *r_error);
+ void (*object_method_bind_ptrcall)(const GDNativeMethodBindPtr p_method_bind, GDNativeObjectPtr p_instance, const GDNativeTypePtr *p_args, GDNativeTypePtr r_ret);
void (*object_destroy)(GDNativeObjectPtr p_o);
GDNativeObjectPtr (*global_get_singleton)(const char *p_name);
- void *(*object_get_instance_binding)(GDNativeObjectPtr p_o, void *p_token, GDNativeInstanceBindingCallbacks *p_callbacks);
+ void *(*object_get_instance_binding)(GDNativeObjectPtr p_o, void *p_token, const GDNativeInstanceBindingCallbacks *p_callbacks);
+ void (*object_set_instance_binding)(GDNativeObjectPtr p_o, void *p_token, void *p_binding, const GDNativeInstanceBindingCallbacks *p_callbacks);
GDNativeObjectPtr (*object_cast_to)(const GDNativeObjectPtr p_object, void *p_class_tag);
GDNativeObjectPtr (*object_get_instance_from_id)(GDObjectInstanceID p_instance_id);
@@ -399,7 +410,7 @@ typedef struct {
void (*classdb_register_extension_class)(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_parent_class_name, const GDNativeExtensionClassCreationInfo *p_extension_funcs);
void (*classdb_register_extension_class_method)(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const GDNativeExtensionClassMethodInfo *p_method_info);
- void (*classdb_register_extension_class_integer_constant)(const GDNativeExtensionClassLibraryPtr p_library, const char *p_enum_name, const char *p_class_name, const char *p_constant_name, uint32_t p_constant_value);
+ void (*classdb_register_extension_class_integer_constant)(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_enum_name, const char *p_constant_name, GDNativeInt p_constant_value);
void (*classdb_register_extension_class_property)(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const GDNativePropertyInfo *p_info, const char *p_setter, const char *p_getter);
void (*classdb_register_extension_class_signal)(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_signal_name, const GDNativePropertyInfo *p_argument_info, GDNativeInt p_argument_count);
void (*classdb_unregister_extension_class)(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name); /* Unregistering a parent class before a class that inherits it will result in failure. Inheritors must be unregistered first. */
diff --git a/core/extension/native_extension.cpp b/core/extension/native_extension.cpp
index 16bc28e0a2..a3cd7ca14c 100644
--- a/core/extension/native_extension.cpp
+++ b/core/extension/native_extension.cpp
@@ -29,11 +29,14 @@
/*************************************************************************/
#include "native_extension.h"
+#include "core/config/project_settings.h"
#include "core/io/config_file.h"
#include "core/object/class_db.h"
#include "core/object/method_bind.h"
#include "core/os/os.h"
+const char *NativeExtension::EXTENSION_LIST_CONFIG_FILE = "res://.godot/extension_list.cfg";
+
class NativeExtensionMethodBind : public MethodBind {
GDNativeExtensionClassMethodCall call_func;
GDNativeExtensionClassMethodPtrCall ptrcall_func;
@@ -68,8 +71,8 @@ public:
virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) {
Variant ret;
GDExtensionClassInstancePtr extension_instance = p_object->_get_extension_instance();
- GDNativeCallError ce;
- call_func(extension_instance, (const GDNativeVariantPtr *)p_args, p_arg_count, (GDNativeVariantPtr)&ret, &ce);
+ GDNativeCallError ce{ GDNATIVE_CALL_OK, 0, 0 };
+ call_func(method_userdata, extension_instance, (const GDNativeVariantPtr *)p_args, p_arg_count, (GDNativeVariantPtr)&ret, &ce);
r_error.error = Callable::CallError::Error(ce.error);
r_error.argument = ce.argument;
r_error.expected = ce.expected;
@@ -78,7 +81,7 @@ public:
virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) {
ERR_FAIL_COND_MSG(vararg, "Vararg methods don't have ptrcall support. This is most likely an engine bug.");
GDExtensionClassInstancePtr extension_instance = p_object->_get_extension_instance();
- ptrcall_func(extension_instance, (const GDNativeTypePtr *)p_args, (GDNativeTypePtr)r_ret);
+ ptrcall_func(method_userdata, extension_instance, (const GDNativeTypePtr *)p_args, (GDNativeTypePtr)r_ret);
}
virtual bool is_vararg() const {
@@ -91,6 +94,7 @@ public:
get_argument_type_func = p_method_info->get_argument_type_func;
get_argument_info_func = p_method_info->get_argument_info_func;
get_argument_metadata_func = p_method_info->get_argument_metadata_func;
+ set_name(p_method_info->name);
vararg = p_method_info->method_flags & GDNATIVE_EXTENSION_METHOD_FLAG_VARARG;
@@ -109,7 +113,7 @@ void NativeExtension::_register_extension_class(const GDNativeExtensionClassLibr
NativeExtension *self = (NativeExtension *)p_library;
StringName class_name = p_class_name;
- ERR_FAIL_COND_MSG(String(class_name).is_valid_identifier(), "Attempt to register extension clas '" + class_name + "', which is not a valid class identifier.");
+ ERR_FAIL_COND_MSG(!String(class_name).is_valid_identifier(), "Attempt to register extension class '" + class_name + "', which is not a valid class identifier.");
ERR_FAIL_COND_MSG(ClassDB::class_exists(class_name), "Attempt to register extension class '" + class_name + "', which appears to be already registered.");
Extension *parent_extension = nullptr;
@@ -150,7 +154,9 @@ void NativeExtension::_register_extension_class(const GDNativeExtensionClassLibr
extension->native_extension.unreference = p_extension_funcs->unreference_func;
extension->native_extension.class_userdata = p_extension_funcs->class_userdata;
extension->native_extension.create_instance = p_extension_funcs->create_instance_func;
+ extension->native_extension.set_object_instance = p_extension_funcs->object_instance_func;
extension->native_extension.free_instance = p_extension_funcs->free_instance_func;
+ extension->native_extension.get_virtual = p_extension_funcs->get_virtual_func;
ClassDB::register_extension_class(&extension->native_extension);
}
@@ -159,19 +165,20 @@ void NativeExtension::_register_extension_class_method(const GDNativeExtensionCl
StringName class_name = p_class_name;
StringName method_name = p_method_info->name;
- ERR_FAIL_COND_MSG(self->extension_classes.has(class_name), "Attempt to register extension method '" + String(method_name) + "' for unexisting class '" + class_name + "'.");
+ ERR_FAIL_COND_MSG(!self->extension_classes.has(class_name), "Attempt to register extension method '" + String(method_name) + "' for unexisting class '" + class_name + "'.");
//Extension *extension = &self->extension_classes[class_name];
NativeExtensionMethodBind *method = memnew(NativeExtensionMethodBind(p_method_info));
+ method->set_instance_class(class_name);
ClassDB::bind_method_custom(class_name, method);
}
-void NativeExtension::_register_extension_class_integer_constant(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_enum_name, const char *p_constant_name, uint32_t p_constant_value) {
+void NativeExtension::_register_extension_class_integer_constant(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_enum_name, const char *p_constant_name, GDNativeInt p_constant_value) {
NativeExtension *self = (NativeExtension *)p_library;
StringName class_name = p_class_name;
- ERR_FAIL_COND_MSG(self->extension_classes.has(class_name), "Attempt to register extension constant '" + String(p_constant_name) + "' for unexisting class '" + class_name + "'.");
+ ERR_FAIL_COND_MSG(!self->extension_classes.has(class_name), "Attempt to register extension constant '" + String(p_constant_name) + "' for unexisting class '" + class_name + "'.");
//Extension *extension = &self->extension_classes[class_name];
@@ -181,7 +188,7 @@ void NativeExtension::_register_extension_class_property(const GDNativeExtension
NativeExtension *self = (NativeExtension *)p_library;
StringName class_name = p_class_name;
- ERR_FAIL_COND_MSG(self->extension_classes.has(class_name), "Attempt to register extension class property '" + String(p_info->name) + "' for unexisting class '" + class_name + "'.");
+ ERR_FAIL_COND_MSG(!self->extension_classes.has(class_name), "Attempt to register extension class property '" + String(p_info->name) + "' for unexisting class '" + class_name + "'.");
//Extension *extension = &self->extension_classes[class_name];
PropertyInfo pinfo;
@@ -199,7 +206,7 @@ void NativeExtension::_register_extension_class_signal(const GDNativeExtensionCl
NativeExtension *self = (NativeExtension *)p_library;
StringName class_name = p_class_name;
- ERR_FAIL_COND_MSG(self->extension_classes.has(class_name), "Attempt to register extension class signal '" + String(p_signal_name) + "' for unexisting class '" + class_name + "'.");
+ ERR_FAIL_COND_MSG(!self->extension_classes.has(class_name), "Attempt to register extension class signal '" + String(p_signal_name) + "' for unexisting class '" + class_name + "'.");
MethodInfo s;
s.name = p_signal_name;
@@ -220,7 +227,7 @@ void NativeExtension::_unregister_extension_class(const GDNativeExtensionClassLi
NativeExtension *self = (NativeExtension *)p_library;
StringName class_name = p_class_name;
- ERR_FAIL_COND_MSG(self->extension_classes.has(class_name), "Attempt to unregister unexisting extension class '" + class_name + "'.");
+ ERR_FAIL_COND_MSG(!self->extension_classes.has(class_name), "Attempt to unregister unexisting extension class '" + class_name + "'.");
Extension *ext = &self->extension_classes[class_name];
ERR_FAIL_COND_MSG(ext->native_extension.children.size(), "Attempt to unregister class '" + class_name + "' while other extension classes inherit from it.");
@@ -368,7 +375,7 @@ RES NativeExtensionResourceLoader::load(const String &p_path, const String &p_or
}
}
- if (library_path != String()) {
+ if (library_path == String()) {
if (r_error) {
*r_error = ERR_FILE_NOT_FOUND;
}
@@ -381,7 +388,8 @@ RES NativeExtensionResourceLoader::load(const String &p_path, const String &p_or
Ref<NativeExtension> lib;
lib.instantiate();
- err = lib->open_library(library_path, entry_symbol);
+ String abs_path = ProjectSettings::get_singleton()->globalize_path(library_path);
+ err = lib->open_library(abs_path, entry_symbol);
if (r_error) {
*r_error = err;
diff --git a/core/extension/native_extension.h b/core/extension/native_extension.h
index 0a23848eb2..b661381d64 100644
--- a/core/extension/native_extension.h
+++ b/core/extension/native_extension.h
@@ -35,8 +35,8 @@
#include "core/io/resource_loader.h"
#include "core/object/ref_counted.h"
-class NativeExtension : public RefCounted {
- GDCLASS(NativeExtension, RefCounted)
+class NativeExtension : public Resource {
+ GDCLASS(NativeExtension, Resource)
void *library = nullptr; // pointer if valid,
@@ -48,7 +48,7 @@ class NativeExtension : public RefCounted {
static void _register_extension_class(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_parent_class_name, const GDNativeExtensionClassCreationInfo *p_extension_funcs);
static void _register_extension_class_method(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const GDNativeExtensionClassMethodInfo *p_method_info);
- static void _register_extension_class_integer_constant(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_enum_name, const char *p_constant_name, uint32_t p_constant_value);
+ static void _register_extension_class_integer_constant(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_enum_name, const char *p_constant_name, GDNativeInt p_constant_value);
static void _register_extension_class_property(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const GDNativePropertyInfo *p_info, const char *p_setter, const char *p_getter);
static void _register_extension_class_signal(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_signal_name, const GDNativePropertyInfo *p_argument_info, GDNativeInt p_argument_count);
static void _unregister_extension_class(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name);
@@ -60,6 +60,8 @@ protected:
static void _bind_methods();
public:
+ static const char *EXTENSION_LIST_CONFIG_FILE;
+
Error open_library(const String &p_path, const String &p_entry_symbol);
void close_library();
diff --git a/core/extension/native_extension_manager.cpp b/core/extension/native_extension_manager.cpp
index 7be2593845..8b7a9df4f1 100644
--- a/core/extension/native_extension_manager.cpp
+++ b/core/extension/native_extension_manager.cpp
@@ -29,6 +29,7 @@
/*************************************************************************/
#include "native_extension_manager.h"
+#include "core/io/file_access.h"
NativeExtensionManager::LoadStatus NativeExtensionManager::load_extension(const String &p_path) {
if (native_extension_map.has(p_path)) {
@@ -76,6 +77,11 @@ NativeExtensionManager::LoadStatus NativeExtensionManager::unload_extension(cons
native_extension_map.erase(p_path);
return LOAD_STATUS_OK;
}
+
+bool NativeExtensionManager::is_extension_loaded(const String &p_path) const {
+ return native_extension_map.has(p_path);
+}
+
Vector<String> NativeExtensionManager::get_loaded_extensions() const {
Vector<String> ret;
for (const Map<String, Ref<NativeExtension>>::Element *E = native_extension_map.front(); E; E = E->next()) {
@@ -105,6 +111,17 @@ void NativeExtensionManager::deinitialize_extensions(NativeExtension::Initializa
level = int32_t(p_level) - 1;
}
+void NativeExtensionManager::load_extensions() {
+ FileAccessRef f = FileAccess::open(NativeExtension::EXTENSION_LIST_CONFIG_FILE, FileAccess::READ);
+ while (f && !f->eof_reached()) {
+ String s = f->get_line().strip_edges();
+ if (s != String()) {
+ LoadStatus err = load_extension(s);
+ ERR_CONTINUE_MSG(err == LOAD_STATUS_FAILED, "Error loading extension: " + s);
+ }
+ }
+}
+
NativeExtensionManager *NativeExtensionManager::get_singleton() {
return singleton;
}
@@ -112,6 +129,8 @@ void NativeExtensionManager::_bind_methods() {
ClassDB::bind_method(D_METHOD("load_extension", "path"), &NativeExtensionManager::load_extension);
ClassDB::bind_method(D_METHOD("reload_extension", "path"), &NativeExtensionManager::reload_extension);
ClassDB::bind_method(D_METHOD("unload_extension", "path"), &NativeExtensionManager::unload_extension);
+ ClassDB::bind_method(D_METHOD("is_extension_loaded", "path"), &NativeExtensionManager::is_extension_loaded);
+
ClassDB::bind_method(D_METHOD("get_loaded_extensions"), &NativeExtensionManager::get_loaded_extensions);
ClassDB::bind_method(D_METHOD("get_extension", "path"), &NativeExtensionManager::get_extension);
diff --git a/core/extension/native_extension_manager.h b/core/extension/native_extension_manager.h
index 78465bd5cf..89ccd155fe 100644
--- a/core/extension/native_extension_manager.h
+++ b/core/extension/native_extension_manager.h
@@ -55,6 +55,7 @@ public:
LoadStatus load_extension(const String &p_path);
LoadStatus reload_extension(const String &p_path);
LoadStatus unload_extension(const String &p_path);
+ bool is_extension_loaded(const String &p_path) const;
Vector<String> get_loaded_extensions() const;
Ref<NativeExtension> get_extension(const String &p_path);
@@ -63,6 +64,8 @@ public:
static NativeExtensionManager *get_singleton();
+ void load_extensions();
+
NativeExtensionManager();
};