diff options
author | reduz <reduzio@gmail.com> | 2022-03-14 15:52:03 +0100 |
---|---|---|
committer | reduz <reduzio@gmail.com> | 2022-03-15 18:39:31 +0100 |
commit | 8b547331bec150b682fda94da1568fbcbda689ba (patch) | |
tree | 49159fd03ccc81cbfc2b4c6a70d1b7f1ac9cc5a1 /core | |
parent | 41edfc88a3f82e643ad3f4613de7a787a00ee68a (diff) |
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.
Diffstat (limited to 'core')
-rw-r--r-- | core/extension/extension_api_dump.cpp | 25 | ||||
-rw-r--r-- | core/extension/gdnative_interface.cpp | 6 | ||||
-rw-r--r-- | core/extension/gdnative_interface.h | 2 | ||||
-rw-r--r-- | core/object/class_db.cpp | 27 | ||||
-rw-r--r-- | core/object/class_db.h | 14 | ||||
-rw-r--r-- | core/object/make_virtuals.py | 5 | ||||
-rw-r--r-- | core/register_core_types.cpp | 2 | ||||
-rw-r--r-- | core/variant/binder_common.h | 4 | ||||
-rw-r--r-- | core/variant/native_ptr.h | 1 | ||||
-rw-r--r-- | core/variant/type_info.h | 34 |
10 files changed, 100 insertions, 20 deletions
diff --git a/core/extension/extension_api_dump.cpp b/core/extension/extension_api_dump.cpp index 3687e4f7e5..31af28b783 100644 --- a/core/extension/extension_api_dump.cpp +++ b/core/extension/extension_api_dump.cpp @@ -841,27 +841,16 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() { { Array native_structures; - // AudioStream structures - { - Dictionary d; - d["name"] = "AudioFrame"; - d["format"] = "float left,float right"; + List<StringName> native_structs; + ClassDB::get_native_struct_list(&native_structs); + native_structs.sort_custom<StringName::AlphCompare>(); - native_structures.push_back(d); - } + for (const StringName &E : native_structs) { + String code = ClassDB::get_native_struct_code(E); - // TextServer structures - { - Dictionary d; - d["name"] = "Glyph"; - d["format"] = "int start,int end,uint8_t count,uint8_t repeat,uint16_t flags,float x_off,float y_off,float advance,RID font_rid,int font_size,int32_t index"; - - native_structures.push_back(d); - } - { Dictionary d; - d["name"] = "CaretInfo"; - d["format"] = "Rect2 leading_caret,Rect2 trailing_caret,TextServer::Direction leading_direction,TextServer::Direction trailing_direction"; + d["name"] = String(E); + d["format"] = code; native_structures.push_back(d); } diff --git a/core/extension/gdnative_interface.cpp b/core/extension/gdnative_interface.cpp index d9ec42dc9d..d0461611ec 100644 --- a/core/extension/gdnative_interface.cpp +++ b/core/extension/gdnative_interface.cpp @@ -60,6 +60,10 @@ static void gdnative_print_script_error(const char *p_description, const char *p _err_print_error(p_function, p_file, p_line, p_description, false, ERR_HANDLER_SCRIPT); } +uint64_t gdnative_get_native_struct_size(const char *p_name) { + return ClassDB::get_native_struct_size(p_name); +} + // Variant functions static void gdnative_variant_new_copy(GDNativeVariantPtr r_dest, const GDNativeVariantPtr p_src) { @@ -902,6 +906,8 @@ void gdnative_setup_interface(GDNativeInterface *p_interface) { gdni.print_warning = gdnative_print_warning; gdni.print_script_error = gdnative_print_script_error; + gdni.get_native_struct_size = gdnative_get_native_struct_size; + /* GODOT VARIANT */ // variant general diff --git a/core/extension/gdnative_interface.h b/core/extension/gdnative_interface.h index 76e87eaf23..cc2957ec56 100644 --- a/core/extension/gdnative_interface.h +++ b/core/extension/gdnative_interface.h @@ -306,6 +306,8 @@ typedef struct { void (*print_warning)(const char *p_description, const char *p_function, const char *p_file, int32_t p_line); void (*print_script_error)(const char *p_description, const char *p_function, const char *p_file, int32_t p_line); + uint64_t (*get_native_struct_size)(const char *p_name); + /* GODOT VARIANT */ /* variant general */ diff --git a/core/object/class_db.cpp b/core/object/class_db.cpp index 08e12dfcaa..e09c6cb97c 100644 --- a/core/object/class_db.cpp +++ b/core/object/class_db.cpp @@ -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(); } // diff --git a/core/object/class_db.h b/core/object/class_db.h index 580ae3582f..32e4bf7644 100644 --- a/core/object/class_db.h +++ b/core/object/class_db.h @@ -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 diff --git a/core/object/make_virtuals.py b/core/object/make_virtuals.py index 2e909b8042..64ee5940b0 100644 --- a/core/object/make_virtuals.py +++ b/core/object/make_virtuals.py @@ -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: diff --git a/core/register_core_types.cpp b/core/register_core_types.cpp index 2aa47c6c96..d05280f6a5 100644 --- a/core/register_core_types.cpp +++ b/core/register_core_types.cpp @@ -261,6 +261,8 @@ void register_core_types() { _classdb = memnew(core_bind::special::ClassDB); _marshalls = memnew(core_bind::Marshalls); _engine_debugger = memnew(core_bind::EngineDebugger); + + GDREGISTER_NATIVE_STRUCT(AudioFrame, "float left;float right"); } void register_core_settings() { diff --git a/core/variant/binder_common.h b/core/variant/binder_common.h index f31191e8a3..22a13b0fab 100644 --- a/core/variant/binder_common.h +++ b/core/variant/binder_common.h @@ -100,6 +100,10 @@ struct VariantCaster<const T &> { _FORCE_INLINE_ static void encode(m_enum p_val, const void *p_ptr) { \ *(int64_t *)p_ptr = (int64_t)p_val; \ } \ + }; \ + template <> \ + struct ZeroInitializer<m_enum> { \ + static void initialize(m_enum &value) { value = (m_enum)0; } \ }; // Object enum casts must go here diff --git a/core/variant/native_ptr.h b/core/variant/native_ptr.h index 8e9fbbc0a4..ed68e0f6c9 100644 --- a/core/variant/native_ptr.h +++ b/core/variant/native_ptr.h @@ -124,6 +124,7 @@ struct PtrToArg<GDNativePtr<T>> { } }; +GDVIRTUAL_NATIVE_PTR(void) GDVIRTUAL_NATIVE_PTR(AudioFrame) GDVIRTUAL_NATIVE_PTR(bool) GDVIRTUAL_NATIVE_PTR(char) diff --git a/core/variant/type_info.h b/core/variant/type_info.h index ee050cff4f..bacd0d19ce 100644 --- a/core/variant/type_info.h +++ b/core/variant/type_info.h @@ -281,4 +281,38 @@ inline StringName __constant_get_enum_name(T param, const String &p_constant) { #define CLASS_INFO(m_type) (GetTypeInfo<m_type *>::get_class_info()) +template <typename T> +struct ZeroInitializer { + static void initialize(T &value) {} //no initialization by default +}; + +template <> +struct ZeroInitializer<bool> { + static void initialize(bool &value) { value = false; } +}; + +template <typename T> +struct ZeroInitializer<T *> { + static void initialize(T *&value) { value = nullptr; } +}; + +#define ZERO_INITIALIZER_NUMBER(m_type) \ + template <> \ + struct ZeroInitializer<m_type> { \ + static void initialize(m_type &value) { value = 0; } \ + }; + +ZERO_INITIALIZER_NUMBER(uint8_t) +ZERO_INITIALIZER_NUMBER(int8_t) +ZERO_INITIALIZER_NUMBER(uint16_t) +ZERO_INITIALIZER_NUMBER(int16_t) +ZERO_INITIALIZER_NUMBER(uint32_t) +ZERO_INITIALIZER_NUMBER(int32_t) +ZERO_INITIALIZER_NUMBER(uint64_t) +ZERO_INITIALIZER_NUMBER(int64_t) +ZERO_INITIALIZER_NUMBER(char16_t) +ZERO_INITIALIZER_NUMBER(char32_t) +ZERO_INITIALIZER_NUMBER(float) +ZERO_INITIALIZER_NUMBER(double) + #endif // TYPE_INFO_H |