Create GDExtension clases for PhysicsServer3D

* Allows creating a GDExtension based 3D Physics Server (for Bullet, PhysX, etc. support)
* Some changes on native struct binding for PhysicsServer

This allows a 3D Physics server created entirely from GDExtension. Once it works, the idea is to port the 2D one to it.
This commit is contained in:
reduz 2022-03-14 15:52:03 +01:00
parent 41edfc88a3
commit 8b547331be
44 changed files with 2486 additions and 110 deletions

View file

@ -1606,7 +1606,7 @@ Variant ClassDB::class_get_default_property_value(const StringName &p_class, con
if (Engine::get_singleton()->has_singleton(p_class)) {
c = Engine::get_singleton()->get_singleton_object(p_class);
cleanup_c = false;
} else if (ClassDB::can_instantiate(p_class)) {
} else if (ClassDB::can_instantiate(p_class) && !ClassDB::is_virtual(p_class)) {
c = ClassDB::instantiate(p_class);
cleanup_c = true;
}
@ -1694,6 +1694,30 @@ void ClassDB::unregister_extension_class(const StringName &p_class) {
classes.erase(p_class);
}
Map<StringName, ClassDB::NativeStruct> ClassDB::native_structs;
void ClassDB::register_native_struct(const StringName &p_name, const String &p_code, uint64_t p_current_size) {
NativeStruct ns;
ns.ccode = p_code;
ns.struct_size = p_current_size;
native_structs[p_name] = ns;
}
void ClassDB::get_native_struct_list(List<StringName> *r_names) {
for (const KeyValue<StringName, NativeStruct> &E : native_structs) {
r_names->push_back(E.key);
}
}
String ClassDB::get_native_struct_code(const StringName &p_name) {
ERR_FAIL_COND_V(!native_structs.has(p_name), String());
return native_structs[p_name].ccode;
}
uint64_t ClassDB::get_native_struct_size(const StringName &p_name) {
ERR_FAIL_COND_V(!native_structs.has(p_name), 0);
return native_structs[p_name].struct_size;
}
RWLock ClassDB::lock;
void ClassDB::cleanup_defaults() {
@ -1717,6 +1741,7 @@ void ClassDB::cleanup() {
classes.clear();
resource_base_extensions.clear();
compat_classes.clear();
native_structs.clear();
}
//

View file

@ -144,6 +144,13 @@ public:
static HashMap<StringName, HashMap<StringName, Variant>> default_values;
static Set<StringName> default_values_cached;
// Native structs, used by binder
struct NativeStruct {
String ccode; // C code to create the native struct, fields separated by ; Arrays accepted (even containing other structs), also function pointers. All types must be Godot types.
uint64_t struct_size; // local size of struct, for comparison
};
static Map<StringName, NativeStruct> native_structs;
private:
// Non-locking variants of get_parent_class and is_parent_class.
static StringName _get_parent_class(const StringName &p_class);
@ -390,6 +397,11 @@ public:
static APIType get_current_api();
static void cleanup_defaults();
static void cleanup();
static void register_native_struct(const StringName &p_name, const String &p_code, uint64_t p_current_size);
static void get_native_struct_list(List<StringName> *r_names);
static String get_native_struct_code(const StringName &p_name);
static uint64_t get_native_struct_size(const StringName &p_name); // Used for asserting
};
#ifdef DEBUG_METHODS_ENABLED
@ -448,6 +460,8 @@ _FORCE_INLINE_ Vector<Error> errarray(P... p_args) {
::ClassDB::register_abstract_class<m_class>(); \
}
#define GDREGISTER_NATIVE_STRUCT(m_class, m_code) ClassDB::register_native_struct(#m_class, m_code, sizeof(m_class))
#include "core/disabled_classes.gen.h"
#endif // CLASS_DB_H

View file

@ -28,7 +28,8 @@ _FORCE_INLINE_ bool _gdvirtual_##m_name##_call($CALLARGS) $CONST { \\
}\\
\\
if (required) {\\
WARN_PRINT_ONCE("Required virtual method: "+get_class()+"::" + #m_name + " must be overriden before calling.");\\
ERR_PRINT_ONCE("Required virtual method: "+get_class()+"::" + #m_name + " must be overriden before calling.");\\
$RVOID\\
}\\
\\
return false;\\
@ -66,10 +67,12 @@ def generate_version(argcount, const=False, returns=False):
if returns:
sproto += "R"
s = s.replace("$RET", "m_ret, ")
s = s.replace("$RVOID", "(void)r_ret;") # If required, may lead to uninitialized errors
s = s.replace("$CALLPTRRETDEF", "PtrToArg<m_ret>::EncodeT ret;")
method_info += "\tmethod_info.return_val = GetTypeInfo<m_ret>::get_class_info();\\\n"
else:
s = s.replace("$RET", "")
s = s.replace("$RVOID", "")
s = s.replace("$CALLPTRRETDEF", "")
if const: