diff options
105 files changed, 2032 insertions, 1532 deletions
diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp index cb82dc7f8f..6df8dd380a 100644 --- a/core/bind/core_bind.cpp +++ b/core/bind/core_bind.cpp @@ -1619,12 +1619,17 @@ Error _Directory::open(const String &p_path) { memdelete(d); } d = alt; + dir_open = true; return OK; } +bool _Directory::is_open() const { + return d && dir_open; +} + Error _Directory::list_dir_begin(bool p_skip_navigational, bool p_skip_hidden) { - ERR_FAIL_COND_V_MSG(!d, ERR_UNCONFIGURED, "Directory must be opened before use."); + ERR_FAIL_COND_V_MSG(!is_open(), ERR_UNCONFIGURED, "Directory must be opened before use."); _list_skip_navigational = p_skip_navigational; _list_skip_hidden = p_skip_hidden; @@ -1633,7 +1638,7 @@ Error _Directory::list_dir_begin(bool p_skip_navigational, bool p_skip_hidden) { } String _Directory::get_next() { - ERR_FAIL_COND_V_MSG(!d, "", "Directory must be opened before use."); + ERR_FAIL_COND_V_MSG(!is_open(), "", "Directory must be opened before use."); String next = d->get_next(); while (next != "" && ((_list_skip_navigational && (next == "." || next == "..")) || (_list_skip_hidden && d->current_is_hidden()))) { @@ -1643,42 +1648,42 @@ String _Directory::get_next() { } bool _Directory::current_is_dir() const { - ERR_FAIL_COND_V_MSG(!d, false, "Directory must be opened before use."); + ERR_FAIL_COND_V_MSG(!is_open(), false, "Directory must be opened before use."); return d->current_is_dir(); } void _Directory::list_dir_end() { - ERR_FAIL_COND_MSG(!d, "Directory must be opened before use."); + ERR_FAIL_COND_MSG(!is_open(), "Directory must be opened before use."); d->list_dir_end(); } int _Directory::get_drive_count() { - ERR_FAIL_COND_V_MSG(!d, 0, "Directory must be opened before use."); + ERR_FAIL_COND_V_MSG(!is_open(), 0, "Directory must be opened before use."); return d->get_drive_count(); } String _Directory::get_drive(int p_drive) { - ERR_FAIL_COND_V_MSG(!d, "", "Directory must be opened before use."); + ERR_FAIL_COND_V_MSG(!is_open(), "", "Directory must be opened before use."); return d->get_drive(p_drive); } int _Directory::get_current_drive() { - ERR_FAIL_COND_V_MSG(!d, 0, "Directory must be opened before use."); + ERR_FAIL_COND_V_MSG(!is_open(), 0, "Directory must be opened before use."); return d->get_current_drive(); } Error _Directory::change_dir(String p_dir) { - ERR_FAIL_COND_V_MSG(!d, ERR_UNCONFIGURED, "Directory must be opened before use."); + ERR_FAIL_COND_V_MSG(!is_open(), ERR_UNCONFIGURED, "Directory must be opened before use."); return d->change_dir(p_dir); } String _Directory::get_current_dir() { - ERR_FAIL_COND_V_MSG(!d, "", "Directory must be opened before use."); + ERR_FAIL_COND_V_MSG(!is_open(), "", "Directory must be opened before use."); return d->get_current_dir(); } Error _Directory::make_dir(String p_dir) { - ERR_FAIL_COND_V_MSG(!d, ERR_UNCONFIGURED, "Directory must be opened before use."); + ERR_FAIL_COND_V_MSG(!is_open(), ERR_UNCONFIGURED, "Directory must be opened before use."); if (!p_dir.is_rel_path()) { DirAccess *d = DirAccess::create_for_path(p_dir); Error err = d->make_dir(p_dir); @@ -1689,7 +1694,7 @@ Error _Directory::make_dir(String p_dir) { } Error _Directory::make_dir_recursive(String p_dir) { - ERR_FAIL_COND_V_MSG(!d, ERR_UNCONFIGURED, "Directory must be opened before use."); + ERR_FAIL_COND_V_MSG(!is_open(), ERR_UNCONFIGURED, "Directory must be opened before use."); if (!p_dir.is_rel_path()) { DirAccess *d = DirAccess::create_for_path(p_dir); Error err = d->make_dir_recursive(p_dir); @@ -1700,7 +1705,7 @@ Error _Directory::make_dir_recursive(String p_dir) { } bool _Directory::file_exists(String p_file) { - ERR_FAIL_COND_V_MSG(!d, false, "Directory must be opened before use."); + ERR_FAIL_COND_V_MSG(!is_open(), false, "Directory must be opened before use."); if (!p_file.is_rel_path()) { return FileAccess::exists(p_file); @@ -1710,7 +1715,7 @@ bool _Directory::file_exists(String p_file) { } bool _Directory::dir_exists(String p_dir) { - ERR_FAIL_COND_V_MSG(!d, false, "Directory must be opened before use."); + ERR_FAIL_COND_V_MSG(!is_open(), false, "Directory must be opened before use."); if (!p_dir.is_rel_path()) { DirAccess *d = DirAccess::create_for_path(p_dir); bool exists = d->dir_exists(p_dir); @@ -1723,17 +1728,17 @@ bool _Directory::dir_exists(String p_dir) { } int _Directory::get_space_left() { - ERR_FAIL_COND_V_MSG(!d, 0, "Directory must be opened before use."); + ERR_FAIL_COND_V_MSG(!is_open(), 0, "Directory must be opened before use."); return d->get_space_left() / 1024 * 1024; //return value in megabytes, given binding is int } Error _Directory::copy(String p_from, String p_to) { - ERR_FAIL_COND_V_MSG(!d, ERR_UNCONFIGURED, "Directory must be opened before use."); + ERR_FAIL_COND_V_MSG(!is_open(), ERR_UNCONFIGURED, "Directory must be opened before use."); return d->copy(p_from, p_to); } Error _Directory::rename(String p_from, String p_to) { - ERR_FAIL_COND_V_MSG(!d, ERR_UNCONFIGURED, "Directory must be opened before use."); + ERR_FAIL_COND_V_MSG(!is_open(), ERR_UNCONFIGURED, "Directory must be opened before use."); if (!p_from.is_rel_path()) { DirAccess *d = DirAccess::create_for_path(p_from); Error err = d->rename(p_from, p_to); @@ -1745,7 +1750,7 @@ Error _Directory::rename(String p_from, String p_to) { } Error _Directory::remove(String p_name) { - ERR_FAIL_COND_V_MSG(!d, ERR_UNCONFIGURED, "Directory must be opened before use."); + ERR_FAIL_COND_V_MSG(!is_open(), ERR_UNCONFIGURED, "Directory must be opened before use."); if (!p_name.is_rel_path()) { DirAccess *d = DirAccess::create_for_path(p_name); Error err = d->remove(p_name); diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h index f9f5a4e7d7..a1fedf1bb8 100644 --- a/core/bind/core_bind.h +++ b/core/bind/core_bind.h @@ -457,6 +457,7 @@ VARIANT_ENUM_CAST(_File::CompressionMode); class _Directory : public Reference { GDCLASS(_Directory, Reference); DirAccess *d; + bool dir_open = false; protected: static void _bind_methods(); @@ -464,6 +465,8 @@ protected: public: Error open(const String &p_path); + bool is_open() const; + Error list_dir_begin(bool p_skip_navigational = false, bool p_skip_hidden = false); // This starts dir listing. String get_next(); bool current_is_dir() const; diff --git a/core/error_macros.h b/core/error_macros.h index d7366be453..6353961b04 100644 --- a/core/error_macros.h +++ b/core/error_macros.h @@ -476,7 +476,7 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li * The current function returns. */ #define ERR_FAIL() \ - if (1) { \ + if (true) { \ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Method/function failed."); \ return; \ } else \ @@ -489,7 +489,7 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li * Prints `m_msg`, and the current function returns. */ #define ERR_FAIL_MSG(m_msg) \ - if (1) { \ + if (true) { \ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Method/function failed.", DEBUG_STR(m_msg)); \ return; \ } else \ @@ -503,7 +503,7 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li * The current function returns `m_retval`. */ #define ERR_FAIL_V(m_retval) \ - if (1) { \ + if (true) { \ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Method/function failed. Returning: " _STR(m_retval)); \ return m_retval; \ } else \ @@ -516,7 +516,7 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li * Prints `m_msg`, and the current function returns `m_retval`. */ #define ERR_FAIL_V_MSG(m_retval, m_msg) \ - if (1) { \ + if (true) { \ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Method/function failed. Returning: " _STR(m_retval), DEBUG_STR(m_msg)); \ return m_retval; \ } else \ @@ -536,7 +536,7 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li * Prints `m_msg` once during the application lifetime. */ #define ERR_PRINT_ONCE(m_msg) \ - if (1) { \ + if (true) { \ static bool first_print = true; \ if (first_print) { \ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_msg); \ @@ -561,7 +561,7 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li * If warning about deprecated usage, use `WARN_DEPRECATED` or `WARN_DEPRECATED_MSG` instead. */ #define WARN_PRINT_ONCE(m_msg) \ - if (1) { \ + if (true) { \ static bool first_print = true; \ if (first_print) { \ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_msg, ERR_HANDLER_WARNING); \ @@ -576,7 +576,7 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li * Warns that the current function is deprecated. */ #define WARN_DEPRECATED \ - if (1) { \ + if (true) { \ static volatile bool warning_shown = false; \ if (!warning_shown) { \ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "This method has been deprecated and will be removed in the future.", ERR_HANDLER_WARNING); \ @@ -589,7 +589,7 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li * Warns that the current function is deprecated and prints `m_msg`. */ #define WARN_DEPRECATED_MSG(m_msg) \ - if (1) { \ + if (true) { \ static volatile bool warning_shown = false; \ if (!warning_shown) { \ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "This method has been deprecated and will be removed in the future.", DEBUG_STR(m_msg), ERR_HANDLER_WARNING); \ @@ -605,7 +605,7 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li * The application crashes. */ #define CRASH_NOW() \ - if (1) { \ + if (true) { \ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "FATAL: Method/function failed."); \ GENERATE_TRAP(); \ } else \ @@ -617,7 +617,7 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li * Prints `m_msg`, and then the application crashes. */ #define CRASH_NOW_MSG(m_msg) \ - if (1) { \ + if (true) { \ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "FATAL: Method/function failed.", DEBUG_STR(m_msg)); \ GENERATE_TRAP(); \ } else \ diff --git a/core/project_settings.cpp b/core/project_settings.cpp index 7e96735d67..3f9585c03c 100644 --- a/core/project_settings.cpp +++ b/core/project_settings.cpp @@ -144,6 +144,12 @@ bool ProjectSettings::_set(const StringName &p_name, const Variant &p_value) { if (p_value.get_type() == Variant::NIL) { props.erase(p_name); + if (p_name.operator String().begins_with("autoload/")) { + String node_name = p_name.operator String().split("/")[1]; + if (autoloads.has(node_name)) { + remove_autoload(node_name); + } + } } else { if (p_name == CoreStringNames::get_singleton()->_custom_features) { Vector<String> custom_feature_array = String(p_value).split(","); @@ -181,6 +187,19 @@ bool ProjectSettings::_set(const StringName &p_name, const Variant &p_value) { } else { props[p_name] = VariantContainer(p_value, last_order++); } + if (p_name.operator String().begins_with("autoload/")) { + String node_name = p_name.operator String().split("/")[1]; + AutoloadInfo autoload; + autoload.name = node_name; + String path = p_value; + if (path.begins_with("*")) { + autoload.is_singleton = true; + autoload.path = path.substr(1); + } else { + autoload.path = path; + } + add_autoload(autoload); + } } return true; @@ -945,6 +964,29 @@ bool ProjectSettings::has_custom_feature(const String &p_feature) const { return custom_features.has(p_feature); } +Map<StringName, ProjectSettings::AutoloadInfo> ProjectSettings::get_autoload_list() const { + return autoloads; +} + +void ProjectSettings::add_autoload(const AutoloadInfo &p_autoload) { + ERR_FAIL_COND_MSG(p_autoload.name == StringName(), "Trying to add autoload with no name."); + autoloads[p_autoload.name] = p_autoload; +} + +void ProjectSettings::remove_autoload(const StringName &p_autoload) { + ERR_FAIL_COND_MSG(!autoloads.has(p_autoload), "Trying to remove non-existent autoload."); + autoloads.erase(p_autoload); +} + +bool ProjectSettings::has_autoload(const StringName &p_autoload) const { + return autoloads.has(p_autoload); +} + +ProjectSettings::AutoloadInfo ProjectSettings::get_autoload(const StringName &p_name) const { + ERR_FAIL_COND_V_MSG(!autoloads.has(p_name), AutoloadInfo(), "Trying to get non-existent autoload."); + return autoloads[p_name]; +} + void ProjectSettings::_bind_methods() { ClassDB::bind_method(D_METHOD("has_setting", "name"), &ProjectSettings::has_setting); ClassDB::bind_method(D_METHOD("set_setting", "name", "value"), &ProjectSettings::set_setting); diff --git a/core/project_settings.h b/core/project_settings.h index 3ed80738a1..4aceafe3c0 100644 --- a/core/project_settings.h +++ b/core/project_settings.h @@ -47,6 +47,12 @@ public: NO_BUILTIN_ORDER_BASE = 1 << 16 }; + struct AutoloadInfo { + StringName name; + String path; + bool is_singleton = false; + }; + protected: struct VariantContainer { int order = 0; @@ -79,6 +85,8 @@ protected: Set<String> custom_features; Map<StringName, StringName> feature_overrides; + Map<StringName, AutoloadInfo> autoloads; + bool _set(const StringName &p_name, const Variant &p_value); bool _get(const StringName &p_name, Variant &r_ret) const; void _get_property_list(List<PropertyInfo> *p_list) const; @@ -148,6 +156,12 @@ public: bool has_custom_feature(const String &p_feature) const; + Map<StringName, AutoloadInfo> get_autoload_list() const; + void add_autoload(const AutoloadInfo &p_autoload); + void remove_autoload(const StringName &p_autoload); + bool has_autoload(const StringName &p_autoload) const; + AutoloadInfo get_autoload(const StringName &p_name) const; + ProjectSettings(); ~ProjectSettings(); }; diff --git a/core/variant_call.cpp b/core/variant_call.cpp index 308fa3c407..0aa1339401 100644 --- a/core/variant_call.cpp +++ b/core/variant_call.cpp @@ -701,6 +701,8 @@ struct _VariantCall { VCALL_PARRMEM1(PackedByteArray, uint8_t, remove); VCALL_PARRMEM1(PackedByteArray, uint8_t, append); VCALL_PARRMEM1(PackedByteArray, uint8_t, append_array); + VCALL_PARRMEM1R(PackedByteArray, uint8_t, has); + VCALL_PARRMEM0(PackedByteArray, uint8_t, sort); VCALL_PARRMEM0(PackedByteArray, uint8_t, invert); VCALL_PARRMEM2R(PackedByteArray, uint8_t, subarray); @@ -714,6 +716,8 @@ struct _VariantCall { VCALL_PARRMEM1(PackedInt32Array, int32_t, remove); VCALL_PARRMEM1(PackedInt32Array, int32_t, append); VCALL_PARRMEM1(PackedInt32Array, int32_t, append_array); + VCALL_PARRMEM1R(PackedInt32Array, int32_t, has); + VCALL_PARRMEM0(PackedInt32Array, int32_t, sort); VCALL_PARRMEM0(PackedInt32Array, int32_t, invert); VCALL_PARRMEM0R(PackedInt64Array, int64_t, size); @@ -726,6 +730,8 @@ struct _VariantCall { VCALL_PARRMEM1(PackedInt64Array, int64_t, remove); VCALL_PARRMEM1(PackedInt64Array, int64_t, append); VCALL_PARRMEM1(PackedInt64Array, int64_t, append_array); + VCALL_PARRMEM1R(PackedInt64Array, int64_t, has); + VCALL_PARRMEM0(PackedInt64Array, int64_t, sort); VCALL_PARRMEM0(PackedInt64Array, int64_t, invert); VCALL_PARRMEM0R(PackedFloat32Array, float, size); @@ -738,6 +744,8 @@ struct _VariantCall { VCALL_PARRMEM1(PackedFloat32Array, float, remove); VCALL_PARRMEM1(PackedFloat32Array, float, append); VCALL_PARRMEM1(PackedFloat32Array, float, append_array); + VCALL_PARRMEM1R(PackedFloat32Array, float, has); + VCALL_PARRMEM0(PackedFloat32Array, float, sort); VCALL_PARRMEM0(PackedFloat32Array, float, invert); VCALL_PARRMEM0R(PackedFloat64Array, double, size); @@ -750,6 +758,8 @@ struct _VariantCall { VCALL_PARRMEM1(PackedFloat64Array, double, remove); VCALL_PARRMEM1(PackedFloat64Array, double, append); VCALL_PARRMEM1(PackedFloat64Array, double, append_array); + VCALL_PARRMEM1R(PackedFloat64Array, double, has); + VCALL_PARRMEM0(PackedFloat64Array, double, sort); VCALL_PARRMEM0(PackedFloat64Array, double, invert); VCALL_PARRMEM0R(PackedStringArray, String, size); @@ -762,6 +772,8 @@ struct _VariantCall { VCALL_PARRMEM1(PackedStringArray, String, remove); VCALL_PARRMEM1(PackedStringArray, String, append); VCALL_PARRMEM1(PackedStringArray, String, append_array); + VCALL_PARRMEM1R(PackedStringArray, String, has); + VCALL_PARRMEM0(PackedStringArray, String, sort); VCALL_PARRMEM0(PackedStringArray, String, invert); VCALL_PARRMEM0R(PackedVector2Array, Vector2, size); @@ -774,6 +786,8 @@ struct _VariantCall { VCALL_PARRMEM1(PackedVector2Array, Vector2, remove); VCALL_PARRMEM1(PackedVector2Array, Vector2, append); VCALL_PARRMEM1(PackedVector2Array, Vector2, append_array); + VCALL_PARRMEM1R(PackedVector2Array, Vector2, has); + VCALL_PARRMEM0(PackedVector2Array, Vector2, sort); VCALL_PARRMEM0(PackedVector2Array, Vector2, invert); VCALL_PARRMEM0R(PackedVector3Array, Vector3, size); @@ -786,6 +800,8 @@ struct _VariantCall { VCALL_PARRMEM1(PackedVector3Array, Vector3, remove); VCALL_PARRMEM1(PackedVector3Array, Vector3, append); VCALL_PARRMEM1(PackedVector3Array, Vector3, append_array); + VCALL_PARRMEM1R(PackedVector3Array, Vector3, has); + VCALL_PARRMEM0(PackedVector3Array, Vector3, sort); VCALL_PARRMEM0(PackedVector3Array, Vector3, invert); VCALL_PARRMEM0R(PackedColorArray, Color, size); @@ -798,6 +814,8 @@ struct _VariantCall { VCALL_PARRMEM1(PackedColorArray, Color, remove); VCALL_PARRMEM1(PackedColorArray, Color, append); VCALL_PARRMEM1(PackedColorArray, Color, append_array); + VCALL_PARRMEM1R(PackedColorArray, Color, has); + VCALL_PARRMEM0(PackedColorArray, Color, sort); VCALL_PARRMEM0(PackedColorArray, Color, invert); #define VCALL_PTR0(m_type, m_method) \ @@ -2085,6 +2103,8 @@ void register_variant_methods() { ADDFUNC1(PACKED_BYTE_ARRAY, NIL, PackedByteArray, remove, INT, "idx", varray()); ADDFUNC2R(PACKED_BYTE_ARRAY, INT, PackedByteArray, insert, INT, "idx", INT, "byte", varray()); ADDFUNC1(PACKED_BYTE_ARRAY, NIL, PackedByteArray, resize, INT, "idx", varray()); + ADDFUNC1R(PACKED_BYTE_ARRAY, BOOL, PackedByteArray, has, INT, "value", varray()); + ADDFUNC0(PACKED_BYTE_ARRAY, NIL, PackedByteArray, sort, varray()); ADDFUNC0(PACKED_BYTE_ARRAY, NIL, PackedByteArray, invert, varray()); ADDFUNC2R(PACKED_BYTE_ARRAY, PACKED_BYTE_ARRAY, PackedByteArray, subarray, INT, "from", INT, "to", varray()); @@ -2103,6 +2123,8 @@ void register_variant_methods() { ADDFUNC1(PACKED_INT32_ARRAY, NIL, PackedInt32Array, remove, INT, "idx", varray()); ADDFUNC2R(PACKED_INT32_ARRAY, INT, PackedInt32Array, insert, INT, "idx", INT, "integer", varray()); ADDFUNC1(PACKED_INT32_ARRAY, NIL, PackedInt32Array, resize, INT, "idx", varray()); + ADDFUNC1R(PACKED_INT32_ARRAY, BOOL, PackedInt32Array, has, INT, "value", varray()); + ADDFUNC0(PACKED_INT32_ARRAY, NIL, PackedInt32Array, sort, varray()); ADDFUNC0(PACKED_INT32_ARRAY, NIL, PackedInt32Array, invert, varray()); ADDFUNC0R(PACKED_INT64_ARRAY, INT, PackedInt64Array, size, varray()); @@ -2114,6 +2136,8 @@ void register_variant_methods() { ADDFUNC1(PACKED_INT64_ARRAY, NIL, PackedInt64Array, remove, INT, "idx", varray()); ADDFUNC2R(PACKED_INT64_ARRAY, INT, PackedInt64Array, insert, INT, "idx", INT, "integer", varray()); ADDFUNC1(PACKED_INT64_ARRAY, NIL, PackedInt64Array, resize, INT, "idx", varray()); + ADDFUNC1R(PACKED_INT64_ARRAY, BOOL, PackedInt64Array, has, INT, "value", varray()); + ADDFUNC0(PACKED_INT64_ARRAY, NIL, PackedInt64Array, sort, varray()); ADDFUNC0(PACKED_INT64_ARRAY, NIL, PackedInt64Array, invert, varray()); ADDFUNC0R(PACKED_FLOAT32_ARRAY, INT, PackedFloat32Array, size, varray()); @@ -2125,6 +2149,8 @@ void register_variant_methods() { ADDFUNC1(PACKED_FLOAT32_ARRAY, NIL, PackedFloat32Array, remove, INT, "idx", varray()); ADDFUNC2R(PACKED_FLOAT32_ARRAY, INT, PackedFloat32Array, insert, INT, "idx", FLOAT, "value", varray()); ADDFUNC1(PACKED_FLOAT32_ARRAY, NIL, PackedFloat32Array, resize, INT, "idx", varray()); + ADDFUNC1R(PACKED_FLOAT32_ARRAY, BOOL, PackedFloat32Array, has, FLOAT, "value", varray()); + ADDFUNC0(PACKED_FLOAT32_ARRAY, NIL, PackedFloat32Array, sort, varray()); ADDFUNC0(PACKED_FLOAT32_ARRAY, NIL, PackedFloat32Array, invert, varray()); ADDFUNC0R(PACKED_FLOAT64_ARRAY, INT, PackedFloat64Array, size, varray()); @@ -2136,6 +2162,8 @@ void register_variant_methods() { ADDFUNC1(PACKED_FLOAT64_ARRAY, NIL, PackedFloat64Array, remove, INT, "idx", varray()); ADDFUNC2R(PACKED_FLOAT64_ARRAY, INT, PackedFloat64Array, insert, INT, "idx", FLOAT, "value", varray()); ADDFUNC1(PACKED_FLOAT64_ARRAY, NIL, PackedFloat64Array, resize, INT, "idx", varray()); + ADDFUNC1R(PACKED_FLOAT64_ARRAY, BOOL, PackedFloat64Array, has, FLOAT, "value", varray()); + ADDFUNC0(PACKED_FLOAT64_ARRAY, NIL, PackedFloat64Array, sort, varray()); ADDFUNC0(PACKED_FLOAT64_ARRAY, NIL, PackedFloat64Array, invert, varray()); ADDFUNC0R(PACKED_STRING_ARRAY, INT, PackedStringArray, size, varray()); @@ -2147,6 +2175,8 @@ void register_variant_methods() { ADDFUNC1(PACKED_STRING_ARRAY, NIL, PackedStringArray, remove, INT, "idx", varray()); ADDFUNC2R(PACKED_STRING_ARRAY, INT, PackedStringArray, insert, INT, "idx", STRING, "string", varray()); ADDFUNC1(PACKED_STRING_ARRAY, NIL, PackedStringArray, resize, INT, "idx", varray()); + ADDFUNC1R(PACKED_STRING_ARRAY, BOOL, PackedStringArray, has, STRING, "value", varray()); + ADDFUNC0(PACKED_STRING_ARRAY, NIL, PackedStringArray, sort, varray()); ADDFUNC0(PACKED_STRING_ARRAY, NIL, PackedStringArray, invert, varray()); ADDFUNC0R(PACKED_VECTOR2_ARRAY, INT, PackedVector2Array, size, varray()); @@ -2158,6 +2188,8 @@ void register_variant_methods() { ADDFUNC1(PACKED_VECTOR2_ARRAY, NIL, PackedVector2Array, remove, INT, "idx", varray()); ADDFUNC2R(PACKED_VECTOR2_ARRAY, INT, PackedVector2Array, insert, INT, "idx", VECTOR2, "vector2", varray()); ADDFUNC1(PACKED_VECTOR2_ARRAY, NIL, PackedVector2Array, resize, INT, "idx", varray()); + ADDFUNC1R(PACKED_VECTOR2_ARRAY, BOOL, PackedVector2Array, has, VECTOR2, "value", varray()); + ADDFUNC0(PACKED_VECTOR2_ARRAY, NIL, PackedVector2Array, sort, varray()); ADDFUNC0(PACKED_VECTOR2_ARRAY, NIL, PackedVector2Array, invert, varray()); ADDFUNC0R(PACKED_VECTOR3_ARRAY, INT, PackedVector3Array, size, varray()); @@ -2169,6 +2201,8 @@ void register_variant_methods() { ADDFUNC1(PACKED_VECTOR3_ARRAY, NIL, PackedVector3Array, remove, INT, "idx", varray()); ADDFUNC2R(PACKED_VECTOR3_ARRAY, INT, PackedVector3Array, insert, INT, "idx", VECTOR3, "vector3", varray()); ADDFUNC1(PACKED_VECTOR3_ARRAY, NIL, PackedVector3Array, resize, INT, "idx", varray()); + ADDFUNC1R(PACKED_VECTOR3_ARRAY, BOOL, PackedVector3Array, has, VECTOR3, "value", varray()); + ADDFUNC0(PACKED_VECTOR3_ARRAY, NIL, PackedVector3Array, sort, varray()); ADDFUNC0(PACKED_VECTOR3_ARRAY, NIL, PackedVector3Array, invert, varray()); ADDFUNC0R(PACKED_COLOR_ARRAY, INT, PackedColorArray, size, varray()); @@ -2180,6 +2214,8 @@ void register_variant_methods() { ADDFUNC1(PACKED_COLOR_ARRAY, NIL, PackedColorArray, remove, INT, "idx", varray()); ADDFUNC2R(PACKED_COLOR_ARRAY, INT, PackedColorArray, insert, INT, "idx", COLOR, "color", varray()); ADDFUNC1(PACKED_COLOR_ARRAY, NIL, PackedColorArray, resize, INT, "idx", varray()); + ADDFUNC1R(PACKED_COLOR_ARRAY, BOOL, PackedColorArray, has, COLOR, "value", varray()); + ADDFUNC0(PACKED_COLOR_ARRAY, NIL, PackedColorArray, sort, varray()); ADDFUNC0(PACKED_COLOR_ARRAY, NIL, PackedColorArray, invert, varray()); //pointerbased diff --git a/core/vector.h b/core/vector.h index 4c152fb084..5fb630c21c 100644 --- a/core/vector.h +++ b/core/vector.h @@ -92,6 +92,10 @@ public: void append_array(Vector<T> p_other); + bool has(const T &p_val) { + return find(p_val, 0) != -1; + } + template <class C> void sort_custom() { int len = _cowdata.size(); diff --git a/doc/classes/EditorInterface.xml b/doc/classes/EditorInterface.xml index c2c73a8b83..1d877e632e 100644 --- a/doc/classes/EditorInterface.xml +++ b/doc/classes/EditorInterface.xml @@ -72,6 +72,13 @@ Returns an [Array] with the file paths of the currently opened scenes. </description> </method> + <method name="get_playing_scene" qualifiers="const"> + <return type="String"> + </return> + <description> + Returns the name of the scene that is being played. If no scene is currently being played, returns an empty string. + </description> + </method> <method name="get_resource_filesystem"> <return type="EditorFileSystem"> </return> @@ -117,6 +124,13 @@ Shows the given property on the given [code]object[/code] in the Editor's Inspector dock. </description> </method> + <method name="is_playing_scene" qualifiers="const"> + <return type="bool"> + </return> + <description> + Returns [code]true[/code], if a scene is currently being played; [code]false[/code] otherwise. Paused scenes are considered as being played. + </description> + </method> <method name="is_plugin_enabled" qualifiers="const"> <return type="bool"> </return> @@ -146,6 +160,29 @@ Opens the scene at the given path. </description> </method> + <method name="play_current_scene"> + <return type="void"> + </return> + <description> + Plays the currently active scene. + </description> + </method> + <method name="play_custom_scene"> + <return type="void"> + </return> + <argument index="0" name="scene_filepath" type="String"> + </argument> + <description> + Plays the scene specified by its filepath. + </description> + </method> + <method name="play_main_scene"> + <return type="void"> + </return> + <description> + Plays the main scene. + </description> + </method> <method name="reload_scene_from_path"> <return type="void"> </return> @@ -201,6 +238,13 @@ Sets the enabled status of a plugin. The plugin name is the same as its directory name. </description> </method> + <method name="stop_playing_scene"> + <return type="void"> + </return> + <description> + Stops the scene that is currently playing. + </description> + </method> </methods> <members> <member name="distraction_free_mode" type="bool" setter="set_distraction_free_mode" getter="is_distraction_free_mode_enabled"> diff --git a/doc/classes/EditorTranslationParserPlugin.xml b/doc/classes/EditorTranslationParserPlugin.xml index 73098efd99..a40ef45916 100644 --- a/doc/classes/EditorTranslationParserPlugin.xml +++ b/doc/classes/EditorTranslationParserPlugin.xml @@ -4,22 +4,39 @@ Plugin for adding custom parsers to extract strings that are to be translated from custom files (.csv, .json etc.). </brief_description> <description> - Plugins are registered via [method EditorPlugin.add_translation_parser_plugin] method. To define the parsing and string extraction logic, override the [method parse_text] method in script. + Plugins are registered via [method EditorPlugin.add_translation_parser_plugin] method. To define the parsing and string extraction logic, override the [method parse_file] method in script. The extracted strings will be written into a POT file selected by user under "POT Generation" in "Localization" tab in "Project Settings" menu. Below shows an example of a custom parser that extracts strings in a CSV file to write into a POT. [codeblock] tool extends EditorTranslationParserPlugin - func parse_text(text, extracted_strings): + + func parse_file(path, extracted_strings): + var file = File.new() + file.open(path, File.READ) + var text = file.get_as_text() var split_strs = text.split(",", false, 0) for s in split_strs: extracted_strings.append(s) #print("Extracted string: " + s) + func get_recognized_extensions(): return ["csv"] [/codeblock] + [b]Note:[/b] If you override parsing logic for standard script types (GDScript, C#, etc.), it would be better to load the [code]path[/code] argument using [method ResourceLoader.load]. This is because built-in scripts are loaded as [Resource] type, not [File] type. + For example: + [codeblock] + func parse_file(path, extracted_strings): + var res = ResourceLoader.load(path, "Script") + var text = res.get_source_code() + # Parsing logic. + + + func get_recognized_extensions(): + return ["gd"] + [/codeblock] </description> <tutorials> </tutorials> @@ -31,10 +48,10 @@ Gets the list of file extensions to associate with this parser, e.g. [code]["csv"][/code]. </description> </method> - <method name="parse_text" qualifiers="virtual"> + <method name="parse_file" qualifiers="virtual"> <return type="void"> </return> - <argument index="0" name="text" type="String"> + <argument index="0" name="path" type="String"> </argument> <argument index="1" name="extracted_strings" type="Array"> </argument> diff --git a/doc/classes/PackedByteArray.xml b/doc/classes/PackedByteArray.xml index b08357e278..08f8558881 100644 --- a/doc/classes/PackedByteArray.xml +++ b/doc/classes/PackedByteArray.xml @@ -78,6 +78,15 @@ Returns a copy of the array's contents as [String]. Slower than [method get_string_from_ascii] but supports UTF-8 encoded data. Use this function if you are unsure about the source of the data. For user input this function should always be preferred. </description> </method> + <method name="has"> + <return type="bool"> + </return> + <argument index="0" name="value" type="int"> + </argument> + <description> + Returns [code]true[/code] if the array contains [code]value[/code]. + </description> + </method> <method name="hex_encode"> <return type="String"> </return> @@ -152,6 +161,13 @@ Returns the size of the array. </description> </method> + <method name="sort"> + <return type="void"> + </return> + <description> + Sorts the elements of the array in ascending order. + </description> + </method> <method name="subarray"> <return type="PackedByteArray"> </return> diff --git a/doc/classes/PackedColorArray.xml b/doc/classes/PackedColorArray.xml index 06228e4dac..ec087e1b39 100644 --- a/doc/classes/PackedColorArray.xml +++ b/doc/classes/PackedColorArray.xml @@ -44,6 +44,15 @@ Returns [code]true[/code] if the array is empty. </description> </method> + <method name="has"> + <return type="bool"> + </return> + <argument index="0" name="value" type="Color"> + </argument> + <description> + Returns [code]true[/code] if the array contains [code]value[/code]. + </description> + </method> <method name="insert"> <return type="int"> </return> @@ -107,6 +116,13 @@ Returns the size of the array. </description> </method> + <method name="sort"> + <return type="void"> + </return> + <description> + Sorts the elements of the array in ascending order. + </description> + </method> </methods> <constants> </constants> diff --git a/doc/classes/PackedFloat32Array.xml b/doc/classes/PackedFloat32Array.xml index ee82586cdb..a6b726944b 100644 --- a/doc/classes/PackedFloat32Array.xml +++ b/doc/classes/PackedFloat32Array.xml @@ -45,6 +45,15 @@ Returns [code]true[/code] if the array is empty. </description> </method> + <method name="has"> + <return type="bool"> + </return> + <argument index="0" name="value" type="float"> + </argument> + <description> + Returns [code]true[/code] if the array contains [code]value[/code]. + </description> + </method> <method name="insert"> <return type="int"> </return> @@ -108,6 +117,13 @@ Returns the size of the array. </description> </method> + <method name="sort"> + <return type="void"> + </return> + <description> + Sorts the elements of the array in ascending order. + </description> + </method> </methods> <constants> </constants> diff --git a/doc/classes/PackedFloat64Array.xml b/doc/classes/PackedFloat64Array.xml index ce2300c65a..f867cda3b6 100644 --- a/doc/classes/PackedFloat64Array.xml +++ b/doc/classes/PackedFloat64Array.xml @@ -45,6 +45,15 @@ Returns [code]true[/code] if the array is empty. </description> </method> + <method name="has"> + <return type="bool"> + </return> + <argument index="0" name="value" type="float"> + </argument> + <description> + Returns [code]true[/code] if the array contains [code]value[/code]. + </description> + </method> <method name="insert"> <return type="int"> </return> @@ -108,6 +117,13 @@ Returns the size of the array. </description> </method> + <method name="sort"> + <return type="void"> + </return> + <description> + Sorts the elements of the array in ascending order. + </description> + </method> </methods> <constants> </constants> diff --git a/doc/classes/PackedInt32Array.xml b/doc/classes/PackedInt32Array.xml index 176c624956..b796d9cacb 100644 --- a/doc/classes/PackedInt32Array.xml +++ b/doc/classes/PackedInt32Array.xml @@ -45,6 +45,15 @@ Returns [code]true[/code] if the array is empty. </description> </method> + <method name="has"> + <return type="bool"> + </return> + <argument index="0" name="value" type="int"> + </argument> + <description> + Returns [code]true[/code] if the array contains [code]value[/code]. + </description> + </method> <method name="insert"> <return type="int"> </return> @@ -108,6 +117,13 @@ Returns the array size. </description> </method> + <method name="sort"> + <return type="void"> + </return> + <description> + Sorts the elements of the array in ascending order. + </description> + </method> </methods> <constants> </constants> diff --git a/doc/classes/PackedInt64Array.xml b/doc/classes/PackedInt64Array.xml index d8a8071590..3d0d9a1360 100644 --- a/doc/classes/PackedInt64Array.xml +++ b/doc/classes/PackedInt64Array.xml @@ -45,6 +45,15 @@ Returns [code]true[/code] if the array is empty. </description> </method> + <method name="has"> + <return type="bool"> + </return> + <argument index="0" name="value" type="int"> + </argument> + <description> + Returns [code]true[/code] if the array contains [code]value[/code]. + </description> + </method> <method name="insert"> <return type="int"> </return> @@ -108,6 +117,13 @@ Returns the array size. </description> </method> + <method name="sort"> + <return type="void"> + </return> + <description> + Sorts the elements of the array in ascending order. + </description> + </method> </methods> <constants> </constants> diff --git a/doc/classes/PackedStringArray.xml b/doc/classes/PackedStringArray.xml index 9526f5899d..f36af66d6d 100644 --- a/doc/classes/PackedStringArray.xml +++ b/doc/classes/PackedStringArray.xml @@ -44,6 +44,15 @@ Returns [code]true[/code] if the array is empty. </description> </method> + <method name="has"> + <return type="bool"> + </return> + <argument index="0" name="value" type="String"> + </argument> + <description> + Returns [code]true[/code] if the array contains [code]value[/code]. + </description> + </method> <method name="insert"> <return type="int"> </return> @@ -107,6 +116,13 @@ Returns the size of the array. </description> </method> + <method name="sort"> + <return type="void"> + </return> + <description> + Sorts the elements of the array in ascending order. + </description> + </method> </methods> <constants> </constants> diff --git a/doc/classes/PackedVector2Array.xml b/doc/classes/PackedVector2Array.xml index 87f202357c..ecc535e488 100644 --- a/doc/classes/PackedVector2Array.xml +++ b/doc/classes/PackedVector2Array.xml @@ -44,6 +44,15 @@ Returns [code]true[/code] if the array is empty. </description> </method> + <method name="has"> + <return type="bool"> + </return> + <argument index="0" name="value" type="Vector2"> + </argument> + <description> + Returns [code]true[/code] if the array contains [code]value[/code]. + </description> + </method> <method name="insert"> <return type="int"> </return> @@ -107,6 +116,13 @@ Returns the size of the array. </description> </method> + <method name="sort"> + <return type="void"> + </return> + <description> + Sorts the elements of the array in ascending order. + </description> + </method> </methods> <constants> </constants> diff --git a/doc/classes/PackedVector3Array.xml b/doc/classes/PackedVector3Array.xml index 7bfa684ff5..f268fbcc83 100644 --- a/doc/classes/PackedVector3Array.xml +++ b/doc/classes/PackedVector3Array.xml @@ -44,6 +44,15 @@ Returns [code]true[/code] if the array is empty. </description> </method> + <method name="has"> + <return type="bool"> + </return> + <argument index="0" name="value" type="Vector3"> + </argument> + <description> + Returns [code]true[/code] if the array contains [code]value[/code]. + </description> + </method> <method name="insert"> <return type="int"> </return> @@ -107,6 +116,13 @@ Returns the size of the array. </description> </method> + <method name="sort"> + <return type="void"> + </return> + <description> + Sorts the elements of the array in ascending order. + </description> + </method> </methods> <constants> </constants> diff --git a/drivers/windows/dir_access_windows.cpp b/drivers/windows/dir_access_windows.cpp index 2653ac1cdb..b8153907a9 100644 --- a/drivers/windows/dir_access_windows.cpp +++ b/drivers/windows/dir_access_windows.cpp @@ -67,7 +67,11 @@ Error DirAccessWindows::list_dir_begin() { list_dir_end(); p->h = FindFirstFileExW((current_dir + "\\*").c_str(), FindExInfoStandard, &p->fu, FindExSearchNameMatch, nullptr, 0); - return (p->h == INVALID_HANDLE_VALUE) ? ERR_CANT_OPEN : OK; + if (p->h == INVALID_HANDLE_VALUE) { + return ERR_CANT_OPEN; + } + + return OK; } String DirAccessWindows::get_next() { diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp index b73a27214d..70747b4956 100644 --- a/editor/code_editor.cpp +++ b/editor/code_editor.cpp @@ -108,22 +108,25 @@ void FindReplaceBar::_notification(int p_what) { void FindReplaceBar::_unhandled_input(const Ref<InputEvent> &p_event) { Ref<InputEventKey> k = p_event; - if (k.is_valid()) { - if (k->is_pressed() && (text_edit->has_focus() || vbc_lineedit->is_a_parent_of(get_focus_owner()))) { - bool accepted = true; - - switch (k->get_keycode()) { - case KEY_ESCAPE: { - _hide_bar(); - } break; - default: { - accepted = false; - } break; - } + if (!k.is_valid() || !k->is_pressed()) { + return; + } - if (accepted) { - accept_event(); - } + Control *focus_owner = get_focus_owner(); + if (text_edit->has_focus() || (focus_owner && vbc_lineedit->is_a_parent_of(focus_owner))) { + bool accepted = true; + + switch (k->get_keycode()) { + case KEY_ESCAPE: { + _hide_bar(); + } break; + default: { + accepted = false; + } break; + } + + if (accepted) { + accept_event(); } } } diff --git a/editor/create_dialog.cpp b/editor/create_dialog.cpp index a1bc7a9522..99a2a73a75 100644 --- a/editor/create_dialog.cpp +++ b/editor/create_dialog.cpp @@ -425,7 +425,6 @@ Object *CreateDialog::instance_selected() { if (n) { n->set_name(custom); } - obj = n; } else { obj = EditorNode::get_editor_data().instance_custom_type(selected->get_text(0), custom); } diff --git a/editor/editor_autoload_settings.cpp b/editor/editor_autoload_settings.cpp index da0ff9f18f..4cd4f68fa2 100644 --- a/editor/editor_autoload_settings.cpp +++ b/editor/editor_autoload_settings.cpp @@ -477,6 +477,8 @@ void EditorAutoloadSettings::update_autoload() { info.node->queue_delete(); info.node = nullptr; } + + ProjectSettings::get_singleton()->remove_autoload(info.name); } // Load new/changed autoloads @@ -503,6 +505,12 @@ void EditorAutoloadSettings::update_autoload() { } } + ProjectSettings::AutoloadInfo prop_info; + prop_info.name = info->name; + prop_info.path = info->path; + prop_info.is_singleton = info->is_singleton; + ProjectSettings::get_singleton()->add_autoload(prop_info); + if (!info->in_editor && !info->is_singleton) { // No reason to keep this node memdelete(info->node); diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp index 7742382048..cf32ffb4e0 100644 --- a/editor/editor_inspector.cpp +++ b/editor/editor_inspector.cpp @@ -1592,7 +1592,9 @@ void EditorInspector::update_tree() { } } if (category->icon.is_null()) { - category->icon = EditorNode::get_singleton()->get_class_icon(type, "Object"); + if (type != String()) { // Can happen for built-in scripts. + category->icon = EditorNode::get_singleton()->get_class_icon(type, "Object"); + } } category->label = type; @@ -2405,9 +2407,12 @@ void EditorInspector::_update_script_class_properties(const Object &p_object, Li String n = EditorNode::get_editor_data().script_class_get_name(script->get_path()); if (n.length()) { classes.push_front(n); - } else { + } else if (script->get_path() != String() && script->get_path().find("::") == -1) { n = script->get_path().get_file(); classes.push_front(n); + } else { + n = TTR("Built-in script"); + classes.push_front(n); } paths[n] = script->get_path(); script = script->get_base_script(); @@ -2436,7 +2441,14 @@ void EditorInspector::_update_script_class_properties(const Object &p_object, Li for (List<StringName>::Element *E = classes.front(); E; E = E->next()) { StringName name = E->get(); String path = paths[name]; - Ref<Script> s = ResourceLoader::load(path, "Script"); + Ref<Script> s; + if (path == String()) { + // Built-in script. It can't be inherited, so must be the script attached to the object. + s = p_object.get_script(); + } else { + s = ResourceLoader::load(path, "Script"); + } + ERR_FAIL_COND(!s->is_valid()); List<PropertyInfo> props; s->get_script_property_list(&props); diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index a4a53d8a92..454170647f 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -1225,20 +1225,25 @@ void EditorNode::_save_scene_with_preview(String p_file, int p_idx) { _find_node_types(editor_data.get_edited_scene_root(), c2d, c3d); - bool is2d; - if (c3d < c2d) { - is2d = true; - } else { - is2d = false; - } save.step(TTR("Creating Thumbnail"), 1); //current view? Ref<Image> img; - if (is2d) { + // If neither 3D or 2D nodes are present, make a 1x1 black texture. + // We cannot fallback on the 2D editor, because it may not have been used yet, + // which would result in an invalid texture. + if (c3d == 0 && c2d == 0) { + img.instance(); + img->create(1, 1, 0, Image::FORMAT_RGB8); + } else if (c3d < c2d) { img = scene_root->get_texture()->get_data(); } else { - img = Node3DEditor::get_singleton()->get_editor_viewport(0)->get_viewport_node()->get_texture()->get_data(); + // The 3D editor may be disabled as a feature, but scenes can still be opened. + // This check prevents the preview from regenerating in case those scenes are then saved. + Ref<EditorFeatureProfile> profile = feature_profile_manager->get_current_profile(); + if (!profile->is_feature_disabled(EditorFeatureProfile::FEATURE_3D)) { + img = Node3DEditor::get_singleton()->get_editor_viewport(0)->get_viewport_node()->get_texture()->get_data(); + } } if (img.is_valid()) { @@ -2043,7 +2048,6 @@ void EditorNode::_run(bool p_current, const String &p_custom) { play_custom_scene_button->set_pressed(false); play_custom_scene_button->set_icon(gui_base->get_theme_icon("PlayCustom", "EditorIcons")); - String main_scene; String run_filename; String args; bool skip_breakpoints; @@ -2464,8 +2468,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { } break; case RUN_PLAY: { - _menu_option_confirm(RUN_STOP, true); - _run(false); + run_play(); } break; case RUN_PLAY_CUSTOM_SCENE: { @@ -2476,8 +2479,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { play_custom_scene_button->set_pressed(false); } else { String last_custom_scene = run_custom_filename; - _menu_option_confirm(RUN_STOP, true); - _run(false, last_custom_scene); + run_play_custom(last_custom_scene); } } break; @@ -2517,9 +2519,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { } break; case RUN_PLAY_SCENE: { - _save_default_environment(); - _menu_option_confirm(RUN_STOP, true); - _run(true); + run_play_current(); } break; case RUN_SCENE_SETTINGS: { @@ -4524,10 +4524,35 @@ void EditorNode::run_play() { _run(false); } +void EditorNode::run_play_current() { + _save_default_environment(); + _menu_option_confirm(RUN_STOP, true); + _run(true); +} + +void EditorNode::run_play_custom(const String &p_custom) { + _menu_option_confirm(RUN_STOP, true); + _run(false, p_custom); +} + void EditorNode::run_stop() { _menu_option_confirm(RUN_STOP, false); } +bool EditorNode::is_run_playing() const { + EditorRun::Status status = editor_run.get_status(); + return (status == EditorRun::STATUS_PLAY || status == EditorRun::STATUS_PAUSED); +} + +String EditorNode::get_run_playing_scene() const { + String run_filename = editor_run.get_running_scene(); + if (run_filename == "" && is_run_playing()) { + run_filename = GLOBAL_DEF("application/run/main_scene", ""); // Must be the main scene then. + } + + return run_filename; +} + int EditorNode::get_current_tab() { return scene_tabs->get_current_tab(); } diff --git a/editor/editor_node.h b/editor/editor_node.h index f6cae466ff..dec28b0d2b 100644 --- a/editor/editor_node.h +++ b/editor/editor_node.h @@ -865,7 +865,11 @@ public: bool ensure_main_scene(bool p_from_native); void run_play(); + void run_play_current(); + void run_play_custom(const String &p_custom); void run_stop(); + bool is_run_playing() const; + String get_run_playing_scene() const; }; struct EditorProgress { diff --git a/editor/editor_plugin.cpp b/editor/editor_plugin.cpp index af1b426327..da0a0827d2 100644 --- a/editor/editor_plugin.cpp +++ b/editor/editor_plugin.cpp @@ -176,6 +176,30 @@ void EditorInterface::reload_scene_from_path(const String &scene_path) { EditorNode::get_singleton()->reload_scene(scene_path); } +void EditorInterface::play_main_scene() { + EditorNode::get_singleton()->run_play(); +} + +void EditorInterface::play_current_scene() { + EditorNode::get_singleton()->run_play_current(); +} + +void EditorInterface::play_custom_scene(const String &scene_path) { + EditorNode::get_singleton()->run_play_custom(scene_path); +} + +void EditorInterface::stop_playing_scene() { + EditorNode::get_singleton()->run_stop(); +} + +bool EditorInterface::is_playing_scene() const { + return EditorNode::get_singleton()->is_run_playing(); +} + +String EditorInterface::get_playing_scene() const { + return EditorNode::get_singleton()->get_run_playing_scene(); +} + Node *EditorInterface::get_edited_scene_root() { return EditorNode::get_singleton()->get_edited_scene(); } @@ -285,6 +309,12 @@ void EditorInterface::_bind_methods() { ClassDB::bind_method(D_METHOD("edit_resource", "resource"), &EditorInterface::edit_resource); ClassDB::bind_method(D_METHOD("open_scene_from_path", "scene_filepath"), &EditorInterface::open_scene_from_path); ClassDB::bind_method(D_METHOD("reload_scene_from_path", "scene_filepath"), &EditorInterface::reload_scene_from_path); + ClassDB::bind_method(D_METHOD("play_main_scene"), &EditorInterface::play_main_scene); + ClassDB::bind_method(D_METHOD("play_current_scene"), &EditorInterface::play_current_scene); + ClassDB::bind_method(D_METHOD("play_custom_scene", "scene_filepath"), &EditorInterface::play_custom_scene); + ClassDB::bind_method(D_METHOD("stop_playing_scene"), &EditorInterface::stop_playing_scene); + ClassDB::bind_method(D_METHOD("is_playing_scene"), &EditorInterface::is_playing_scene); + ClassDB::bind_method(D_METHOD("get_playing_scene"), &EditorInterface::get_playing_scene); ClassDB::bind_method(D_METHOD("get_open_scenes"), &EditorInterface::get_open_scenes); ClassDB::bind_method(D_METHOD("get_edited_scene_root"), &EditorInterface::get_edited_scene_root); ClassDB::bind_method(D_METHOD("get_resource_previewer"), &EditorInterface::get_resource_previewer); diff --git a/editor/editor_plugin.h b/editor/editor_plugin.h index 52ff7f04f8..685f69bf3f 100644 --- a/editor/editor_plugin.h +++ b/editor/editor_plugin.h @@ -73,6 +73,13 @@ public: void open_scene_from_path(const String &scene_path); void reload_scene_from_path(const String &scene_path); + void play_main_scene(); + void play_current_scene(); + void play_custom_scene(const String &scene_path); + void stop_playing_scene(); + bool is_playing_scene() const; + String get_playing_scene() const; + Node *get_edited_scene_root(); Array get_open_scenes() const; ScriptEditor *get_script_editor(); diff --git a/editor/editor_run.cpp b/editor/editor_run.cpp index 6a73e6c072..b49c50fa31 100644 --- a/editor/editor_run.cpp +++ b/editor/editor_run.cpp @@ -38,6 +38,10 @@ EditorRun::Status EditorRun::get_status() const { return status; } +String EditorRun::get_running_scene() const { + return running_scene; +} + Error EditorRun::run(const String &p_scene, const String &p_custom_args, const List<String> &p_breakpoints, const bool &p_skip_breakpoints) { List<String> args; @@ -203,6 +207,9 @@ Error EditorRun::run(const String &p_scene, const String &p_custom_args, const L } status = STATUS_PLAY; + if (p_scene != "") { + running_scene = p_scene; + } return OK; } @@ -231,8 +238,10 @@ void EditorRun::stop() { } status = STATUS_STOP; + running_scene = ""; } EditorRun::EditorRun() { status = STATUS_STOP; + running_scene = ""; } diff --git a/editor/editor_run.h b/editor/editor_run.h index 06050436a9..a15d65d91b 100644 --- a/editor/editor_run.h +++ b/editor/editor_run.h @@ -46,9 +46,11 @@ public: private: Status status; + String running_scene; public: Status get_status() const; + String get_running_scene() const; Error run(const String &p_scene, const String &p_custom_args, const List<String> &p_breakpoints, const bool &p_skip_breakpoints = false); void run_native_notify() { status = STATUS_PLAY; } void stop(); diff --git a/editor/editor_translation_parser.cpp b/editor/editor_translation_parser.cpp index 1f08a985f1..3f4864ad1e 100644 --- a/editor/editor_translation_parser.cpp +++ b/editor/editor_translation_parser.cpp @@ -41,33 +41,16 @@ Error EditorTranslationParserPlugin::parse_file(const String &p_path, Vector<Str if (!get_script_instance()) return ERR_UNAVAILABLE; - if (get_script_instance()->has_method("parse_text")) { - Error err; - FileAccess *file = FileAccess::open(p_path, FileAccess::READ, &err); - if (err != OK) { - ERR_PRINT("Failed to open " + p_path); - return err; - } - parse_text(file->get_as_utf8_string(), r_extracted_strings); - return OK; - } else { - ERR_PRINT("Custom translation parser plugin's \"func parse_text(text, extracted_strings)\" is undefined."); - return ERR_UNAVAILABLE; - } -} - -void EditorTranslationParserPlugin::parse_text(const String &p_text, Vector<String> *r_extracted_strings) { - if (!get_script_instance()) - return; - - if (get_script_instance()->has_method("parse_text")) { + if (get_script_instance()->has_method("parse_file")) { Array extracted_strings; - get_script_instance()->call("parse_text", p_text, extracted_strings); + get_script_instance()->call("parse_file", p_path, extracted_strings); for (int i = 0; i < extracted_strings.size(); i++) { r_extracted_strings->append(extracted_strings[i]); } + return OK; } else { - ERR_PRINT("Custom translation parser plugin's \"func parse_text(text, extracted_strings)\" is undefined."); + ERR_PRINT("Custom translation parser plugin's \"func parse_file(path, extracted_strings)\" is undefined."); + return ERR_UNAVAILABLE; } } @@ -86,7 +69,7 @@ void EditorTranslationParserPlugin::get_recognized_extensions(List<String> *r_ex } void EditorTranslationParserPlugin::_bind_methods() { - ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::NIL, "parse_text", PropertyInfo(Variant::STRING, "text"), PropertyInfo(Variant::ARRAY, "extracted_strings"))); + ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::NIL, "parse_file", PropertyInfo(Variant::STRING, "path"), PropertyInfo(Variant::ARRAY, "extracted_strings"))); ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::ARRAY, "get_recognized_extensions")); } diff --git a/editor/editor_translation_parser.h b/editor/editor_translation_parser.h index 518e3616eb..6d00bedfa4 100644 --- a/editor/editor_translation_parser.h +++ b/editor/editor_translation_parser.h @@ -42,7 +42,6 @@ protected: public: virtual Error parse_file(const String &p_path, Vector<String> *r_extracted_strings); - virtual void parse_text(const String &p_text, Vector<String> *r_extracted_strings); virtual void get_recognized_extensions(List<String> *r_extensions) const; }; diff --git a/editor/plugins/packed_scene_translation_parser_plugin.cpp b/editor/plugins/packed_scene_translation_parser_plugin.cpp index f9aaa93614..52af0008b7 100644 --- a/editor/plugins/packed_scene_translation_parser_plugin.cpp +++ b/editor/plugins/packed_scene_translation_parser_plugin.cpp @@ -71,7 +71,7 @@ Error PackedSceneEditorTranslationParserPlugin::parse_file(const String &p_path, String extension = s->get_language()->get_extension(); if (EditorTranslationParser::get_singleton()->can_parse(extension)) { Vector<String> temp; - EditorTranslationParser::get_singleton()->get_parser(extension)->parse_text(s->get_source_code(), &temp); + EditorTranslationParser::get_singleton()->get_parser(extension)->parse_file(s->get_path(), &temp); parsed_strings.append_array(temp); } } else if (property_name == "filters") { diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp index 1c9dadc0dd..9304683d77 100644 --- a/editor/plugins/script_text_editor.cpp +++ b/editor/plugins/script_text_editor.cpp @@ -343,16 +343,11 @@ void ScriptTextEditor::_set_theme_for_script() { } //colorize singleton autoloads (as types, just as engine singletons are) - List<PropertyInfo> props; - ProjectSettings::get_singleton()->get_property_list(&props); - for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) { - String s = E->get().name; - if (!s.begins_with("autoload/")) { - continue; - } - String path = ProjectSettings::get_singleton()->get(s); - if (path.begins_with("*")) { - text_edit->add_keyword_color(s.get_slice("/", 1), colors_cache.usertype_color); + Map<StringName, ProjectSettings::AutoloadInfo> autoloads = ProjectSettings::get_singleton()->get_autoload_list(); + for (Map<StringName, ProjectSettings::AutoloadInfo>::Element *E = autoloads.front(); E; E = E->next()) { + const ProjectSettings::AutoloadInfo &info = E->value(); + if (info.is_singleton) { + text_edit->add_keyword_color(info.name, colors_cache.usertype_color); } } @@ -942,12 +937,11 @@ void ScriptTextEditor::_lookup_symbol(const String &p_symbol, int p_row, int p_c emit_signal("go_to_help", "class_global:" + result.class_name + ":" + result.class_member); } break; } - } else if (ProjectSettings::get_singleton()->has_setting("autoload/" + p_symbol)) { - //check for Autoload scenes - String path = ProjectSettings::get_singleton()->get("autoload/" + p_symbol); - if (path.begins_with("*")) { - path = path.substr(1, path.length()); - EditorNode::get_singleton()->load_scene(path); + } else if (ProjectSettings::get_singleton()->has_autoload(p_symbol)) { + // Check for Autoload scenes. + const ProjectSettings::AutoloadInfo &info = ProjectSettings::get_singleton()->get_autoload(p_symbol); + if (info.is_singleton) { + EditorNode::get_singleton()->load_scene(info.path); } } else if (p_symbol.is_rel_path()) { // Every symbol other than absolute path is relative path so keep this condition at last. @@ -974,7 +968,7 @@ void ScriptTextEditor::_validate_symbol(const String &p_symbol) { } ScriptLanguage::LookupResult result; - if (ScriptServer::is_global_class(p_symbol) || p_symbol.is_resource_file() || script->get_language()->lookup_code(code_editor->get_text_edit()->get_text_for_lookup_completion(), p_symbol, script->get_path(), base, result) == OK || ProjectSettings::get_singleton()->has_setting("autoload/" + p_symbol)) { + if (ScriptServer::is_global_class(p_symbol) || p_symbol.is_resource_file() || script->get_language()->lookup_code(code_editor->get_text_edit()->get_text_for_lookup_completion(), p_symbol, script->get_path(), base, result) == OK || (ProjectSettings::get_singleton()->has_autoload(p_symbol) && ProjectSettings::get_singleton()->get_autoload(p_symbol).is_singleton)) { text_edit->set_highlighted_word(p_symbol); } else if (p_symbol.is_rel_path()) { String path = _get_absolute_path(p_symbol); diff --git a/main/main.cpp b/main/main.cpp index 608b4a7c4d..4ea11cfaeb 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -1792,46 +1792,26 @@ bool Main::start() { if (!project_manager && !editor) { // game if (game_path != "" || script != "") { //autoload - List<PropertyInfo> props; - ProjectSettings::get_singleton()->get_property_list(&props); + Map<StringName, ProjectSettings::AutoloadInfo> autoloads = ProjectSettings::get_singleton()->get_autoload_list(); //first pass, add the constants so they exist before any script is loaded - for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) { - String s = E->get().name; - if (!s.begins_with("autoload/")) { - continue; - } - String name = s.get_slicec('/', 1); - String path = ProjectSettings::get_singleton()->get(s); - bool global_var = false; - if (path.begins_with("*")) { - global_var = true; - } + for (Map<StringName, ProjectSettings::AutoloadInfo>::Element *E = autoloads.front(); E; E = E->next()) { + const ProjectSettings::AutoloadInfo &info = E->get(); - if (global_var) { + if (info.is_singleton) { for (int i = 0; i < ScriptServer::get_language_count(); i++) { - ScriptServer::get_language(i)->add_global_constant(name, Variant()); + ScriptServer::get_language(i)->add_global_constant(info.name, Variant()); } } } //second pass, load into global constants List<Node *> to_add; - for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) { - String s = E->get().name; - if (!s.begins_with("autoload/")) { - continue; - } - String name = s.get_slicec('/', 1); - String path = ProjectSettings::get_singleton()->get(s); - bool global_var = false; - if (path.begins_with("*")) { - global_var = true; - path = path.substr(1, path.length() - 1); - } + for (Map<StringName, ProjectSettings::AutoloadInfo>::Element *E = autoloads.front(); E; E = E->next()) { + const ProjectSettings::AutoloadInfo &info = E->get(); - RES res = ResourceLoader::load(path); - ERR_CONTINUE_MSG(res.is_null(), "Can't autoload: " + path); + RES res = ResourceLoader::load(info.path); + ERR_CONTINUE_MSG(res.is_null(), "Can't autoload: " + info.path); Node *n = nullptr; if (res->is_class("PackedScene")) { Ref<PackedScene> ps = res; @@ -1840,7 +1820,7 @@ bool Main::start() { Ref<Script> script_res = res; StringName ibt = script_res->get_instance_base_type(); bool valid_type = ClassDB::is_parent_class(ibt, "Node"); - ERR_CONTINUE_MSG(!valid_type, "Script does not inherit a Node: " + path); + ERR_CONTINUE_MSG(!valid_type, "Script does not inherit a Node: " + info.path); Object *obj = ClassDB::instance(ibt); @@ -1850,15 +1830,15 @@ bool Main::start() { n->set_script(script_res); } - ERR_CONTINUE_MSG(!n, "Path in autoload not a node or script: " + path); - n->set_name(name); + ERR_CONTINUE_MSG(!n, "Path in autoload not a node or script: " + info.path); + n->set_name(info.name); //defer so references are all valid on _ready() to_add.push_back(n); - if (global_var) { + if (info.is_singleton) { for (int i = 0; i < ScriptServer::get_language_count(); i++) { - ScriptServer::get_language(i)->add_global_constant(name, n); + ScriptServer::get_language(i)->add_global_constant(info.name, n); } } } diff --git a/modules/bullet/area_bullet.cpp b/modules/bullet/area_bullet.cpp index 79d8e252f0..01f068780d 100644 --- a/modules/bullet/area_bullet.cpp +++ b/modules/bullet/area_bullet.cpp @@ -164,7 +164,7 @@ void AreaBullet::main_shape_changed() { btGhost->setCollisionShape(get_main_shape()); } -void AreaBullet::reload_body() { +void AreaBullet::do_reload_body() { if (space) { space->remove_area(this); space->add_area(this); @@ -174,16 +174,19 @@ void AreaBullet::reload_body() { void AreaBullet::set_space(SpaceBullet *p_space) { // Clear the old space if there is one if (space) { + overlappingObjects.clear(); isScratched = false; // Remove this object form the physics world + space->unregister_collision_object(this); space->remove_area(this); } space = p_space; if (space) { - space->add_area(this); + space->register_collision_object(this); + reload_body(); } } diff --git a/modules/bullet/area_bullet.h b/modules/bullet/area_bullet.h index c0bcc858fe..12272092f7 100644 --- a/modules/bullet/area_bullet.h +++ b/modules/bullet/area_bullet.h @@ -140,7 +140,7 @@ public: _FORCE_INLINE_ int get_spOv_priority() { return spOv_priority; } virtual void main_shape_changed(); - virtual void reload_body(); + virtual void do_reload_body(); virtual void set_space(SpaceBullet *p_space); virtual void dispatch_callbacks(); diff --git a/modules/bullet/bullet_physics_server.cpp b/modules/bullet/bullet_physics_server.cpp index f397c53344..bb1678a994 100644 --- a/modules/bullet/bullet_physics_server.cpp +++ b/modules/bullet/bullet_physics_server.cpp @@ -561,14 +561,14 @@ void BulletPhysicsServer3D::body_clear_shapes(RID p_body) { } void BulletPhysicsServer3D::body_attach_object_instance_id(RID p_body, ObjectID p_id) { - CollisionObjectBullet *body = get_collisin_object(p_body); + CollisionObjectBullet *body = get_collision_object(p_body); ERR_FAIL_COND(!body); body->set_instance_id(p_id); } ObjectID BulletPhysicsServer3D::body_get_object_instance_id(RID p_body) const { - CollisionObjectBullet *body = get_collisin_object(p_body); + CollisionObjectBullet *body = get_collision_object(p_body); ERR_FAIL_COND_V(!body, ObjectID()); return body->get_instance_id(); @@ -1567,7 +1567,17 @@ int BulletPhysicsServer3D::get_process_info(ProcessInfo p_info) { return 0; } -CollisionObjectBullet *BulletPhysicsServer3D::get_collisin_object(RID p_object) const { +SpaceBullet *BulletPhysicsServer3D::get_space(RID p_rid) const { + ERR_FAIL_COND_V_MSG(space_owner.owns(p_rid) == false, nullptr, "The RID is not valid."); + return space_owner.getornull(p_rid); +} + +ShapeBullet *BulletPhysicsServer3D::get_shape(RID p_rid) const { + ERR_FAIL_COND_V_MSG(shape_owner.owns(p_rid) == false, nullptr, "The RID is not valid."); + return shape_owner.getornull(p_rid); +} + +CollisionObjectBullet *BulletPhysicsServer3D::get_collision_object(RID p_object) const { if (rigid_body_owner.owns(p_object)) { return rigid_body_owner.getornull(p_object); } @@ -1577,15 +1587,20 @@ CollisionObjectBullet *BulletPhysicsServer3D::get_collisin_object(RID p_object) if (soft_body_owner.owns(p_object)) { return soft_body_owner.getornull(p_object); } - return nullptr; + ERR_FAIL_V_MSG(nullptr, "The RID is no valid."); } -RigidCollisionObjectBullet *BulletPhysicsServer3D::get_rigid_collisin_object(RID p_object) const { +RigidCollisionObjectBullet *BulletPhysicsServer3D::get_rigid_collision_object(RID p_object) const { if (rigid_body_owner.owns(p_object)) { return rigid_body_owner.getornull(p_object); } if (area_owner.owns(p_object)) { return area_owner.getornull(p_object); } - return nullptr; + ERR_FAIL_V_MSG(nullptr, "The RID is no valid."); +} + +JointBullet *BulletPhysicsServer3D::get_joint(RID p_rid) const { + ERR_FAIL_COND_V_MSG(joint_owner.owns(p_rid) == false, nullptr, "The RID is not valid."); + return joint_owner.getornull(p_rid); } diff --git a/modules/bullet/bullet_physics_server.h b/modules/bullet/bullet_physics_server.h index 8e8b33a4b8..a8c4f6d0b2 100644 --- a/modules/bullet/bullet_physics_server.h +++ b/modules/bullet/bullet_physics_server.h @@ -405,11 +405,11 @@ public: virtual int get_process_info(ProcessInfo p_info); - CollisionObjectBullet *get_collisin_object(RID p_object) const; - RigidCollisionObjectBullet *get_rigid_collisin_object(RID p_object) const; - - /// Internal APIs -public: + SpaceBullet *get_space(RID p_rid) const; + ShapeBullet *get_shape(RID p_rid) const; + CollisionObjectBullet *get_collision_object(RID p_object) const; + RigidCollisionObjectBullet *get_rigid_collision_object(RID p_object) const; + JointBullet *get_joint(RID p_rid) const; }; #endif diff --git a/modules/bullet/collision_object_bullet.cpp b/modules/bullet/collision_object_bullet.cpp index a3158a15e5..dd208965bd 100644 --- a/modules/bullet/collision_object_bullet.cpp +++ b/modules/bullet/collision_object_bullet.cpp @@ -79,7 +79,7 @@ btTransform CollisionObjectBullet::ShapeWrapper::get_adjusted_transform() const } void CollisionObjectBullet::ShapeWrapper::claim_bt_shape(const btVector3 &body_scale) { - if (!bt_shape) { + if (bt_shape == nullptr) { if (active) { bt_shape = shape->create_bt_shape(scale * body_scale); } else { @@ -88,6 +88,13 @@ void CollisionObjectBullet::ShapeWrapper::claim_bt_shape(const btVector3 &body_s } } +void CollisionObjectBullet::ShapeWrapper::release_bt_shape() { + if (bt_shape != nullptr) { + shape->destroy_bt_shape(bt_shape); + bt_shape = nullptr; + } +} + CollisionObjectBullet::CollisionObjectBullet(Type p_type) : RIDBullet(), type(p_type) {} @@ -158,6 +165,13 @@ bool CollisionObjectBullet::has_collision_exception(const CollisionObjectBullet return !bt_collision_object->checkCollideWith(p_otherCollisionObject->bt_collision_object); } +void CollisionObjectBullet::prepare_object_for_dispatch() { + if (need_body_reload) { + do_reload_body(); + need_body_reload = false; + } +} + void CollisionObjectBullet::set_collision_enabled(bool p_enabled) { collisionsEnabled = p_enabled; if (collisionsEnabled) { @@ -319,16 +333,28 @@ bool RigidCollisionObjectBullet::is_shape_disabled(int p_index) { return !shapes[p_index].active; } +void RigidCollisionObjectBullet::prepare_object_for_dispatch() { + if (need_shape_reload) { + do_reload_shapes(); + need_shape_reload = false; + } + CollisionObjectBullet::prepare_object_for_dispatch(); +} + void RigidCollisionObjectBullet::shape_changed(int p_shape_index) { ShapeWrapper &shp = shapes.write[p_shape_index]; if (shp.bt_shape == mainShape) { mainShape = nullptr; } - bulletdelete(shp.bt_shape); + shp.release_bt_shape(); reload_shapes(); } void RigidCollisionObjectBullet::reload_shapes() { + need_shape_reload = true; +} + +void RigidCollisionObjectBullet::do_reload_shapes() { if (mainShape && mainShape->isCompound()) { // Destroy compound bulletdelete(mainShape); @@ -336,41 +362,39 @@ void RigidCollisionObjectBullet::reload_shapes() { mainShape = nullptr; - ShapeWrapper *shpWrapper; const int shape_count = shapes.size(); + ShapeWrapper *shapes_ptr = shapes.ptrw(); - // Reset shape if required + // Reset all shapes if required if (force_shape_reset) { for (int i(0); i < shape_count; ++i) { - shpWrapper = &shapes.write[i]; - bulletdelete(shpWrapper->bt_shape); + shapes_ptr[i].release_bt_shape(); } force_shape_reset = false; } const btVector3 body_scale(get_bt_body_scale()); - // Try to optimize by not using compound if (1 == shape_count) { - shpWrapper = &shapes.write[0]; - btTransform transform = shpWrapper->get_adjusted_transform(); + // Is it possible to optimize by not using compound? + btTransform transform = shapes_ptr[0].get_adjusted_transform(); if (transform.getOrigin().isZero() && transform.getBasis() == transform.getBasis().getIdentity()) { - shpWrapper->claim_bt_shape(body_scale); - mainShape = shpWrapper->bt_shape; + shapes_ptr[0].claim_bt_shape(body_scale); + mainShape = shapes_ptr[0].bt_shape; main_shape_changed(); + // Nothing more to do return; } } - // Optimization not possible use a compound shape + // Optimization not possible use a compound shape. btCompoundShape *compoundShape = bulletnew(btCompoundShape(enableDynamicAabbTree, shape_count)); for (int i(0); i < shape_count; ++i) { - shpWrapper = &shapes.write[i]; - shpWrapper->claim_bt_shape(body_scale); - btTransform scaled_shape_transform(shpWrapper->get_adjusted_transform()); + shapes_ptr[i].claim_bt_shape(body_scale); + btTransform scaled_shape_transform(shapes_ptr[i].get_adjusted_transform()); scaled_shape_transform.getOrigin() *= body_scale; - compoundShape->addChildShape(scaled_shape_transform, shpWrapper->bt_shape); + compoundShape->addChildShape(scaled_shape_transform, shapes_ptr[i].bt_shape); } compoundShape->recalculateLocalAabb(); @@ -389,5 +413,5 @@ void RigidCollisionObjectBullet::internal_shape_destroy(int p_index, bool p_perm if (shp.bt_shape == mainShape) { mainShape = nullptr; } - bulletdelete(shp.bt_shape); + shp.release_bt_shape(); } diff --git a/modules/bullet/collision_object_bullet.h b/modules/bullet/collision_object_bullet.h index f1423a69e4..ac74661f24 100644 --- a/modules/bullet/collision_object_bullet.h +++ b/modules/bullet/collision_object_bullet.h @@ -70,11 +70,12 @@ public: struct ShapeWrapper { ShapeBullet *shape = nullptr; - btCollisionShape *bt_shape = nullptr; btTransform transform; btVector3 scale; bool active = true; + btCollisionShape *bt_shape = nullptr; + public: ShapeWrapper() {} ShapeWrapper(ShapeBullet *p_shape, const btTransform &p_transform, bool p_active) : @@ -107,6 +108,7 @@ public: btTransform get_adjusted_transform() const; void claim_bt_shape(const btVector3 &body_scale); + void release_bt_shape(); }; protected: @@ -124,6 +126,8 @@ protected: VSet<RID> exceptions; + bool need_body_reload = true; + /// This array is used to know all areas where this Object is overlapped in /// New area is added when overlap with new area (AreaBullet::addOverlap), then is removed when it exit (CollisionObjectBullet::onExitArea) /// This array is used mainly to know which area hold the pointer of this object @@ -131,6 +135,9 @@ protected: bool isTransformChanged = false; public: + bool is_in_world = false; + +public: CollisionObjectBullet(Type p_type); virtual ~CollisionObjectBullet(); @@ -183,13 +190,21 @@ public: return collisionLayer & p_other->collisionMask || p_other->collisionLayer & collisionMask; } - virtual void reload_body() = 0; + bool need_reload_body() const { + return need_body_reload; + } + + void reload_body() { + need_body_reload = true; + } + virtual void do_reload_body() = 0; virtual void set_space(SpaceBullet *p_space) = 0; _FORCE_INLINE_ SpaceBullet *get_space() const { return space; } virtual void on_collision_checker_start() = 0; virtual void on_collision_checker_end() = 0; + virtual void prepare_object_for_dispatch(); virtual void dispatch_callbacks() = 0; void set_collision_enabled(bool p_enabled); @@ -215,6 +230,7 @@ class RigidCollisionObjectBullet : public CollisionObjectBullet, public ShapeOwn protected: btCollisionShape *mainShape = nullptr; Vector<ShapeWrapper> shapes; + bool need_shape_reload = true; public: RigidCollisionObjectBullet(Type p_type) : @@ -246,8 +262,12 @@ public: void set_shape_disabled(int p_index, bool p_disabled); bool is_shape_disabled(int p_index); + virtual void prepare_object_for_dispatch(); + virtual void shape_changed(int p_shape_index); - virtual void reload_shapes(); + void reload_shapes(); + bool need_reload_shapes() const { return need_shape_reload; } + virtual void do_reload_shapes(); virtual void main_shape_changed() = 0; virtual void body_scale_changed(); diff --git a/modules/bullet/rigid_body_bullet.cpp b/modules/bullet/rigid_body_bullet.cpp index 6cfbe18a64..8ff27cda30 100644 --- a/modules/bullet/rigid_body_bullet.cpp +++ b/modules/bullet/rigid_body_bullet.cpp @@ -237,7 +237,7 @@ void RigidBodyBullet::KinematicUtilities::copyAllOwnerShapes() { case PhysicsServer3D::SHAPE_CYLINDER: case PhysicsServer3D::SHAPE_CONVEX_POLYGON: case PhysicsServer3D::SHAPE_RAY: { - shapes.write[i].shape = static_cast<btConvexShape *>(shape_wrapper->shape->create_bt_shape(owner_scale * shape_wrapper->scale, safe_margin)); + shapes.write[i].shape = static_cast<btConvexShape *>(shape_wrapper->shape->internal_create_bt_shape(owner_scale * shape_wrapper->scale, safe_margin)); } break; default: WARN_PRINT("This shape is not supported for kinematic collision."); @@ -307,7 +307,7 @@ void RigidBodyBullet::main_shape_changed() { set_continuous_collision_detection(is_continuous_collision_detection_enabled()); // Reset } -void RigidBodyBullet::reload_body() { +void RigidBodyBullet::do_reload_body() { if (space) { space->remove_rigid_body(this); if (get_main_shape()) { @@ -325,13 +325,15 @@ void RigidBodyBullet::set_space(SpaceBullet *p_space) { assert_no_constraints(); // Remove this object form the physics world + space->unregister_collision_object(this); space->remove_rigid_body(this); } space = p_space; if (space) { - space->add_rigid_body(this); + space->register_collision_object(this); + reload_body(); } } @@ -803,8 +805,8 @@ const btTransform &RigidBodyBullet::get_transform__bullet() const { } } -void RigidBodyBullet::reload_shapes() { - RigidCollisionObjectBullet::reload_shapes(); +void RigidBodyBullet::do_reload_shapes() { + RigidCollisionObjectBullet::do_reload_shapes(); const btScalar invMass = btBody->getInvMass(); const btScalar mass = invMass == 0 ? 0 : 1 / invMass; diff --git a/modules/bullet/rigid_body_bullet.h b/modules/bullet/rigid_body_bullet.h index ddc9d2916a..135497b897 100644 --- a/modules/bullet/rigid_body_bullet.h +++ b/modules/bullet/rigid_body_bullet.h @@ -236,7 +236,7 @@ public: _FORCE_INLINE_ btRigidBody *get_bt_rigid_body() { return btBody; } virtual void main_shape_changed(); - virtual void reload_body(); + virtual void do_reload_body(); virtual void set_space(SpaceBullet *p_space); virtual void dispatch_callbacks(); @@ -315,7 +315,7 @@ public: virtual void set_transform__bullet(const btTransform &p_global_transform); virtual const btTransform &get_transform__bullet() const; - virtual void reload_shapes(); + virtual void do_reload_shapes(); virtual void on_enter_area(AreaBullet *p_area); virtual void on_exit_area(AreaBullet *p_area); diff --git a/modules/bullet/shape_bullet.cpp b/modules/bullet/shape_bullet.cpp index d53f1e7d17..f4550c2024 100644 --- a/modules/bullet/shape_bullet.cpp +++ b/modules/bullet/shape_bullet.cpp @@ -46,9 +46,15 @@ @author AndreaCatania */ -ShapeBullet::ShapeBullet() {} +ShapeBullet::ShapeBullet() { +} -ShapeBullet::~ShapeBullet() {} +ShapeBullet::~ShapeBullet() { + if (default_shape != nullptr) { + bulletdelete(default_shape); + default_shape = nullptr; + } +} btCollisionShape *ShapeBullet::create_bt_shape(const Vector3 &p_implicit_scale, real_t p_extra_edge) { btVector3 s; @@ -56,6 +62,22 @@ btCollisionShape *ShapeBullet::create_bt_shape(const Vector3 &p_implicit_scale, return create_bt_shape(s, p_extra_edge); } +btCollisionShape *ShapeBullet::create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge) { + if (p_extra_edge == 0.0 && (p_implicit_scale - btVector3(1, 1, 1)).length2() <= CMP_EPSILON) { + return default_shape; + } + + return internal_create_bt_shape(p_implicit_scale, p_extra_edge); +} + +void ShapeBullet::destroy_bt_shape(btCollisionShape *p_shape) const { + if (p_shape != default_shape && p_shape != old_default_shape) { + if (likely(p_shape != nullptr)) { + bulletdelete(p_shape); + } + } +} + btCollisionShape *ShapeBullet::prepare(btCollisionShape *p_btShape) const { p_btShape->setUserPointer(const_cast<ShapeBullet *>(this)); p_btShape->setMargin(margin); @@ -63,10 +85,21 @@ btCollisionShape *ShapeBullet::prepare(btCollisionShape *p_btShape) const { } void ShapeBullet::notifyShapeChanged() { + // Store the old shape ptr so to not lose the reference pointer. + old_default_shape = default_shape; + // Create the new default shape with the new data. + default_shape = internal_create_bt_shape(btVector3(1, 1, 1)); + for (Map<ShapeOwnerBullet *, int>::Element *E = owners.front(); E; E = E->next()) { ShapeOwnerBullet *owner = static_cast<ShapeOwnerBullet *>(E->key()); owner->shape_changed(owner->find_shape(this)); } + + if (old_default_shape) { + // At this point now one has the old default shape; just delete it. + bulletdelete(old_default_shape); + old_default_shape = nullptr; + } } void ShapeBullet::add_owner(ShapeOwnerBullet *p_owner) { @@ -186,7 +219,7 @@ void PlaneShapeBullet::setup(const Plane &p_plane) { notifyShapeChanged(); } -btCollisionShape *PlaneShapeBullet::create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge) { +btCollisionShape *PlaneShapeBullet::internal_create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge) { btVector3 btPlaneNormal; G_TO_B(plane.normal, btPlaneNormal); return prepare(PlaneShapeBullet::create_shape_plane(btPlaneNormal, plane.d)); @@ -214,7 +247,7 @@ void SphereShapeBullet::setup(real_t p_radius) { notifyShapeChanged(); } -btCollisionShape *SphereShapeBullet::create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge) { +btCollisionShape *SphereShapeBullet::internal_create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge) { return prepare(ShapeBullet::create_shape_sphere(radius * p_implicit_scale[0] + p_extra_edge)); } @@ -241,7 +274,7 @@ void BoxShapeBullet::setup(const Vector3 &p_half_extents) { notifyShapeChanged(); } -btCollisionShape *BoxShapeBullet::create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge) { +btCollisionShape *BoxShapeBullet::internal_create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge) { return prepare(ShapeBullet::create_shape_box((half_extents * p_implicit_scale) + btVector3(p_extra_edge, p_extra_edge, p_extra_edge))); } @@ -274,7 +307,7 @@ void CapsuleShapeBullet::setup(real_t p_height, real_t p_radius) { notifyShapeChanged(); } -btCollisionShape *CapsuleShapeBullet::create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge) { +btCollisionShape *CapsuleShapeBullet::internal_create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge) { return prepare(ShapeBullet::create_shape_capsule(radius * p_implicit_scale[0] + p_extra_edge, height * p_implicit_scale[1] + p_extra_edge)); } @@ -307,7 +340,7 @@ void CylinderShapeBullet::setup(real_t p_height, real_t p_radius) { notifyShapeChanged(); } -btCollisionShape *CylinderShapeBullet::create_bt_shape(const btVector3 &p_implicit_scale, real_t p_margin) { +btCollisionShape *CylinderShapeBullet::internal_create_bt_shape(const btVector3 &p_implicit_scale, real_t p_margin) { return prepare(ShapeBullet::create_shape_cylinder(radius * p_implicit_scale[0] + p_margin, height * p_implicit_scale[1] + p_margin)); } @@ -349,7 +382,7 @@ void ConvexPolygonShapeBullet::setup(const Vector<Vector3> &p_vertices) { notifyShapeChanged(); } -btCollisionShape *ConvexPolygonShapeBullet::create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge) { +btCollisionShape *ConvexPolygonShapeBullet::internal_create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge) { if (!vertices.size()) { // This is necessary since 0 vertices return prepare(ShapeBullet::create_shape_empty()); @@ -431,7 +464,7 @@ void ConcavePolygonShapeBullet::setup(Vector<Vector3> p_faces) { notifyShapeChanged(); } -btCollisionShape *ConcavePolygonShapeBullet::create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge) { +btCollisionShape *ConcavePolygonShapeBullet::internal_create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge) { btCollisionShape *cs = ShapeBullet::create_shape_concave(meshShape); if (!cs) { // This is necessary since if 0 faces the creation of concave return null @@ -555,7 +588,7 @@ void HeightMapShapeBullet::setup(Vector<real_t> &p_heights, int p_width, int p_d notifyShapeChanged(); } -btCollisionShape *HeightMapShapeBullet::create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge) { +btCollisionShape *HeightMapShapeBullet::internal_create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge) { btCollisionShape *cs(ShapeBullet::create_shape_height_field(heights, width, depth, min_height, max_height)); cs->setLocalScaling(p_implicit_scale); prepare(cs); @@ -588,6 +621,6 @@ void RayShapeBullet::setup(real_t p_length, bool p_slips_on_slope) { notifyShapeChanged(); } -btCollisionShape *RayShapeBullet::create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge) { +btCollisionShape *RayShapeBullet::internal_create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge) { return prepare(ShapeBullet::create_shape_ray(length * p_implicit_scale[1] + p_extra_edge, slips_on_slope)); } diff --git a/modules/bullet/shape_bullet.h b/modules/bullet/shape_bullet.h index a35a1d8a18..6ca4d36a23 100644 --- a/modules/bullet/shape_bullet.h +++ b/modules/bullet/shape_bullet.h @@ -53,6 +53,10 @@ class ShapeBullet : public RIDBullet { Map<ShapeOwnerBullet *, int> owners; real_t margin = 0.04; + // Contains the default shape. + btCollisionShape *default_shape = nullptr; + btCollisionShape *old_default_shape = nullptr; + protected: /// return self btCollisionShape *prepare(btCollisionShape *p_btShape) const; @@ -63,7 +67,11 @@ public: virtual ~ShapeBullet(); btCollisionShape *create_bt_shape(const Vector3 &p_implicit_scale, real_t p_extra_edge = 0); - virtual btCollisionShape *create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge = 0) = 0; + btCollisionShape *create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge = 0); + + void destroy_bt_shape(btCollisionShape *p_shape) const; + + virtual btCollisionShape *internal_create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge = 0) = 0; void add_owner(ShapeOwnerBullet *p_owner); void remove_owner(ShapeOwnerBullet *p_owner, bool p_permanentlyFromThisBody = false); @@ -102,7 +110,7 @@ public: virtual void set_data(const Variant &p_data); virtual Variant get_data() const; virtual PhysicsServer3D::ShapeType get_type() const; - virtual btCollisionShape *create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge = 0); + virtual btCollisionShape *internal_create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge = 0); private: void setup(const Plane &p_plane); @@ -118,7 +126,7 @@ public: virtual void set_data(const Variant &p_data); virtual Variant get_data() const; virtual PhysicsServer3D::ShapeType get_type() const; - virtual btCollisionShape *create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge = 0); + virtual btCollisionShape *internal_create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge = 0); private: void setup(real_t p_radius); @@ -134,7 +142,7 @@ public: virtual void set_data(const Variant &p_data); virtual Variant get_data() const; virtual PhysicsServer3D::ShapeType get_type() const; - virtual btCollisionShape *create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge = 0); + virtual btCollisionShape *internal_create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge = 0); private: void setup(const Vector3 &p_half_extents); @@ -152,7 +160,7 @@ public: virtual void set_data(const Variant &p_data); virtual Variant get_data() const; virtual PhysicsServer3D::ShapeType get_type() const; - virtual btCollisionShape *create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge = 0); + virtual btCollisionShape *internal_create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge = 0); private: void setup(real_t p_height, real_t p_radius); @@ -170,7 +178,7 @@ public: virtual void set_data(const Variant &p_data); virtual Variant get_data() const; virtual PhysicsServer3D::ShapeType get_type() const; - virtual btCollisionShape *create_bt_shape(const btVector3 &p_implicit_scale, real_t p_margin = 0); + virtual btCollisionShape *internal_create_bt_shape(const btVector3 &p_implicit_scale, real_t p_margin = 0); private: void setup(real_t p_height, real_t p_radius); @@ -186,7 +194,7 @@ public: void get_vertices(Vector<Vector3> &out_vertices); virtual Variant get_data() const; virtual PhysicsServer3D::ShapeType get_type() const; - virtual btCollisionShape *create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge = 0); + virtual btCollisionShape *internal_create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge = 0); private: void setup(const Vector<Vector3> &p_vertices); @@ -204,7 +212,7 @@ public: virtual void set_data(const Variant &p_data); virtual Variant get_data() const; virtual PhysicsServer3D::ShapeType get_type() const; - virtual btCollisionShape *create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge = 0); + virtual btCollisionShape *internal_create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge = 0); private: void setup(Vector<Vector3> p_faces); @@ -223,7 +231,7 @@ public: virtual void set_data(const Variant &p_data); virtual Variant get_data() const; virtual PhysicsServer3D::ShapeType get_type() const; - virtual btCollisionShape *create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge = 0); + virtual btCollisionShape *internal_create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge = 0); private: void setup(Vector<real_t> &p_heights, int p_width, int p_depth, real_t p_min_height, real_t p_max_height); @@ -239,7 +247,7 @@ public: virtual void set_data(const Variant &p_data); virtual Variant get_data() const; virtual PhysicsServer3D::ShapeType get_type() const; - virtual btCollisionShape *create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge = 0); + virtual btCollisionShape *internal_create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge = 0); private: void setup(real_t p_length, bool p_slips_on_slope); diff --git a/modules/bullet/soft_body_bullet.cpp b/modules/bullet/soft_body_bullet.cpp index 6794d6c313..3fccd3d8a2 100644 --- a/modules/bullet/soft_body_bullet.cpp +++ b/modules/bullet/soft_body_bullet.cpp @@ -41,7 +41,7 @@ SoftBodyBullet::SoftBodyBullet() : SoftBodyBullet::~SoftBodyBullet() { } -void SoftBodyBullet::reload_body() { +void SoftBodyBullet::do_reload_body() { if (space) { space->remove_soft_body(this); space->add_soft_body(this); @@ -51,13 +51,15 @@ void SoftBodyBullet::reload_body() { void SoftBodyBullet::set_space(SpaceBullet *p_space) { if (space) { isScratched = false; + space->unregister_collision_object(this); space->remove_soft_body(this); } space = p_space; if (space) { - space->add_soft_body(this); + space->register_collision_object(this); + reload_body(); } } diff --git a/modules/bullet/soft_body_bullet.h b/modules/bullet/soft_body_bullet.h index da8a2412ed..ba968f4271 100644 --- a/modules/bullet/soft_body_bullet.h +++ b/modules/bullet/soft_body_bullet.h @@ -87,7 +87,7 @@ public: SoftBodyBullet(); ~SoftBodyBullet(); - virtual void reload_body(); + virtual void do_reload_body(); virtual void set_space(SpaceBullet *p_space); virtual void dispatch_callbacks() {} diff --git a/modules/bullet/space_bullet.cpp b/modules/bullet/space_bullet.cpp index cfe8cd5322..8204d7ed20 100644 --- a/modules/bullet/space_bullet.cpp +++ b/modules/bullet/space_bullet.cpp @@ -127,7 +127,7 @@ int BulletPhysicsDirectSpaceState::intersect_shape(const RID &p_shape, const Tra btCollisionShape *btShape = shape->create_bt_shape(p_xform.basis.get_scale_abs(), p_margin); if (!btShape->isConvex()) { - bulletdelete(btShape); + shape->destroy_bt_shape(btShape); ERR_PRINT("The shape is not a convex shape, then is not supported: shape type: " + itos(shape->get_type())); return 0; } @@ -147,7 +147,7 @@ int BulletPhysicsDirectSpaceState::intersect_shape(const RID &p_shape, const Tra btQuery.m_closestDistanceThreshold = 0; space->dynamicsWorld->contactTest(&collision_object, btQuery); - bulletdelete(btConvex); + shape->destroy_bt_shape(btShape); return btQuery.m_count; } @@ -167,7 +167,7 @@ bool BulletPhysicsDirectSpaceState::cast_motion(const RID &p_shape, const Transf btCollisionShape *btShape = shape->create_bt_shape(p_xform.basis.get_scale(), p_margin); if (!btShape->isConvex()) { - bulletdelete(btShape); + shape->destroy_bt_shape(btShape); ERR_PRINT("The shape is not a convex shape, then is not supported: shape type: " + itos(shape->get_type())); return false; } @@ -206,7 +206,7 @@ bool BulletPhysicsDirectSpaceState::cast_motion(const RID &p_shape, const Transf r_closest_unsafe = 1.0f; } - bulletdelete(bt_convex_shape); + shape->destroy_bt_shape(btShape); return true; // Mean success } @@ -221,7 +221,7 @@ bool BulletPhysicsDirectSpaceState::collide_shape(RID p_shape, const Transform & btCollisionShape *btShape = shape->create_bt_shape(p_shape_xform.basis.get_scale_abs(), p_margin); if (!btShape->isConvex()) { - bulletdelete(btShape); + shape->destroy_bt_shape(btShape); ERR_PRINT("The shape is not a convex shape, then is not supported: shape type: " + itos(shape->get_type())); return false; } @@ -242,7 +242,7 @@ bool BulletPhysicsDirectSpaceState::collide_shape(RID p_shape, const Transform & space->dynamicsWorld->contactTest(&collision_object, btQuery); r_result_count = btQuery.m_count; - bulletdelete(btConvex); + shape->destroy_bt_shape(btShape); return btQuery.m_count; } @@ -253,7 +253,7 @@ bool BulletPhysicsDirectSpaceState::rest_info(RID p_shape, const Transform &p_sh btCollisionShape *btShape = shape->create_bt_shape(p_shape_xform.basis.get_scale_abs(), p_margin); if (!btShape->isConvex()) { - bulletdelete(btShape); + shape->destroy_bt_shape(btShape); ERR_PRINT("The shape is not a convex shape, then is not supported: shape type: " + itos(shape->get_type())); return false; } @@ -273,7 +273,7 @@ bool BulletPhysicsDirectSpaceState::rest_info(RID p_shape, const Transform &p_sh btQuery.m_closestDistanceThreshold = 0; space->dynamicsWorld->contactTest(&collision_object, btQuery); - bulletdelete(btConvex); + shape->destroy_bt_shape(btShape); if (btQuery.m_collided) { if (btCollisionObject::CO_RIGID_BODY == btQuery.m_rest_info_collision_object->getInternalType()) { @@ -286,7 +286,7 @@ bool BulletPhysicsDirectSpaceState::rest_info(RID p_shape, const Transform &p_sh } Vector3 BulletPhysicsDirectSpaceState::get_closest_point_to_object_volume(RID p_object, const Vector3 p_point) const { - RigidCollisionObjectBullet *rigid_object = space->get_physics_server()->get_rigid_collisin_object(p_object); + RigidCollisionObjectBullet *rigid_object = space->get_physics_server()->get_rigid_collision_object(p_object); ERR_FAIL_COND_V(!rigid_object, Vector3()); btVector3 out_closest_point(0, 0, 0); @@ -349,9 +349,11 @@ SpaceBullet::~SpaceBullet() { } void SpaceBullet::flush_queries() { - const btCollisionObjectArray &colObjArray = dynamicsWorld->getCollisionObjectArray(); - for (int i = colObjArray.size() - 1; 0 <= i; --i) { - static_cast<CollisionObjectBullet *>(colObjArray[i]->getUserPointer())->dispatch_callbacks(); + const int size = collision_objects.size(); + CollisionObjectBullet **objects = collision_objects.ptrw(); + for (int i = 0; i < size; i += 1) { + objects[i]->prepare_object_for_dispatch(); + objects[i]->dispatch_callbacks(); } } @@ -448,16 +450,30 @@ real_t SpaceBullet::get_param(PhysicsServer3D::SpaceParameter p_param) { } void SpaceBullet::add_area(AreaBullet *p_area) { +#ifdef TOOLS_ENABLED + // This never happen, and there is no way for the user to trigger it. + // If in future a bug is introduced into this bullet integration and this + // function is called twice, the crash will notify the developer that will + // fix it even before do the eventual PR. + CRASH_COND(p_area->is_in_world); +#endif areas.push_back(p_area); dynamicsWorld->addCollisionObject(p_area->get_bt_ghost(), p_area->get_collision_layer(), p_area->get_collision_mask()); + p_area->is_in_world = true; } void SpaceBullet::remove_area(AreaBullet *p_area) { - areas.erase(p_area); - dynamicsWorld->removeCollisionObject(p_area->get_bt_ghost()); + if (p_area->is_in_world) { + areas.erase(p_area); + dynamicsWorld->removeCollisionObject(p_area->get_bt_ghost()); + p_area->is_in_world = false; + } } void SpaceBullet::reload_collision_filters(AreaBullet *p_area) { + if (p_area->is_in_world == false) { + return; + } btGhostObject *ghost_object = p_area->get_bt_ghost(); btBroadphaseProxy *ghost_proxy = ghost_object->getBroadphaseHandle(); @@ -467,24 +483,46 @@ void SpaceBullet::reload_collision_filters(AreaBullet *p_area) { dynamicsWorld->refreshBroadphaseProxy(ghost_object); } +void SpaceBullet::register_collision_object(CollisionObjectBullet *p_object) { + collision_objects.push_back(p_object); +} + +void SpaceBullet::unregister_collision_object(CollisionObjectBullet *p_object) { + collision_objects.erase(p_object); +} + void SpaceBullet::add_rigid_body(RigidBodyBullet *p_body) { +#ifdef TOOLS_ENABLED + // This never happen, and there is no way for the user to trigger it. + // If in future a bug is introduced into this bullet integration and this + // function is called twice, the crash will notify the developer that will + // fix it even before do the eventual PR. + CRASH_COND(p_body->is_in_world); +#endif if (p_body->is_static()) { dynamicsWorld->addCollisionObject(p_body->get_bt_rigid_body(), p_body->get_collision_layer(), p_body->get_collision_mask()); } else { dynamicsWorld->addRigidBody(p_body->get_bt_rigid_body(), p_body->get_collision_layer(), p_body->get_collision_mask()); p_body->scratch_space_override_modificator(); } + p_body->is_in_world = true; } void SpaceBullet::remove_rigid_body(RigidBodyBullet *p_body) { - if (p_body->is_static()) { - dynamicsWorld->removeCollisionObject(p_body->get_bt_rigid_body()); - } else { - dynamicsWorld->removeRigidBody(p_body->get_bt_rigid_body()); + if (p_body->is_in_world) { + if (p_body->is_static()) { + dynamicsWorld->removeCollisionObject(p_body->get_bt_rigid_body()); + } else { + dynamicsWorld->removeRigidBody(p_body->get_bt_rigid_body()); + } + p_body->is_in_world = false; } } void SpaceBullet::reload_collision_filters(RigidBodyBullet *p_body) { + if (p_body->is_in_world == false) { + return; + } btRigidBody *rigid_body = p_body->get_bt_rigid_body(); btBroadphaseProxy *body_proxy = rigid_body->getBroadphaseProxy(); diff --git a/modules/bullet/space_bullet.h b/modules/bullet/space_bullet.h index 5ff421ef52..ae4dc30274 100644 --- a/modules/bullet/space_bullet.h +++ b/modules/bullet/space_bullet.h @@ -110,6 +110,7 @@ class SpaceBullet : public RIDBullet { real_t linear_damp = 0.0; real_t angular_damp = 0.0; + Vector<CollisionObjectBullet *> collision_objects; Vector<AreaBullet *> areas; Vector<Vector3> contactDebug; @@ -124,9 +125,12 @@ public: real_t get_delta_time() { return delta_time; } void step(real_t p_delta_time); - _FORCE_INLINE_ btBroadphaseInterface *get_broadphase() { return broadphase; } - _FORCE_INLINE_ btCollisionDispatcher *get_dispatcher() { return dispatcher; } - _FORCE_INLINE_ btSoftBodyWorldInfo *get_soft_body_world_info() { return soft_body_world_info; } + _FORCE_INLINE_ btBroadphaseInterface *get_broadphase() const { return broadphase; } + _FORCE_INLINE_ btDefaultCollisionConfiguration *get_collision_configuration() const { return collisionConfiguration; } + _FORCE_INLINE_ btCollisionDispatcher *get_dispatcher() const { return dispatcher; } + _FORCE_INLINE_ btConstraintSolver *get_solver() const { return solver; } + _FORCE_INLINE_ btDiscreteDynamicsWorld *get_dynamic_world() const { return dynamicsWorld; } + _FORCE_INLINE_ btSoftBodyWorldInfo *get_soft_body_world_info() const { return soft_body_world_info; } _FORCE_INLINE_ bool is_using_soft_world() { return soft_body_world_info; } /// Used to set some parameters to Bullet world @@ -147,6 +151,9 @@ public: void remove_area(AreaBullet *p_area); void reload_collision_filters(AreaBullet *p_area); + void register_collision_object(CollisionObjectBullet *p_object); + void unregister_collision_object(CollisionObjectBullet *p_object); + void add_rigid_body(RigidBodyBullet *p_body); void remove_rigid_body(RigidBodyBullet *p_body); void reload_collision_filters(RigidBodyBullet *p_body); diff --git a/modules/gdnative/gdnative/packed_arrays.cpp b/modules/gdnative/gdnative/packed_arrays.cpp index fc71d50289..de93c1d9b3 100644 --- a/modules/gdnative/gdnative/packed_arrays.cpp +++ b/modules/gdnative/gdnative/packed_arrays.cpp @@ -104,6 +104,16 @@ godot_error GDAPI godot_packed_byte_array_insert(godot_packed_byte_array *p_self return (godot_error)self->insert(p_idx, p_data); } +godot_bool GDAPI godot_packed_byte_array_has(godot_packed_byte_array *p_self, const uint8_t p_value) { + Vector<uint8_t> *self = (Vector<uint8_t> *)p_self; + return (godot_bool)self->has(p_value); +} + +void GDAPI godot_packed_byte_array_sort(godot_packed_byte_array *p_self) { + Vector<uint8_t> *self = (Vector<uint8_t> *)p_self; + self->sort(); +} + void GDAPI godot_packed_byte_array_invert(godot_packed_byte_array *p_self) { Vector<uint8_t> *self = (Vector<uint8_t> *)p_self; self->invert(); @@ -198,6 +208,16 @@ godot_error GDAPI godot_packed_int32_array_insert(godot_packed_int32_array *p_se return (godot_error)self->insert(p_idx, p_data); } +godot_bool GDAPI godot_packed_int32_array_has(godot_packed_int32_array *p_self, const int32_t p_value) { + Vector<int32_t> *self = (Vector<int32_t> *)p_self; + return (godot_bool)self->has(p_value); +} + +void GDAPI godot_packed_int32_array_sort(godot_packed_int32_array *p_self) { + Vector<int32_t> *self = (Vector<int32_t> *)p_self; + self->sort(); +} + void GDAPI godot_packed_int32_array_invert(godot_packed_int32_array *p_self) { Vector<int32_t> *self = (Vector<int32_t> *)p_self; self->invert(); @@ -292,6 +312,16 @@ godot_error GDAPI godot_packed_int64_array_insert(godot_packed_int64_array *p_se return (godot_error)self->insert(p_idx, p_data); } +godot_bool GDAPI godot_packed_int64_array_has(godot_packed_int64_array *p_self, const int64_t p_value) { + Vector<int64_t> *self = (Vector<int64_t> *)p_self; + return (godot_bool)self->has(p_value); +} + +void GDAPI godot_packed_int64_array_sort(godot_packed_int64_array *p_self) { + Vector<int64_t> *self = (Vector<int64_t> *)p_self; + self->sort(); +} + void GDAPI godot_packed_int64_array_invert(godot_packed_int64_array *p_self) { Vector<int64_t> *self = (Vector<int64_t> *)p_self; self->invert(); @@ -386,6 +416,16 @@ godot_error GDAPI godot_packed_float32_array_insert(godot_packed_float32_array * return (godot_error)self->insert(p_idx, p_data); } +godot_bool GDAPI godot_packed_float32_array_has(godot_packed_float32_array *p_self, const float p_value) { + Vector<float> *self = (Vector<float> *)p_self; + return (godot_bool)self->has(p_value); +} + +void GDAPI godot_packed_float32_array_sort(godot_packed_float32_array *p_self) { + Vector<float> *self = (Vector<float> *)p_self; + self->sort(); +} + void GDAPI godot_packed_float32_array_invert(godot_packed_float32_array *p_self) { Vector<float> *self = (Vector<float> *)p_self; self->invert(); @@ -480,6 +520,16 @@ godot_error GDAPI godot_packed_float64_array_insert(godot_packed_float64_array * return (godot_error)self->insert(p_idx, p_data); } +godot_bool GDAPI godot_packed_float64_array_has(godot_packed_float64_array *p_self, const double p_value) { + Vector<double> *self = (Vector<double> *)p_self; + return (godot_bool)self->has(p_value); +} + +void GDAPI godot_packed_float64_array_sort(godot_packed_float64_array *p_self) { + Vector<double> *self = (Vector<double> *)p_self; + self->sort(); +} + void GDAPI godot_packed_float64_array_invert(godot_packed_float64_array *p_self) { Vector<double> *self = (Vector<double> *)p_self; self->invert(); @@ -576,6 +626,17 @@ godot_error GDAPI godot_packed_string_array_insert(godot_packed_string_array *p_ return (godot_error)self->insert(p_idx, s); } +godot_bool GDAPI godot_packed_string_array_has(godot_packed_string_array *p_self, const godot_string *p_value) { + Vector<String> *self = (Vector<String> *)p_self; + String &s = *(String *)p_value; + return (godot_bool)self->has(s); +} + +void GDAPI godot_packed_string_array_sort(godot_packed_string_array *p_self) { + Vector<String> *self = (Vector<String> *)p_self; + self->sort(); +} + void GDAPI godot_packed_string_array_invert(godot_packed_string_array *p_self) { Vector<String> *self = (Vector<String> *)p_self; self->invert(); @@ -678,6 +739,17 @@ godot_error GDAPI godot_packed_vector2_array_insert(godot_packed_vector2_array * return (godot_error)self->insert(p_idx, s); } +godot_bool GDAPI godot_packed_vector2_array_has(godot_packed_vector2_array *p_self, const godot_vector2 *p_value) { + Vector<Vector2> *self = (Vector<Vector2> *)p_self; + Vector2 &v = *(Vector2 *)p_value; + return (godot_bool)self->has(v); +} + +void GDAPI godot_packed_vector2_array_sort(godot_packed_vector2_array *p_self) { + Vector<Vector2> *self = (Vector<Vector2> *)p_self; + self->sort(); +} + void GDAPI godot_packed_vector2_array_invert(godot_packed_vector2_array *p_self) { Vector<Vector2> *self = (Vector<Vector2> *)p_self; self->invert(); @@ -779,6 +851,17 @@ godot_error GDAPI godot_packed_vector3_array_insert(godot_packed_vector3_array * return (godot_error)self->insert(p_idx, s); } +godot_bool GDAPI godot_packed_vector3_array_has(godot_packed_vector3_array *p_self, const godot_vector3 *p_value) { + Vector<Vector3> *self = (Vector<Vector3> *)p_self; + Vector3 &v = *(Vector3 *)p_value; + return (godot_bool)self->has(v); +} + +void GDAPI godot_packed_vector3_array_sort(godot_packed_vector3_array *p_self) { + Vector<Vector3> *self = (Vector<Vector3> *)p_self; + self->sort(); +} + void GDAPI godot_packed_vector3_array_invert(godot_packed_vector3_array *p_self) { Vector<Vector3> *self = (Vector<Vector3> *)p_self; self->invert(); @@ -880,6 +963,17 @@ godot_error GDAPI godot_packed_color_array_insert(godot_packed_color_array *p_se return (godot_error)self->insert(p_idx, s); } +godot_bool GDAPI godot_packed_color_array_has(godot_packed_color_array *p_self, const godot_color *p_value) { + Vector<Color> *self = (Vector<Color> *)p_self; + Color &c = *(Color *)p_value; + return (godot_bool)self->has(c); +} + +void GDAPI godot_packed_color_array_sort(godot_packed_color_array *p_self) { + Vector<Color> *self = (Vector<Color> *)p_self; + self->sort(); +} + void GDAPI godot_packed_color_array_invert(godot_packed_color_array *p_self) { Vector<Color> *self = (Vector<Color> *)p_self; self->invert(); diff --git a/modules/gdnative/gdnative_api.json b/modules/gdnative/gdnative_api.json index 1284ebbd66..eb122089b6 100644 --- a/modules/gdnative/gdnative_api.json +++ b/modules/gdnative/gdnative_api.json @@ -918,42 +918,42 @@ ["const godot_variant **", "p_arguments"], ["godot_int", "p_argcount"] ] - }, + }, { "name": "godot_callable_is_null", "return_type": "godot_bool", "arguments": [ ["const godot_callable *", "p_self"] ] - }, + }, { "name": "godot_callable_is_custom", "return_type": "godot_bool", "arguments": [ ["const godot_callable *", "p_self"] ] - }, + }, { "name": "godot_callable_is_standard", "return_type": "godot_bool", "arguments": [ ["const godot_callable *", "p_self"] ] - }, + }, { "name": "godot_callable_get_object", "return_type": "godot_object *", "arguments": [ ["const godot_callable *", "p_self"] ] - }, + }, { "name": "godot_callable_get_object_id", "return_type": "uint64_t", "arguments": [ ["const godot_callable *", "p_self"] ] - }, + }, { "name": "godot_callable_get_method", "return_type": "godot_string_name", @@ -1093,14 +1093,14 @@ "arguments": [ ["const godot_signal *", "p_self"] ] - }, + }, { "name": "godot_signal_as_string", "return_type": "godot_string", "arguments": [ ["const godot_signal *", "p_self"] ] - }, + }, { "name": "godot_signal_operator_equal", "return_type": "godot_bool", @@ -1108,7 +1108,7 @@ ["const godot_signal *", "p_self"], ["const godot_signal *", "p_other"] ] - }, + }, { "name": "godot_signal_operator_less", "return_type": "godot_bool", @@ -1671,6 +1671,21 @@ ] }, { + "name": "godot_packed_byte_array_has", + "return_type": "godot_bool", + "arguments": [ + ["godot_packed_byte_array *", "p_self"], + ["const uint8_t", "p_value"] + ] + }, + { + "name": "godot_packed_byte_array_sort", + "return_type": "void", + "arguments": [ + ["godot_packed_byte_array *", "p_self"] + ] + }, + { "name": "godot_packed_byte_array_invert", "return_type": "void", "arguments": [ @@ -1802,6 +1817,21 @@ ] }, { + "name": "godot_packed_int32_array_has", + "return_type": "godot_bool", + "arguments": [ + ["godot_packed_int32_array *", "p_self"], + ["const int32_t", "p_value"] + ] + }, + { + "name": "godot_packed_int32_array_sort", + "return_type": "void", + "arguments": [ + ["godot_packed_int32_array *", "p_self"] + ] + }, + { "name": "godot_packed_int32_array_invert", "return_type": "void", "arguments": [ @@ -1933,6 +1963,21 @@ ] }, { + "name": "godot_packed_int64_array_has", + "return_type": "godot_bool", + "arguments": [ + ["godot_packed_int64_array *", "p_self"], + ["const int64_t", "p_value"] + ] + }, + { + "name": "godot_packed_int64_array_sort", + "return_type": "void", + "arguments": [ + ["godot_packed_int64_array *", "p_self"] + ] + }, + { "name": "godot_packed_int64_array_invert", "return_type": "void", "arguments": [ @@ -2064,6 +2109,21 @@ ] }, { + "name": "godot_packed_float32_array_has", + "return_type": "godot_bool", + "arguments": [ + ["godot_packed_float32_array *", "p_self"], + ["const float", "p_value"] + ] + }, + { + "name": "godot_packed_float32_array_sort", + "return_type": "void", + "arguments": [ + ["godot_packed_float32_array *", "p_self"] + ] + }, + { "name": "godot_packed_float32_array_invert", "return_type": "void", "arguments": [ @@ -2195,6 +2255,21 @@ ] }, { + "name": "godot_packed_float64_array_has", + "return_type": "godot_bool", + "arguments": [ + ["godot_packed_float64_array *", "p_self"], + ["const double", "p_value"] + ] + }, + { + "name": "godot_packed_float64_array_sort", + "return_type": "void", + "arguments": [ + ["godot_packed_float64_array *", "p_self"] + ] + }, + { "name": "godot_packed_float64_array_invert", "return_type": "void", "arguments": [ @@ -2326,6 +2401,21 @@ ] }, { + "name": "godot_packed_string_array_has", + "return_type": "godot_bool", + "arguments": [ + ["godot_packed_string_array *", "p_self"], + ["const godot_string *", "p_value"] + ] + }, + { + "name": "godot_packed_string_array_sort", + "return_type": "void", + "arguments": [ + ["godot_packed_string_array *", "p_self"] + ] + }, + { "name": "godot_packed_string_array_invert", "return_type": "void", "arguments": [ @@ -2457,6 +2547,21 @@ ] }, { + "name": "godot_packed_vector2_array_has", + "return_type": "godot_bool", + "arguments": [ + ["godot_packed_vector2_array *", "p_self"], + ["const godot_vector2 *", "p_value"] + ] + }, + { + "name": "godot_packed_vector2_array_sort", + "return_type": "void", + "arguments": [ + ["godot_packed_vector2_array *", "p_self"] + ] + }, + { "name": "godot_packed_vector2_array_invert", "return_type": "void", "arguments": [ @@ -2588,6 +2693,21 @@ ] }, { + "name": "godot_packed_vector3_array_has", + "return_type": "godot_bool", + "arguments": [ + ["godot_packed_vector3_array *", "p_self"], + ["const godot_vector3 *", "p_value"] + ] + }, + { + "name": "godot_packed_vector3_array_sort", + "return_type": "void", + "arguments": [ + ["godot_packed_vector3_array *", "p_self"] + ] + }, + { "name": "godot_packed_vector3_array_invert", "return_type": "void", "arguments": [ @@ -2719,6 +2839,21 @@ ] }, { + "name": "godot_packed_color_array_has", + "return_type": "godot_bool", + "arguments": [ + ["godot_packed_color_array *", "p_self"], + ["const godot_color *", "p_value"] + ] + }, + { + "name": "godot_packed_color_array_sort", + "return_type": "void", + "arguments": [ + ["godot_packed_color_array *", "p_self"] + ] + }, + { "name": "godot_packed_color_array_invert", "return_type": "void", "arguments": [ @@ -2748,7 +2883,7 @@ ["godot_packed_color_array *", "p_self"], ["const godot_int", "p_size"] ] - }, + }, { "name": "godot_packed_color_array_ptr", "return_type": "const godot_color *", @@ -5463,7 +5598,7 @@ ["godot_variant *", "r_dest"], ["const godot_packed_int64_array *", "p_pia"] ] - }, + }, { "name": "godot_variant_new_packed_float32_array", "return_type": "void", diff --git a/modules/gdnative/include/gdnative/packed_arrays.h b/modules/gdnative/include/gdnative/packed_arrays.h index 87d467a5b8..6a1727d76f 100644 --- a/modules/gdnative/include/gdnative/packed_arrays.h +++ b/modules/gdnative/include/gdnative/packed_arrays.h @@ -167,6 +167,10 @@ void GDAPI godot_packed_byte_array_append_array(godot_packed_byte_array *p_self, godot_error GDAPI godot_packed_byte_array_insert(godot_packed_byte_array *p_self, const godot_int p_idx, const uint8_t p_data); +godot_bool GDAPI godot_packed_byte_array_has(godot_packed_byte_array *p_self, const uint8_t p_value); + +void GDAPI godot_packed_byte_array_sort(godot_packed_byte_array *p_self); + void GDAPI godot_packed_byte_array_invert(godot_packed_byte_array *p_self); void GDAPI godot_packed_byte_array_push_back(godot_packed_byte_array *p_self, const uint8_t p_data); @@ -199,6 +203,10 @@ void GDAPI godot_packed_int32_array_append_array(godot_packed_int32_array *p_sel godot_error GDAPI godot_packed_int32_array_insert(godot_packed_int32_array *p_self, const godot_int p_idx, const int32_t p_data); +godot_bool GDAPI godot_packed_int32_array_has(godot_packed_int32_array *p_self, const int32_t p_value); + +void GDAPI godot_packed_int32_array_sort(godot_packed_int32_array *p_self); + void GDAPI godot_packed_int32_array_invert(godot_packed_int32_array *p_self); void GDAPI godot_packed_int32_array_push_back(godot_packed_int32_array *p_self, const int32_t p_data); @@ -231,6 +239,10 @@ void GDAPI godot_packed_int64_array_append_array(godot_packed_int64_array *p_sel godot_error GDAPI godot_packed_int64_array_insert(godot_packed_int64_array *p_self, const godot_int p_idx, const int64_t p_data); +godot_bool GDAPI godot_packed_int64_array_has(godot_packed_int64_array *p_self, const int64_t p_value); + +void GDAPI godot_packed_int64_array_sort(godot_packed_int64_array *p_self); + void GDAPI godot_packed_int64_array_invert(godot_packed_int64_array *p_self); void GDAPI godot_packed_int64_array_push_back(godot_packed_int64_array *p_self, const int64_t p_data); @@ -263,6 +275,10 @@ void GDAPI godot_packed_float32_array_append_array(godot_packed_float32_array *p godot_error GDAPI godot_packed_float32_array_insert(godot_packed_float32_array *p_self, const godot_int p_idx, const float p_data); +godot_bool GDAPI godot_packed_float32_array_has(godot_packed_float32_array *p_self, const float p_value); + +void GDAPI godot_packed_float32_array_sort(godot_packed_float32_array *p_self); + void GDAPI godot_packed_float32_array_invert(godot_packed_float32_array *p_self); void GDAPI godot_packed_float32_array_push_back(godot_packed_float32_array *p_self, const float p_data); @@ -295,6 +311,10 @@ void GDAPI godot_packed_float64_array_append_array(godot_packed_float64_array *p godot_error GDAPI godot_packed_float64_array_insert(godot_packed_float64_array *p_self, const godot_int p_idx, const double p_data); +godot_bool GDAPI godot_packed_float64_array_has(godot_packed_float64_array *p_self, const double p_value); + +void GDAPI godot_packed_float64_array_sort(godot_packed_float64_array *p_self); + void GDAPI godot_packed_float64_array_invert(godot_packed_float64_array *p_self); void GDAPI godot_packed_float64_array_push_back(godot_packed_float64_array *p_self, const double p_data); @@ -327,6 +347,10 @@ void GDAPI godot_packed_string_array_append_array(godot_packed_string_array *p_s godot_error GDAPI godot_packed_string_array_insert(godot_packed_string_array *p_self, const godot_int p_idx, const godot_string *p_data); +godot_bool GDAPI godot_packed_string_array_has(godot_packed_string_array *p_self, const godot_string *p_value); + +void GDAPI godot_packed_string_array_sort(godot_packed_string_array *p_self); + void GDAPI godot_packed_string_array_invert(godot_packed_string_array *p_self); void GDAPI godot_packed_string_array_push_back(godot_packed_string_array *p_self, const godot_string *p_data); @@ -359,6 +383,10 @@ void GDAPI godot_packed_vector2_array_append_array(godot_packed_vector2_array *p godot_error GDAPI godot_packed_vector2_array_insert(godot_packed_vector2_array *p_self, const godot_int p_idx, const godot_vector2 *p_data); +godot_bool GDAPI godot_packed_vector2_array_has(godot_packed_vector2_array *p_self, const godot_vector2 *p_value); + +void GDAPI godot_packed_vector2_array_sort(godot_packed_vector2_array *p_self); + void GDAPI godot_packed_vector2_array_invert(godot_packed_vector2_array *p_self); void GDAPI godot_packed_vector2_array_push_back(godot_packed_vector2_array *p_self, const godot_vector2 *p_data); @@ -391,6 +419,10 @@ void GDAPI godot_packed_vector3_array_append_array(godot_packed_vector3_array *p godot_error GDAPI godot_packed_vector3_array_insert(godot_packed_vector3_array *p_self, const godot_int p_idx, const godot_vector3 *p_data); +godot_bool GDAPI godot_packed_vector3_array_has(godot_packed_vector3_array *p_self, const godot_vector3 *p_value); + +void GDAPI godot_packed_vector3_array_sort(godot_packed_vector3_array *p_self); + void GDAPI godot_packed_vector3_array_invert(godot_packed_vector3_array *p_self); void GDAPI godot_packed_vector3_array_push_back(godot_packed_vector3_array *p_self, const godot_vector3 *p_data); @@ -423,6 +455,10 @@ void GDAPI godot_packed_color_array_append_array(godot_packed_color_array *p_sel godot_error GDAPI godot_packed_color_array_insert(godot_packed_color_array *p_self, const godot_int p_idx, const godot_color *p_data); +godot_bool GDAPI godot_packed_color_array_has(godot_packed_color_array *p_self, const godot_color *p_value); + +void GDAPI godot_packed_color_array_sort(godot_packed_color_array *p_self); + void GDAPI godot_packed_color_array_invert(godot_packed_color_array *p_self); void GDAPI godot_packed_color_array_push_back(godot_packed_color_array *p_self, const godot_color *p_data); diff --git a/modules/gdscript/editor/gdscript_translation_parser_plugin.cpp b/modules/gdscript/editor/gdscript_translation_parser_plugin.cpp index a1b18978fc..6d454e43f2 100644 --- a/modules/gdscript/editor/gdscript_translation_parser_plugin.cpp +++ b/modules/gdscript/editor/gdscript_translation_parser_plugin.cpp @@ -38,25 +38,8 @@ void GDScriptEditorTranslationParserPlugin::get_recognized_extensions(List<Strin } Error GDScriptEditorTranslationParserPlugin::parse_file(const String &p_path, Vector<String> *r_extracted_strings) { - List<String> extensions; - get_recognized_extensions(&extensions); - bool extension_valid = false; - for (auto E = extensions.front(); E; E = E->next()) { - if (p_path.get_extension() == E->get()) { - extension_valid = true; - break; - } - } - - if (!extension_valid) { - Vector<String> temp; - for (auto E = extensions.front(); E; E = E->next()) { - temp.push_back(E->get()); - } - String valid_extensions = String(", ").join(temp); - ERR_PRINT("Argument p_path \"" + p_path + "\" has wrong extension. List of valid extensions: " + valid_extensions); - return ERR_INVALID_PARAMETER; - } + // Parse and match all GDScript function API that involves translation string. + // E.g get_node("Label").text = "something", var test = tr("something"), "something" will be matched and collected. Error err; RES loaded_res = ResourceLoader::load(p_path, "", false, &err); @@ -66,26 +49,18 @@ Error GDScriptEditorTranslationParserPlugin::parse_file(const String &p_path, Ve } Ref<GDScript> gdscript = loaded_res; - parse_text(gdscript->get_source_code(), r_extracted_strings); - - return OK; -} - -void GDScriptEditorTranslationParserPlugin::parse_text(const String &p_text, Vector<String> *r_extracted_strings) { - // Parse and match all GDScript function API that involves translation string. - // E.g get_node("Label").text = "something", var test = tr("something"), "something" will be matched and collected. - + String source_code = gdscript->get_source_code(); Vector<String> parsed_strings; // Search translation strings with RegEx. regex.clear(); regex.compile(String("|").join(patterns)); - Array results = regex.search_all(p_text); + Array results = regex.search_all(source_code); _get_captured_strings(results, &parsed_strings); // Special handling for FileDialog. Vector<String> temp; - _parse_file_dialog(p_text, &temp); + _parse_file_dialog(source_code, &temp); parsed_strings.append_array(temp); // Filter out / and + @@ -97,6 +72,8 @@ void GDScriptEditorTranslationParserPlugin::parse_text(const String &p_text, Vec } r_extracted_strings->append_array(parsed_strings); + + return OK; } void GDScriptEditorTranslationParserPlugin::_parse_file_dialog(const String &p_source_code, Vector<String> *r_output) { diff --git a/modules/gdscript/editor/gdscript_translation_parser_plugin.h b/modules/gdscript/editor/gdscript_translation_parser_plugin.h index ef967845b9..efef8f8249 100644 --- a/modules/gdscript/editor/gdscript_translation_parser_plugin.h +++ b/modules/gdscript/editor/gdscript_translation_parser_plugin.h @@ -48,7 +48,6 @@ class GDScriptEditorTranslationParserPlugin : public EditorTranslationParserPlug public: virtual Error parse_file(const String &p_path, Vector<String> *r_extracted_strings); - virtual void parse_text(const String &p_text, Vector<String> *r_extracted_strings); virtual void get_recognized_extensions(List<String> *r_extensions) const; GDScriptEditorTranslationParserPlugin(); diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index 632407c61f..01af562327 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -2001,114 +2001,116 @@ String GDScriptLanguage::get_global_class_name(const String &p_path, String *r_b String GDScriptWarning::get_message() const { #define CHECK_SYMBOLS(m_amount) ERR_FAIL_COND_V(symbols.size() < m_amount, String()); + String msg; + switch (code) { case UNASSIGNED_VARIABLE_OP_ASSIGN: { CHECK_SYMBOLS(1); - return "Using assignment with operation but the variable '" + symbols[0] + "' was not previously assigned a value."; + msg = "Using assignment with operation but the variable '" + symbols[0] + "' was not previously assigned a value."; } break; case UNASSIGNED_VARIABLE: { CHECK_SYMBOLS(1); - return "The variable '" + symbols[0] + "' was used but never assigned a value."; + msg = "The variable '" + symbols[0] + "' was used but never assigned a value."; } break; case UNUSED_VARIABLE: { CHECK_SYMBOLS(1); - return "The local variable '" + symbols[0] + "' is declared but never used in the block. If this is intended, prefix it with an underscore: '_" + symbols[0] + "'"; + msg = "The local variable '" + symbols[0] + "' is declared but never used in the block. If this is intended, prefix it with an underscore: '_" + symbols[0] + "'"; } break; case SHADOWED_VARIABLE: { CHECK_SYMBOLS(2); - return "The local variable '" + symbols[0] + "' is shadowing an already-defined variable at line " + symbols[1] + "."; + msg = "The local variable '" + symbols[0] + "' is shadowing an already-defined variable at line " + symbols[1] + "."; } break; case UNUSED_CLASS_VARIABLE: { CHECK_SYMBOLS(1); - return "The class variable '" + symbols[0] + "' is declared but never used in the script."; + msg = "The class variable '" + symbols[0] + "' is declared but never used in the script."; } break; case UNUSED_ARGUMENT: { CHECK_SYMBOLS(2); - return "The argument '" + symbols[1] + "' is never used in the function '" + symbols[0] + "'. If this is intended, prefix it with an underscore: '_" + symbols[1] + "'"; + msg = "The argument '" + symbols[1] + "' is never used in the function '" + symbols[0] + "'. If this is intended, prefix it with an underscore: '_" + symbols[1] + "'"; } break; case UNREACHABLE_CODE: { CHECK_SYMBOLS(1); - return "Unreachable code (statement after return) in function '" + symbols[0] + "()'."; + msg = "Unreachable code (statement after return) in function '" + symbols[0] + "()'."; } break; case STANDALONE_EXPRESSION: { - return "Standalone expression (the line has no effect)."; + msg = "Standalone expression (the line has no effect)."; } break; case VOID_ASSIGNMENT: { CHECK_SYMBOLS(1); - return "Assignment operation, but the function '" + symbols[0] + "()' returns void."; + msg = "Assignment operation, but the function '" + symbols[0] + "()' returns void."; } break; case NARROWING_CONVERSION: { - return "Narrowing conversion (float is converted to int and loses precision)."; + msg = "Narrowing conversion (float is converted to int and loses precision)."; } break; case FUNCTION_MAY_YIELD: { CHECK_SYMBOLS(1); - return "Assigned variable is typed but the function '" + symbols[0] + "()' may yield and return a GDScriptFunctionState instead."; + msg = "Assigned variable is typed but the function '" + symbols[0] + "()' may yield and return a GDScriptFunctionState instead."; } break; case VARIABLE_CONFLICTS_FUNCTION: { CHECK_SYMBOLS(1); - return "Variable declaration of '" + symbols[0] + "' conflicts with a function of the same name."; + msg = "Variable declaration of '" + symbols[0] + "' conflicts with a function of the same name."; } break; case FUNCTION_CONFLICTS_VARIABLE: { CHECK_SYMBOLS(1); - return "Function declaration of '" + symbols[0] + "()' conflicts with a variable of the same name."; + msg = "Function declaration of '" + symbols[0] + "()' conflicts with a variable of the same name."; } break; case FUNCTION_CONFLICTS_CONSTANT: { CHECK_SYMBOLS(1); - return "Function declaration of '" + symbols[0] + "()' conflicts with a constant of the same name."; + msg = "Function declaration of '" + symbols[0] + "()' conflicts with a constant of the same name."; } break; case INCOMPATIBLE_TERNARY: { - return "Values of the ternary conditional are not mutually compatible."; + msg = "Values of the ternary conditional are not mutually compatible."; } break; case UNUSED_SIGNAL: { CHECK_SYMBOLS(1); - return "The signal '" + symbols[0] + "' is declared but never emitted."; + msg = "The signal '" + symbols[0] + "' is declared but never emitted."; } break; case RETURN_VALUE_DISCARDED: { CHECK_SYMBOLS(1); - return "The function '" + symbols[0] + "()' returns a value, but this value is never used."; + msg = "The function '" + symbols[0] + "()' returns a value, but this value is never used."; } break; case PROPERTY_USED_AS_FUNCTION: { CHECK_SYMBOLS(2); - return "The method '" + symbols[0] + "()' was not found in base '" + symbols[1] + "' but there's a property with the same name. Did you mean to access it?"; + msg = "The method '" + symbols[0] + "()' was not found in base '" + symbols[1] + "' but there's a property with the same name. Did you mean to access it?"; } break; case CONSTANT_USED_AS_FUNCTION: { CHECK_SYMBOLS(2); - return "The method '" + symbols[0] + "()' was not found in base '" + symbols[1] + "' but there's a constant with the same name. Did you mean to access it?"; + msg = "The method '" + symbols[0] + "()' was not found in base '" + symbols[1] + "' but there's a constant with the same name. Did you mean to access it?"; } break; case FUNCTION_USED_AS_PROPERTY: { CHECK_SYMBOLS(2); - return "The property '" + symbols[0] + "' was not found in base '" + symbols[1] + "' but there's a method with the same name. Did you mean to call it?"; + msg = "The property '" + symbols[0] + "' was not found in base '" + symbols[1] + "' but there's a method with the same name. Did you mean to call it?"; } break; case INTEGER_DIVISION: { - return "Integer division, decimal part will be discarded."; + msg = "Integer division, decimal part will be discarded."; } break; case UNSAFE_PROPERTY_ACCESS: { CHECK_SYMBOLS(2); - return "The property '" + symbols[0] + "' is not present on the inferred type '" + symbols[1] + "' (but may be present on a subtype)."; + msg = "The property '" + symbols[0] + "' is not present on the inferred type '" + symbols[1] + "' (but may be present on a subtype)."; } break; case UNSAFE_METHOD_ACCESS: { CHECK_SYMBOLS(2); - return "The method '" + symbols[0] + "' is not present on the inferred type '" + symbols[1] + "' (but may be present on a subtype)."; + msg = "The method '" + symbols[0] + "' is not present on the inferred type '" + symbols[1] + "' (but may be present on a subtype)."; } break; case UNSAFE_CAST: { CHECK_SYMBOLS(1); - return "The value is cast to '" + symbols[0] + "' but has an unknown type."; + msg = "The value is cast to '" + symbols[0] + "' but has an unknown type."; } break; case UNSAFE_CALL_ARGUMENT: { CHECK_SYMBOLS(4); - return "The argument '" + symbols[0] + "' of the function '" + symbols[1] + "' requires a the subtype '" + symbols[2] + "' but the supertype '" + symbols[3] + "' was provided"; + msg = "The argument '" + symbols[0] + "' of the function '" + symbols[1] + "' requires a the subtype '" + symbols[2] + "' but the supertype '" + symbols[3] + "' was provided"; } break; case DEPRECATED_KEYWORD: { CHECK_SYMBOLS(2); - return "The '" + symbols[0] + "' keyword is deprecated and will be removed in a future release, please replace its uses by '" + symbols[1] + "'."; + msg = "The '" + symbols[0] + "' keyword is deprecated and will be removed in a future release, please replace its uses by '" + symbols[1] + "'."; } break; case STANDALONE_TERNARY: { - return "Standalone ternary conditional operator: the return value is being discarded."; - } + msg = "Standalone ternary conditional operator: the return value is being discarded."; + } break; case WARNING_MAX: - break; // Can't happen, but silences warning + ERR_FAIL_V_MSG(String(), "Invalid GDScript warning code: " + get_name_from_code(code) + "."); } - ERR_FAIL_V_MSG(String(), "Invalid GDScript warning code: " + get_name_from_code(code) + "."); + return msg + " [" + get_name() + "]"; #undef CHECK_SYMBOLS } diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index ca452bf008..63da849723 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -4072,6 +4072,9 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { while (true) { current_function = function; Node *arg = _parse_and_reduce_expression(p_class, _static); + if (!arg) { + return; + } current_function = nullptr; cparent->arguments.push_back(arg); diff --git a/modules/gdscript/register_types.cpp b/modules/gdscript/register_types.cpp index 53e760ffa7..388df63dba 100644 --- a/modules/gdscript/register_types.cpp +++ b/modules/gdscript/register_types.cpp @@ -55,6 +55,8 @@ Ref<ResourceFormatSaverGDScript> resource_saver_gd; #include "language_server/gdscript_language_server.h" #endif // !GDSCRIPT_NO_LSP +Ref<GDScriptEditorTranslationParserPlugin> gdscript_translation_parser_plugin; + class EditorExportGDScript : public EditorExportPlugin { GDCLASS(EditorExportGDScript, EditorExportPlugin); @@ -167,7 +169,6 @@ void register_gdscript_types() { ScriptEditor::register_create_syntax_highlighter_function(GDScriptSyntaxHighlighter::create); EditorNode::add_init_callback(_editor_init); - Ref<GDScriptEditorTranslationParserPlugin> gdscript_translation_parser_plugin; gdscript_translation_parser_plugin.instance(); EditorTranslationParser::get_singleton()->add_parser(gdscript_translation_parser_plugin, EditorTranslationParser::STANDARD); #endif // TOOLS_ENABLED @@ -185,4 +186,9 @@ void unregister_gdscript_types() { ResourceSaver::remove_resource_format_saver(resource_saver_gd); resource_saver_gd.unref(); + +#ifdef TOOLS_ENABLED + EditorTranslationParser::get_singleton()->remove_parser(gdscript_translation_parser_plugin, EditorTranslationParser::STANDARD); + gdscript_translation_parser_plugin.unref(); +#endif // TOOLS_ENABLED } diff --git a/modules/mono/class_db_api_json.cpp b/modules/mono/class_db_api_json.cpp index 39e3a95afa..d7b2028204 100644 --- a/modules/mono/class_db_api_json.cpp +++ b/modules/mono/class_db_api_json.cpp @@ -53,8 +53,9 @@ void class_db_api_to_json(const String &p_output_file, ClassDB::APIType p_api) { for (List<StringName>::Element *E = names.front(); E; E = E->next()) { ClassDB::ClassInfo *t = ClassDB::classes.getptr(E->get()); ERR_FAIL_COND(!t); - if (t->api != p_api || !t->exposed) + if (t->api != p_api || !t->exposed) { continue; + } Dictionary class_dict; classes_dict[t->name] = class_dict; @@ -72,8 +73,9 @@ void class_db_api_to_json(const String &p_output_file, ClassDB::APIType p_api) { ERR_CONTINUE(name.empty()); - if (name[0] == '_') + if (name[0] == '_') { continue; // Ignore non-virtual methods that start with an underscore + } snames.push_back(*k); } diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index ae25bd3544..22e4d84e98 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -125,8 +125,9 @@ void CSharpLanguage::init() { print_line("Run this binary with '--generate-mono-glue path/to/modules/mono/glue'"); #endif - if (gdmono->is_runtime_initialized()) + if (gdmono->is_runtime_initialized()) { gdmono->initialize_load_assemblies(); + } #ifdef TOOLS_ENABLED EditorNode::add_init_callback(&_editor_init_callback); @@ -134,8 +135,13 @@ void CSharpLanguage::init() { } void CSharpLanguage::finish() { - if (finalized) + finalize(); +} + +void CSharpLanguage::finalize() { + if (finalized) { return; + } finalizing = true; @@ -390,15 +396,17 @@ bool CSharpLanguage::supports_builtin_mode() const { #ifdef TOOLS_ENABLED static String variant_type_to_managed_name(const String &p_var_type_name) { - if (p_var_type_name.empty()) + if (p_var_type_name.empty()) { return "object"; + } if (!ClassDB::class_exists(p_var_type_name)) { return p_var_type_name; } - if (p_var_type_name == Variant::get_type_name(Variant::OBJECT)) + if (p_var_type_name == Variant::get_type_name(Variant::OBJECT)) { return "Godot.Object"; + } if (p_var_type_name == Variant::get_type_name(Variant::FLOAT)) { #ifdef REAL_T_IS_DOUBLE @@ -408,36 +416,49 @@ static String variant_type_to_managed_name(const String &p_var_type_name) { #endif } - if (p_var_type_name == Variant::get_type_name(Variant::STRING)) + if (p_var_type_name == Variant::get_type_name(Variant::STRING)) { return "string"; // I prefer this one >:[ + } - if (p_var_type_name == Variant::get_type_name(Variant::DICTIONARY)) + if (p_var_type_name == Variant::get_type_name(Variant::DICTIONARY)) { return "Collections.Dictionary"; + } - if (p_var_type_name == Variant::get_type_name(Variant::ARRAY)) + if (p_var_type_name == Variant::get_type_name(Variant::ARRAY)) { return "Collections.Array"; + } - if (p_var_type_name == Variant::get_type_name(Variant::PACKED_BYTE_ARRAY)) + if (p_var_type_name == Variant::get_type_name(Variant::PACKED_BYTE_ARRAY)) { return "byte[]"; - if (p_var_type_name == Variant::get_type_name(Variant::PACKED_INT32_ARRAY)) + } + if (p_var_type_name == Variant::get_type_name(Variant::PACKED_INT32_ARRAY)) { return "int[]"; - if (p_var_type_name == Variant::get_type_name(Variant::PACKED_INT64_ARRAY)) + } + if (p_var_type_name == Variant::get_type_name(Variant::PACKED_INT64_ARRAY)) { return "long[]"; - if (p_var_type_name == Variant::get_type_name(Variant::PACKED_FLOAT32_ARRAY)) + } + if (p_var_type_name == Variant::get_type_name(Variant::PACKED_FLOAT32_ARRAY)) { return "float[]"; - if (p_var_type_name == Variant::get_type_name(Variant::PACKED_FLOAT64_ARRAY)) + } + if (p_var_type_name == Variant::get_type_name(Variant::PACKED_FLOAT64_ARRAY)) { return "double[]"; - if (p_var_type_name == Variant::get_type_name(Variant::PACKED_STRING_ARRAY)) + } + if (p_var_type_name == Variant::get_type_name(Variant::PACKED_STRING_ARRAY)) { return "string[]"; - if (p_var_type_name == Variant::get_type_name(Variant::PACKED_VECTOR2_ARRAY)) + } + if (p_var_type_name == Variant::get_type_name(Variant::PACKED_VECTOR2_ARRAY)) { return "Vector2[]"; - if (p_var_type_name == Variant::get_type_name(Variant::PACKED_VECTOR3_ARRAY)) + } + if (p_var_type_name == Variant::get_type_name(Variant::PACKED_VECTOR3_ARRAY)) { return "Vector3[]"; - if (p_var_type_name == Variant::get_type_name(Variant::PACKED_COLOR_ARRAY)) + } + if (p_var_type_name == Variant::get_type_name(Variant::PACKED_COLOR_ARRAY)) { return "Color[]"; + } - if (p_var_type_name == Variant::get_type_name(Variant::SIGNAL)) + if (p_var_type_name == Variant::get_type_name(Variant::SIGNAL)) { return "SignalInfo"; + } Variant::Type var_types[] = { Variant::BOOL, @@ -462,8 +483,9 @@ static String variant_type_to_managed_name(const String &p_var_type_name) { }; for (unsigned int i = 0; i < sizeof(var_types) / sizeof(Variant::Type); i++) { - if (p_var_type_name == Variant::get_type_name(var_types[i])) + if (p_var_type_name == Variant::get_type_name(var_types[i])) { return p_var_type_name; + } } return "object"; @@ -477,8 +499,9 @@ String CSharpLanguage::make_function(const String &, const String &p_name, const for (int i = 0; i < p_args.size(); i++) { const String &arg = p_args[i]; - if (i > 0) + if (i > 0) { s += ", "; + } s += variant_type_to_managed_name(arg.get_slice(":", 1)) + " " + escape_csharp_keyword(arg.get_slice(":", 0)); } @@ -516,32 +539,36 @@ String CSharpLanguage::debug_get_error() const { } int CSharpLanguage::debug_get_stack_level_count() const { - if (_debug_parse_err_line >= 0) + if (_debug_parse_err_line >= 0) { return 1; + } // TODO: StackTrace return 1; } int CSharpLanguage::debug_get_stack_level_line(int p_level) const { - if (_debug_parse_err_line >= 0) + if (_debug_parse_err_line >= 0) { return _debug_parse_err_line; + } // TODO: StackTrace return 1; } String CSharpLanguage::debug_get_stack_level_function(int p_level) const { - if (_debug_parse_err_line >= 0) + if (_debug_parse_err_line >= 0) { return String(); + } // TODO: StackTrace return String(); } String CSharpLanguage::debug_get_stack_level_source(int p_level) const { - if (_debug_parse_err_line >= 0) + if (_debug_parse_err_line >= 0) { return _debug_parse_err_file; + } // TODO: StackTrace return String(); @@ -551,15 +578,17 @@ Vector<ScriptLanguage::StackInfo> CSharpLanguage::debug_get_current_stack_info() #ifdef DEBUG_ENABLED // Printing an error here will result in endless recursion, so we must be careful static thread_local bool _recursion_flag_ = false; - if (_recursion_flag_) + if (_recursion_flag_) { return Vector<StackInfo>(); + } _recursion_flag_ = true; SCOPE_EXIT { _recursion_flag_ = false; }; GD_MONO_SCOPE_THREAD_ATTACH; - if (!gdmono->is_runtime_initialized() || !GDMono::get_singleton()->get_core_api_assembly() || !GDMonoCache::cached_data.corlib_cache_updated) + if (!gdmono->is_runtime_initialized() || !GDMono::get_singleton()->get_core_api_assembly() || !GDMonoCache::cached_data.corlib_cache_updated) { return Vector<StackInfo>(); + } MonoObject *stack_trace = mono_object_new(mono_domain_get(), CACHED_CLASS(System_Diagnostics_StackTrace)->get_mono_ptr()); @@ -581,8 +610,9 @@ Vector<ScriptLanguage::StackInfo> CSharpLanguage::debug_get_current_stack_info() Vector<ScriptLanguage::StackInfo> CSharpLanguage::stack_trace_get_info(MonoObject *p_stack_trace) { // Printing an error here will result in endless recursion, so we must be careful static thread_local bool _recursion_flag_ = false; - if (_recursion_flag_) + if (_recursion_flag_) { return Vector<StackInfo>(); + } _recursion_flag_ = true; SCOPE_EXIT { _recursion_flag_ = false; }; @@ -599,8 +629,9 @@ Vector<ScriptLanguage::StackInfo> CSharpLanguage::stack_trace_get_info(MonoObjec int frame_count = mono_array_length(frames); - if (frame_count <= 0) + if (frame_count <= 0) { return Vector<StackInfo>(); + } Vector<StackInfo> si; si.resize(frame_count); @@ -646,8 +677,9 @@ void CSharpLanguage::pre_unsafe_unreference(Object *p_obj) { ObjectID id = p_obj->get_instance_id(); Map<ObjectID, int>::Element *elem = unsafe_object_references.find(id); ERR_FAIL_NULL(elem); - if (--elem->value() == 0) + if (--elem->value() == 0) { unsafe_object_references.erase(elem); + } #endif } @@ -673,8 +705,9 @@ void CSharpLanguage::frame() { struct CSharpScriptDepSort { // must support sorting so inheritance works properly (parent must be reloaded first) bool operator()(const Ref<CSharpScript> &A, const Ref<CSharpScript> &B) const { - if (A == B) + if (A == B) { return false; // shouldn't happen but.. + } GDMonoClass *I = B->base; while (I) { if (I == A->script_class) { @@ -717,8 +750,9 @@ void CSharpLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_soft #ifdef GD_MONO_HOT_RELOAD bool CSharpLanguage::is_assembly_reloading_needed() { - if (!gdmono->is_runtime_initialized()) + if (!gdmono->is_runtime_initialized()) { return false; + } GDMonoAssembly *proj_assembly = gdmono->get_project_assembly(); @@ -736,23 +770,27 @@ bool CSharpLanguage::is_assembly_reloading_needed() { if (!FileAccess::exists(proj_asm_path)) { // Maybe it wasn't loaded from the default path, so check this as well proj_asm_path = GodotSharpDirs::get_res_temp_assemblies_dir().plus_file(appname_safe); - if (!FileAccess::exists(proj_asm_path)) + if (!FileAccess::exists(proj_asm_path)) { return false; // No assembly to load + } } - if (FileAccess::get_modified_time(proj_asm_path) <= proj_assembly->get_modified_time()) + if (FileAccess::get_modified_time(proj_asm_path) <= proj_assembly->get_modified_time()) { return false; // Already up to date + } } else { - if (!FileAccess::exists(GodotSharpDirs::get_res_temp_assemblies_dir().plus_file(appname_safe))) + if (!FileAccess::exists(GodotSharpDirs::get_res_temp_assemblies_dir().plus_file(appname_safe))) { return false; // No assembly to load + } } return true; } void CSharpLanguage::reload_assemblies(bool p_soft_reload) { - if (!gdmono->is_runtime_initialized()) + if (!gdmono->is_runtime_initialized()) { return; + } // There is no soft reloading with Mono. It's always hard reloading. @@ -858,8 +896,9 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) { CSharpInstance *csi = static_cast<CSharpInstance *>(obj->get_script_instance()); // Call OnBeforeSerialize - if (csi->script->script_class->implements_interface(CACHED_CLASS(ISerializationListener))) + if (csi->script->script_class->implements_interface(CACHED_CLASS(ISerializationListener))) { obj->get_script_instance()->call_multilevel(string_names.on_before_serialize); + } // Save instance info CSharpScript::StateBackup state; @@ -894,8 +933,9 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) { for (const Map<ObjectID, CSharpScript::StateBackup>::Element *F = scr->pending_reload_state.front(); F; F = F->next()) { Object *obj = ObjectDB::get_instance(F->key()); - if (!obj) + if (!obj) { continue; + } ObjectID obj_id = obj->get_instance_id(); @@ -1092,8 +1132,9 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) { } // Call OnAfterDeserialization - if (csi->script->script_class->implements_interface(CACHED_CLASS(ISerializationListener))) + if (csi->script->script_class->implements_interface(CACHED_CLASS(ISerializationListener))) { obj->get_script_instance()->call_multilevel(string_names.on_after_deserialize); + } } } @@ -1246,6 +1287,7 @@ void CSharpLanguage::_on_scripts_domain_unloaded() { script_binding.inited = false; } +#ifdef GD_MONO_HOT_RELOAD { MutexLock lock(ManagedCallable::instances_mutex); @@ -1255,6 +1297,7 @@ void CSharpLanguage::_on_scripts_domain_unloaded() { managed_callable->delegate_invoke = nullptr; } } +#endif scripts_metadata_invalidated = true; } @@ -1275,7 +1318,8 @@ void CSharpLanguage::_editor_init_callback() { GDMonoUtils::runtime_object_init(mono_object, editor_klass, &exc); UNHANDLED_EXCEPTION(exc); - EditorPlugin *godotsharp_editor = Object::cast_to<EditorPlugin>(GDMonoMarshal::mono_object_to_variant(mono_object)); + EditorPlugin *godotsharp_editor = Object::cast_to<EditorPlugin>( + GDMonoMarshal::mono_object_to_variant(mono_object).operator Object *()); CRASH_COND(godotsharp_editor == nullptr); // Enable it as a plugin @@ -1324,7 +1368,7 @@ CSharpLanguage::CSharpLanguage() { } CSharpLanguage::~CSharpLanguage() { - finish(); + finalize(); singleton = nullptr; } @@ -1341,8 +1385,9 @@ bool CSharpLanguage::setup_csharp_script_binding(CSharpScriptBinding &r_script_b // ¯\_(ツ)_/¯ const ClassDB::ClassInfo *classinfo = ClassDB::classes.getptr(type_name); - while (classinfo && !classinfo->exposed) + while (classinfo && !classinfo->exposed) { classinfo = classinfo->inherits_ptr; + } ERR_FAIL_NULL_V(classinfo, false); type_name = classinfo->name; @@ -1380,13 +1425,15 @@ void *CSharpLanguage::alloc_instance_binding_data(Object *p_object) { MutexLock lock(language_bind_mutex); Map<Object *, CSharpScriptBinding>::Element *match = script_bindings.find(p_object); - if (match) + if (match) { return (void *)match; + } CSharpScriptBinding script_binding; - if (!setup_csharp_script_binding(script_binding, p_object)) + if (!setup_csharp_script_binding(script_binding, p_object)) { return nullptr; + } return (void *)insert_script_binding(p_object, script_binding); } @@ -1404,8 +1451,9 @@ void CSharpLanguage::free_instance_binding_data(void *p_data) { return; } - if (finalizing) + if (finalizing) { return; // inside CSharpLanguage::finish(), all the gchandle bindings are released there + } GD_MONO_ASSERT_THREAD_ATTACHED; @@ -1444,8 +1492,9 @@ void CSharpLanguage::refcount_incremented_instance_binding(Object *p_object) { CSharpScriptBinding &script_binding = ((Map<Object *, CSharpScriptBinding>::Element *)data)->get(); MonoGCHandleData &gchandle = script_binding.gchandle; - if (!script_binding.inited) + if (!script_binding.inited) { return; + } if (ref_owner->reference_get_count() > 1 && gchandle.is_weak()) { // The managed side also holds a reference, hence 1 instead of 0 GD_MONO_SCOPE_THREAD_ATTACH; @@ -1455,8 +1504,9 @@ void CSharpLanguage::refcount_incremented_instance_binding(Object *p_object) { // so the owner must hold the managed side alive again to avoid it from being GCed. MonoObject *target = gchandle.get_target(); - if (!target) + if (!target) { return; // Called after the managed side was collected, so nothing to do here + } // Release the current weak handle and replace it with a strong handle. MonoGCHandleData strong_gchandle = MonoGCHandleData::new_strong_handle(target); @@ -1481,8 +1531,9 @@ bool CSharpLanguage::refcount_decremented_instance_binding(Object *p_object) { int refcount = ref_owner->reference_get_count(); - if (!script_binding.inited) + if (!script_binding.inited) { return refcount == 0; + } if (refcount == 1 && !gchandle.is_released() && !gchandle.is_weak()) { // The managed side also holds a reference, hence 1 instead of 0 GD_MONO_SCOPE_THREAD_ATTACH; @@ -1491,8 +1542,9 @@ bool CSharpLanguage::refcount_decremented_instance_binding(Object *p_object) { // the managed instance takes responsibility of deleting the owner when GCed. MonoObject *target = gchandle.get_target(); - if (!target) + if (!target) { return refcount == 0; // Called after the managed side was collected, so nothing to do here + } // Release the current strong handle and replace it with a weak handle. MonoGCHandleData weak_gchandle = MonoGCHandleData::new_weak_handle(target); @@ -1514,8 +1566,9 @@ CSharpInstance *CSharpInstance::create_for_managed_type(Object *p_owner, CSharpS instance->owner = p_owner; instance->gchandle = p_gchandle; - if (instance->base_ref) + if (instance->base_ref) { instance->_reference_owner_unsafe(); + } p_script->instances.insert(p_owner); @@ -1572,8 +1625,9 @@ bool CSharpInstance::set(const StringName &p_name, const Variant &p_value) { MonoObject *ret = method->invoke(mono_object, args); - if (ret && GDMonoMarshal::unbox<MonoBoolean>(ret)) + if (ret && GDMonoMarshal::unbox<MonoBoolean>(ret)) { return true; + } break; } @@ -1658,8 +1712,9 @@ void CSharpInstance::get_properties_state_for_reloading(List<Pair<StringName, Va ManagedType managedType; GDMonoField *field = script->script_class->get_field(state_pair.first); - if (!field) + if (!field) { continue; // Properties ignored. We get the property baking fields instead. + } managedType = field->get_type(); @@ -1679,8 +1734,9 @@ void CSharpInstance::get_event_signals_state_for_reloading(List<Pair<StringName, const CSharpScript::EventSignal &event_signal = E->value(); MonoDelegate *delegate_field_value = (MonoDelegate *)event_signal.field->get_value(owner_managed); - if (!delegate_field_value) + if (!delegate_field_value) { continue; // Empty + } Array serialized_data; MonoObject *managed_serialized_data = GDMonoMarshal::variant_to_mono_object(serialized_data); @@ -1725,8 +1781,9 @@ void CSharpInstance::get_property_list(List<PropertyInfo> *p_properties) const { if (ret) { Array array = Array(GDMonoMarshal::mono_object_to_variant(ret)); - for (int i = 0, size = array.size(); i < size; i++) + for (int i = 0, size = array.size(); i < size; i++) { p_properties->push_back(PropertyInfo::from_dict(array.get(i))); + } return; } @@ -1739,20 +1796,23 @@ void CSharpInstance::get_property_list(List<PropertyInfo> *p_properties) const { Variant::Type CSharpInstance::get_property_type(const StringName &p_name, bool *r_is_valid) const { if (script->member_info.has(p_name)) { - if (r_is_valid) + if (r_is_valid) { *r_is_valid = true; + } return script->member_info[p_name].type; } - if (r_is_valid) + if (r_is_valid) { *r_is_valid = false; + } return Variant::NIL; } bool CSharpInstance::has_method(const StringName &p_method) const { - if (!script.is_valid()) + if (!script.is_valid()) { return false; + } GD_MONO_SCOPE_THREAD_ATTACH; @@ -1868,8 +1928,9 @@ bool CSharpInstance::_unreference_owner_unsafe() { CRASH_COND(owner == nullptr); #endif - if (!unsafe_referenced) + if (!unsafe_referenced) { return false; // Already unreferenced + } unsafe_referenced = false; @@ -1912,8 +1973,9 @@ MonoObject *CSharpInstance::_internal_new_managed() { // Tie managed to unmanaged gchandle = MonoGCHandleData::new_strong_handle(mono_object); - if (base_ref) + if (base_ref) { _reference_owner_unsafe(); // Here, after assigning the gchandle (for the refcount_incremented callback) + } CACHED_FIELD(GodotObject, ptr)->set_value_raw(mono_object, owner); @@ -2130,7 +2192,7 @@ void CSharpInstance::_call_notification(int p_notification) { // Custom version of _call_multilevel, optimized for _notification - uint32_t arg = p_notification; + int32_t arg = p_notification; void *args[1] = { &arg }; StringName method_name = CACHED_STRING_NAME(_notification); @@ -2154,8 +2216,9 @@ String CSharpInstance::to_string(bool *r_valid) { MonoObject *mono_object = get_mono_object(); if (mono_object == nullptr) { - if (r_valid) + if (r_valid) { *r_valid = false; + } return String(); } @@ -2164,14 +2227,16 @@ String CSharpInstance::to_string(bool *r_valid) { if (exc) { GDMonoUtils::set_pending_exception(exc); - if (r_valid) + if (r_valid) { *r_valid = false; + } return String(); } if (result == nullptr) { - if (r_valid) + if (r_valid) { *r_valid = false; + } return String(); } @@ -2342,11 +2407,13 @@ void CSharpScript::_update_member_info_no_exports() { bool CSharpScript::_update_exports() { #ifdef TOOLS_ENABLED bool is_editor = Engine::get_singleton()->is_editor_hint(); - if (is_editor) + if (is_editor) { placeholder_fallback_enabled = true; // until proven otherwise + } #endif - if (!valid) + if (!valid) { return false; + } bool changed = false; @@ -2543,8 +2610,9 @@ void CSharpScript::load_script_signals(GDMonoClass *p_class, GDMonoClass *p_nati for (int i = delegates.size() - 1; i >= 0; --i) { GDMonoClass *delegate = delegates[i]; - if (!delegate->has_attribute(CACHED_CLASS(SignalAttribute))) + if (!delegate->has_attribute(CACHED_CLASS(SignalAttribute))) { continue; + } // Arguments are accessibles as arguments of .Invoke method GDMonoMethod *invoke_method = delegate->get_method(mono_get_delegate_invoke(delegate->get_mono_ptr())); @@ -2577,11 +2645,13 @@ void CSharpScript::load_script_signals(GDMonoClass *p_class, GDMonoClass *p_nati GDMonoClass *field_class = field->get_type().type_class; - if (!mono_class_is_delegate(field_class->get_mono_ptr())) + if (!mono_class_is_delegate(field_class->get_mono_ptr())) { continue; + } - if (!found_event_signals.find(field->get_name())) + if (!found_event_signals.find(field->get_name())) { continue; + } GDMonoMethod *invoke_method = field_class->get_method(mono_get_delegate_invoke(field_class->get_mono_ptr())); @@ -2640,14 +2710,16 @@ bool CSharpScript::_get_member_export(IMonoClassMember *p_member, bool p_inspect if (p_member->is_static()) { #ifdef TOOLS_ENABLED - if (p_member->has_attribute(CACHED_CLASS(ExportAttribute))) + if (p_member->has_attribute(CACHED_CLASS(ExportAttribute))) { ERR_PRINT("Cannot export member because it is static: '" + MEMBER_FULL_QUALIFIED_NAME(p_member) + "'."); + } #endif return false; } - if (member_info.has(p_member->get_name())) + if (member_info.has(p_member->get_name())) { return false; + } ManagedType type; @@ -2665,15 +2737,17 @@ bool CSharpScript::_get_member_export(IMonoClassMember *p_member, bool p_inspect GDMonoProperty *property = static_cast<GDMonoProperty *>(p_member); if (!property->has_getter()) { #ifdef TOOLS_ENABLED - if (exported) + if (exported) { ERR_PRINT("Read-only property cannot be exported: '" + MEMBER_FULL_QUALIFIED_NAME(p_member) + "'."); + } #endif return false; } if (!property->has_setter()) { #ifdef TOOLS_ENABLED - if (exported) + if (exported) { ERR_PRINT("Write-only property (without getter) cannot be exported: '" + MEMBER_FULL_QUALIFIED_NAME(p_member) + "'."); + } #endif return false; } @@ -2802,8 +2876,9 @@ int CSharpScript::_try_get_member_export_hint(IMonoClassMember *p_member, Manage ManagedType elem_type; - if (!GDMonoMarshal::try_get_array_element_type(p_type, elem_type)) + if (!GDMonoMarshal::try_get_array_element_type(p_type, elem_type)) { return 0; + } Variant::Type elem_variant_type = GDMonoMarshal::managed_to_variant_type(elem_type); @@ -2830,15 +2905,6 @@ int CSharpScript::_try_get_member_export_hint(IMonoClassMember *p_member, Manage } #endif -void CSharpScript::_clear() { - tool = false; - valid = false; - - base = nullptr; - native = nullptr; - script_class = nullptr; -} - Variant CSharpScript::call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { if (unlikely(GDMono::get_singleton() == nullptr)) { // Probably not the best error but eh. @@ -2871,11 +2937,7 @@ Variant CSharpScript::call(const StringName &p_method, const Variant **p_args, i } void CSharpScript::_resource_path_changed() { - String path = get_path(); - - if (!path.empty()) { - name = get_path().get_file().get_basename(); - } + _update_name(); } bool CSharpScript::_get(const StringName &p_name, Variant &r_ret) const { @@ -2931,8 +2993,9 @@ void CSharpScript::initialize_for_managed_type(Ref<CSharpScript> p_script, GDMon GDMonoClass *base = p_script->script_class->get_parent_class(); - if (base != p_script->native) + if (base != p_script->native) { p_script->base = base; + } p_script->valid = true; p_script->tool = p_script->script_class->has_attribute(CACHED_CLASS(ToolAttribute)); @@ -2958,8 +3021,9 @@ void CSharpScript::initialize_for_managed_type(Ref<CSharpScript> p_script, GDMon while (native_top) { native_top->fetch_methods_with_godot_api_checks(p_script->native); - if (native_top == CACHED_CLASS(GodotObject)) + if (native_top == CACHED_CLASS(GodotObject)) { break; + } native_top = native_top->get_parent_class(); } @@ -3005,10 +3069,11 @@ bool CSharpScript::can_instance() const { } StringName CSharpScript::get_instance_base_type() const { - if (native) + if (native) { return native->get_name(); - else + } else { return StringName(); + } } CSharpInstance *CSharpScript::_create_instance(const Variant **p_args, int p_argcount, Object *p_owner, bool p_isref, Callable::CallError &r_error) { @@ -3081,8 +3146,9 @@ CSharpInstance *CSharpScript::_create_instance(const Variant **p_args, int p_arg // Tie managed to unmanaged instance->gchandle = MonoGCHandleData::new_strong_handle(mono_object); - if (instance->base_ref) + if (instance->base_ref) { instance->_reference_owner_unsafe(); // Here, after assigning the gchandle (for the refcount_incremented callback) + } { MutexLock lock(CSharpLanguage::get_singleton()->script_instances_mutex); @@ -3184,8 +3250,9 @@ String CSharpScript::get_source_code() const { } void CSharpScript::set_source_code(const String &p_code) { - if (source == p_code) + if (source == p_code) { return; + } source = p_code; #ifdef TOOLS_ENABLED source_changed_cache = true; @@ -3193,8 +3260,9 @@ void CSharpScript::set_source_code(const String &p_code) { } void CSharpScript::get_script_method_list(List<MethodInfo> *p_list) const { - if (!script_class) + if (!script_class) { return; + } GD_MONO_SCOPE_THREAD_ATTACH; @@ -3206,8 +3274,9 @@ void CSharpScript::get_script_method_list(List<MethodInfo> *p_list) const { } bool CSharpScript::has_method(const StringName &p_method) const { - if (!script_class) + if (!script_class) { return false; + } GD_MONO_SCOPE_THREAD_ATTACH; @@ -3215,8 +3284,9 @@ bool CSharpScript::has_method(const StringName &p_method) const { } MethodInfo CSharpScript::get_method_info(const StringName &p_method) const { - if (!script_class) + if (!script_class) { return MethodInfo(); + } GD_MONO_SCOPE_THREAD_ATTACH; @@ -3290,8 +3360,9 @@ Error CSharpScript::reload(bool p_keep_state) { GDMonoClass *base_class = script_class->get_parent_class(); - if (base_class != native) + if (base_class != native) { base = base_class; + } #ifdef DEBUG_ENABLED // For debug builds, we must fetch from all native base methods as well. @@ -3303,8 +3374,9 @@ Error CSharpScript::reload(bool p_keep_state) { while (native_top) { native_top->fetch_methods_with_godot_api_checks(native); - if (native_top == CACHED_CLASS(GodotObject)) + if (native_top == CACHED_CLASS(GodotObject)) { break; + } native_top = native_top->get_parent_class(); } @@ -3434,8 +3506,9 @@ void CSharpScript::get_script_signal_list(List<MethodInfo> *r_signals) const { const SignalParameter ¶m = params[i]; PropertyInfo arg_info = PropertyInfo(param.type, param.name); - if (param.type == Variant::NIL && param.nil_is_variant) + if (param.type == Variant::NIL && param.nil_is_variant) { arg_info.usage |= PROPERTY_USAGE_NIL_IS_VARIANT; + } mi.arguments.push_back(arg_info); } @@ -3453,8 +3526,9 @@ void CSharpScript::get_script_signal_list(List<MethodInfo> *r_signals) const { const SignalParameter ¶m = params[i]; PropertyInfo arg_info = PropertyInfo(param.type, param.name); - if (param.type == Variant::NIL && param.nil_is_variant) + if (param.type == Variant::NIL && param.nil_is_variant) { arg_info.usage |= PROPERTY_USAGE_NIL_IS_VARIANT; + } mi.arguments.push_back(arg_info); } @@ -3497,18 +3571,24 @@ int CSharpScript::get_member_line(const StringName &p_member) const { } MultiplayerAPI::RPCMode CSharpScript::_member_get_rpc_mode(IMonoClassMember *p_member) const { - if (p_member->has_attribute(CACHED_CLASS(RemoteAttribute))) + if (p_member->has_attribute(CACHED_CLASS(RemoteAttribute))) { return MultiplayerAPI::RPC_MODE_REMOTE; - if (p_member->has_attribute(CACHED_CLASS(MasterAttribute))) + } + if (p_member->has_attribute(CACHED_CLASS(MasterAttribute))) { return MultiplayerAPI::RPC_MODE_MASTER; - if (p_member->has_attribute(CACHED_CLASS(PuppetAttribute))) + } + if (p_member->has_attribute(CACHED_CLASS(PuppetAttribute))) { return MultiplayerAPI::RPC_MODE_PUPPET; - if (p_member->has_attribute(CACHED_CLASS(RemoteSyncAttribute))) + } + if (p_member->has_attribute(CACHED_CLASS(RemoteSyncAttribute))) { return MultiplayerAPI::RPC_MODE_REMOTESYNC; - if (p_member->has_attribute(CACHED_CLASS(MasterSyncAttribute))) + } + if (p_member->has_attribute(CACHED_CLASS(MasterSyncAttribute))) { return MultiplayerAPI::RPC_MODE_MASTERSYNC; - if (p_member->has_attribute(CACHED_CLASS(PuppetSyncAttribute))) + } + if (p_member->has_attribute(CACHED_CLASS(PuppetSyncAttribute))) { return MultiplayerAPI::RPC_MODE_PUPPETSYNC; + } return MultiplayerAPI::RPC_MODE_DISABLED; } @@ -3583,14 +3663,27 @@ Error CSharpScript::load_source_code(const String &p_path) { return OK; } -StringName CSharpScript::get_script_name() const { - return name; +void CSharpScript::_update_name() { + String path = get_path(); + + if (!path.empty()) { + name = get_path().get_file().get_basename(); + } +} + +void CSharpScript::_clear() { + tool = false; + valid = false; + + base = nullptr; + native = nullptr; + script_class = nullptr; } CSharpScript::CSharpScript() { _clear(); - _resource_path_changed(); + _update_name(); #ifdef DEBUG_ENABLED { @@ -3620,8 +3713,9 @@ void CSharpScript::get_members(Set<StringName> *p_members) { /*************** RESOURCE ***************/ RES ResourceFormatLoaderCSharpScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { - if (r_error) + if (r_error) { *r_error = ERR_FILE_CANT_OPEN; + } // TODO ignore anything inside bin/ and obj/ in tools builds? @@ -3638,8 +3732,9 @@ RES ResourceFormatLoaderCSharpScript::load(const String &p_path, const String &p script->reload(); - if (r_error) + if (r_error) { *r_error = OK; + } return scriptres; } diff --git a/modules/mono/csharp_script.h b/modules/mono/csharp_script.h index 0bf08ceafd..c2370364f9 100644 --- a/modules/mono/csharp_script.h +++ b/modules/mono/csharp_script.h @@ -135,7 +135,7 @@ private: bool exports_invalidated = true; void _update_exports_values(Map<StringName, Variant> &values, List<PropertyInfo> &propnames); void _update_member_info_no_exports(); - virtual void _placeholder_erased(PlaceHolderScriptInstance *p_placeholder); + void _placeholder_erased(PlaceHolderScriptInstance *p_placeholder) override; #endif #if defined(TOOLS_ENABLED) || defined(DEBUG_ENABLED) @@ -146,6 +146,8 @@ private: void _clear(); + void _update_name(); + void load_script_signals(GDMonoClass *p_class, GDMonoClass *p_native_class); bool _get_signal(GDMonoClass *p_class, GDMonoMethod *p_delegate_invoke, Vector<SignalParameter> ¶ms); @@ -169,68 +171,66 @@ private: protected: static void _bind_methods(); - Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error); - virtual void _resource_path_changed(); + Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) override; + void _resource_path_changed() override; bool _get(const StringName &p_name, Variant &r_ret) const; bool _set(const StringName &p_name, const Variant &p_value); void _get_property_list(List<PropertyInfo> *p_properties) const; public: - virtual bool can_instance() const; - virtual StringName get_instance_base_type() const; - virtual ScriptInstance *instance_create(Object *p_this); - virtual PlaceHolderScriptInstance *placeholder_instance_create(Object *p_this); - virtual bool instance_has(const Object *p_this) const; + bool can_instance() const override; + StringName get_instance_base_type() const override; + ScriptInstance *instance_create(Object *p_this) override; + PlaceHolderScriptInstance *placeholder_instance_create(Object *p_this) override; + bool instance_has(const Object *p_this) const override; - virtual bool has_source_code() const; - virtual String get_source_code() const; - virtual void set_source_code(const String &p_code); + bool has_source_code() const override; + String get_source_code() const override; + void set_source_code(const String &p_code) override; - virtual Error reload(bool p_keep_state = false); + Error reload(bool p_keep_state = false) override; - virtual bool has_script_signal(const StringName &p_signal) const; - virtual void get_script_signal_list(List<MethodInfo> *r_signals) const; + bool has_script_signal(const StringName &p_signal) const override; + void get_script_signal_list(List<MethodInfo> *r_signals) const override; - virtual bool get_property_default_value(const StringName &p_property, Variant &r_value) const; - virtual void get_script_property_list(List<PropertyInfo> *p_list) const; - virtual void update_exports(); + bool get_property_default_value(const StringName &p_property, Variant &r_value) const override; + void get_script_property_list(List<PropertyInfo> *p_list) const override; + void update_exports() override; void get_members(Set<StringName> *p_members) override; - virtual bool is_tool() const { return tool; } - virtual bool is_valid() const { return valid; } + bool is_tool() const override { return tool; } + bool is_valid() const override { return valid; } - bool inherits_script(const Ref<Script> &p_script) const; + bool inherits_script(const Ref<Script> &p_script) const override; - virtual Ref<Script> get_base_script() const; - virtual ScriptLanguage *get_language() const; + Ref<Script> get_base_script() const override; + ScriptLanguage *get_language() const override; - virtual void get_script_method_list(List<MethodInfo> *p_list) const; - bool has_method(const StringName &p_method) const; - MethodInfo get_method_info(const StringName &p_method) const; + void get_script_method_list(List<MethodInfo> *p_list) const override; + bool has_method(const StringName &p_method) const override; + MethodInfo get_method_info(const StringName &p_method) const override; - virtual int get_member_line(const StringName &p_member) const; + int get_member_line(const StringName &p_member) const override; - virtual Vector<ScriptNetData> get_rpc_methods() const; - virtual uint16_t get_rpc_method_id(const StringName &p_method) const; - virtual StringName get_rpc_method(const uint16_t p_rpc_method_id) const; - virtual MultiplayerAPI::RPCMode get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const; - virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const; + Vector<ScriptNetData> get_rpc_methods() const override; + uint16_t get_rpc_method_id(const StringName &p_method) const override; + StringName get_rpc_method(const uint16_t p_rpc_method_id) const override; + MultiplayerAPI::RPCMode get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const override; + MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const override; - virtual Vector<ScriptNetData> get_rset_properties() const; - virtual uint16_t get_rset_property_id(const StringName &p_variable) const; - virtual StringName get_rset_property(const uint16_t p_variable_id) const; - virtual MultiplayerAPI::RPCMode get_rset_mode_by_id(const uint16_t p_variable_id) const; - virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const; + Vector<ScriptNetData> get_rset_properties() const override; + uint16_t get_rset_property_id(const StringName &p_variable) const override; + StringName get_rset_property(const uint16_t p_variable_id) const override; + MultiplayerAPI::RPCMode get_rset_mode_by_id(const uint16_t p_variable_id) const override; + MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const override; #ifdef TOOLS_ENABLED - virtual bool is_placeholder_fallback_enabled() const { return placeholder_fallback_enabled; } + bool is_placeholder_fallback_enabled() const override { return placeholder_fallback_enabled; } #endif Error load_source_code(const String &p_path); - StringName get_script_name() const; - CSharpScript(); ~CSharpScript(); }; @@ -249,8 +249,6 @@ class CSharpInstance : public ScriptInstance { Ref<CSharpScript> script; MonoGCHandleData gchandle; - Vector<Callable> event_signal_callables; - bool _reference_owner_unsafe(); /* @@ -277,18 +275,18 @@ public: _FORCE_INLINE_ bool is_destructing_script_instance() { return destructing_script_instance; } - virtual Object *get_owner(); + Object *get_owner() override; - virtual bool set(const StringName &p_name, const Variant &p_value); - virtual bool get(const StringName &p_name, Variant &r_ret) const; - virtual void get_property_list(List<PropertyInfo> *p_properties) const; - virtual Variant::Type get_property_type(const StringName &p_name, bool *r_is_valid) const; + bool set(const StringName &p_name, const Variant &p_value) override; + bool get(const StringName &p_name, Variant &r_ret) const override; + void get_property_list(List<PropertyInfo> *p_properties) const override; + Variant::Type get_property_type(const StringName &p_name, bool *r_is_valid) const override; - /* TODO */ virtual void get_method_list(List<MethodInfo> *p_list) const {} - virtual bool has_method(const StringName &p_method) const; - virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error); - virtual void call_multilevel(const StringName &p_method, const Variant **p_args, int p_argcount); - virtual void call_multilevel_reversed(const StringName &p_method, const Variant **p_args, int p_argcount); + /* TODO */ void get_method_list(List<MethodInfo> *p_list) const override {} + bool has_method(const StringName &p_method) const override; + Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) override; + void call_multilevel(const StringName &p_method, const Variant **p_args, int p_argcount) override; + void call_multilevel_reversed(const StringName &p_method, const Variant **p_args, int p_argcount) override; void mono_object_disposed(MonoObject *p_obj); @@ -301,29 +299,29 @@ public: void connect_event_signals(); void disconnect_event_signals(); - virtual void refcount_incremented(); - virtual bool refcount_decremented(); + void refcount_incremented() override; + bool refcount_decremented() override; - virtual Vector<ScriptNetData> get_rpc_methods() const; - virtual uint16_t get_rpc_method_id(const StringName &p_method) const; - virtual StringName get_rpc_method(const uint16_t p_rpc_method_id) const; - virtual MultiplayerAPI::RPCMode get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const; - virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const; + Vector<ScriptNetData> get_rpc_methods() const override; + uint16_t get_rpc_method_id(const StringName &p_method) const override; + StringName get_rpc_method(const uint16_t p_rpc_method_id) const override; + MultiplayerAPI::RPCMode get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const override; + MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const override; - virtual Vector<ScriptNetData> get_rset_properties() const; - virtual uint16_t get_rset_property_id(const StringName &p_variable) const; - virtual StringName get_rset_property(const uint16_t p_variable_id) const; - virtual MultiplayerAPI::RPCMode get_rset_mode_by_id(const uint16_t p_variable_id) const; - virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const; + Vector<ScriptNetData> get_rset_properties() const override; + uint16_t get_rset_property_id(const StringName &p_variable) const override; + StringName get_rset_property(const uint16_t p_variable_id) const override; + MultiplayerAPI::RPCMode get_rset_mode_by_id(const uint16_t p_variable_id) const override; + MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const override; - virtual void notification(int p_notification); + void notification(int p_notification) override; void _call_notification(int p_notification); - virtual String to_string(bool *r_valid); + String to_string(bool *r_valid) override; - virtual Ref<Script> get_script() const; + Ref<Script> get_script() const override; - virtual ScriptLanguage *get_language(); + ScriptLanguage *get_language() override; CSharpInstance(const Ref<CSharpScript> &p_script); ~CSharpInstance(); @@ -437,83 +435,90 @@ public: } _FORCE_INLINE_ const Dictionary &get_scripts_metadata() { - if (scripts_metadata_invalidated) + if (scripts_metadata_invalidated) { _load_scripts_metadata(); + } return scripts_metadata; } _FORCE_INLINE_ ManagedCallableMiddleman *get_managed_callable_middleman() const { return managed_callable_middleman; } - virtual String get_name() const; + String get_name() const override; /* LANGUAGE FUNCTIONS */ - virtual String get_type() const; - virtual String get_extension() const; - virtual Error execute_file(const String &p_path); - virtual void init(); - virtual void finish(); + String get_type() const override; + String get_extension() const override; + Error execute_file(const String &p_path) override; + void init() override; + void finish() override; + + void finalize(); /* EDITOR FUNCTIONS */ - virtual void get_reserved_words(List<String> *p_words) const; - virtual void get_comment_delimiters(List<String> *p_delimiters) const; - virtual void get_string_delimiters(List<String> *p_delimiters) const; - virtual Ref<Script> get_template(const String &p_class_name, const String &p_base_class_name) const; - virtual bool is_using_templates(); - virtual void make_template(const String &p_class_name, const String &p_base_class_name, Ref<Script> &p_script); - /* TODO */ virtual bool validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path, List<String> *r_functions, List<ScriptLanguage::Warning> *r_warnings = nullptr, Set<int> *r_safe_lines = nullptr) const { return true; } - virtual String validate_path(const String &p_path) const; - virtual Script *create_script() const; - virtual bool has_named_classes() const; - virtual bool supports_builtin_mode() const; - /* TODO? */ virtual int find_function(const String &p_function, const String &p_code) const { return -1; } - virtual String make_function(const String &p_class, const String &p_name, const PackedStringArray &p_args) const; + void get_reserved_words(List<String> *p_words) const override; + void get_comment_delimiters(List<String> *p_delimiters) const override; + void get_string_delimiters(List<String> *p_delimiters) const override; + Ref<Script> get_template(const String &p_class_name, const String &p_base_class_name) const override; + bool is_using_templates() override; + void make_template(const String &p_class_name, const String &p_base_class_name, Ref<Script> &p_script) override; + /* TODO */ bool validate(const String &p_script, int &r_line_error, int &r_col_error, + String &r_test_error, const String &p_path, List<String> *r_functions, + List<ScriptLanguage::Warning> *r_warnings = nullptr, Set<int> *r_safe_lines = nullptr) const override { + return true; + } + String validate_path(const String &p_path) const override; + Script *create_script() const override; + bool has_named_classes() const override; + bool supports_builtin_mode() const override; + /* TODO? */ int find_function(const String &p_function, const String &p_code) const override { return -1; } + String make_function(const String &p_class, const String &p_name, const PackedStringArray &p_args) const override; virtual String _get_indentation() const; - /* TODO? */ virtual void auto_indent_code(String &p_code, int p_from_line, int p_to_line) const {} - /* TODO */ virtual void add_global_constant(const StringName &p_variable, const Variant &p_value) {} + /* TODO? */ void auto_indent_code(String &p_code, int p_from_line, int p_to_line) const override {} + /* TODO */ void add_global_constant(const StringName &p_variable, const Variant &p_value) override {} /* DEBUGGER FUNCTIONS */ - virtual String debug_get_error() const; - virtual int debug_get_stack_level_count() const; - virtual int debug_get_stack_level_line(int p_level) const; - virtual String debug_get_stack_level_function(int p_level) const; - virtual String debug_get_stack_level_source(int p_level) const; - /* TODO */ virtual void debug_get_stack_level_locals(int p_level, List<String> *p_locals, List<Variant> *p_values, int p_max_subitems, int p_max_depth) {} - /* TODO */ virtual void debug_get_stack_level_members(int p_level, List<String> *p_members, List<Variant> *p_values, int p_max_subitems, int p_max_depth) {} - /* TODO */ virtual void debug_get_globals(List<String> *p_locals, List<Variant> *p_values, int p_max_subitems, int p_max_depth) {} - /* TODO */ virtual String debug_parse_stack_level_expression(int p_level, const String &p_expression, int p_max_subitems, int p_max_depth) { return ""; } - virtual Vector<StackInfo> debug_get_current_stack_info(); + String debug_get_error() const override; + int debug_get_stack_level_count() const override; + int debug_get_stack_level_line(int p_level) const override; + String debug_get_stack_level_function(int p_level) const override; + String debug_get_stack_level_source(int p_level) const override; + /* TODO */ void debug_get_stack_level_locals(int p_level, List<String> *p_locals, List<Variant> *p_values, int p_max_subitems, int p_max_depth) override {} + /* TODO */ void debug_get_stack_level_members(int p_level, List<String> *p_members, List<Variant> *p_values, int p_max_subitems, int p_max_depth) override {} + /* TODO */ void debug_get_globals(List<String> *p_locals, List<Variant> *p_values, int p_max_subitems, int p_max_depth) override {} + /* TODO */ String debug_parse_stack_level_expression(int p_level, const String &p_expression, int p_max_subitems, int p_max_depth) override { return ""; } + Vector<StackInfo> debug_get_current_stack_info() override; /* PROFILING FUNCTIONS */ - /* TODO */ virtual void profiling_start() {} - /* TODO */ virtual void profiling_stop() {} - /* TODO */ virtual int profiling_get_accumulated_data(ProfilingInfo *p_info_arr, int p_info_max) { return 0; } - /* TODO */ virtual int profiling_get_frame_data(ProfilingInfo *p_info_arr, int p_info_max) { return 0; } + /* TODO */ void profiling_start() override {} + /* TODO */ void profiling_stop() override {} + /* TODO */ int profiling_get_accumulated_data(ProfilingInfo *p_info_arr, int p_info_max) override { return 0; } + /* TODO */ int profiling_get_frame_data(ProfilingInfo *p_info_arr, int p_info_max) override { return 0; } - virtual void frame(); + void frame() override; - /* TODO? */ virtual void get_public_functions(List<MethodInfo> *p_functions) const {} - /* TODO? */ virtual void get_public_constants(List<Pair<String, Variant>> *p_constants) const {} + /* TODO? */ void get_public_functions(List<MethodInfo> *p_functions) const override {} + /* TODO? */ void get_public_constants(List<Pair<String, Variant>> *p_constants) const override {} - virtual void reload_all_scripts(); - virtual void reload_tool_script(const Ref<Script> &p_script, bool p_soft_reload); + void reload_all_scripts() override; + void reload_tool_script(const Ref<Script> &p_script, bool p_soft_reload) override; /* LOADER FUNCTIONS */ - virtual void get_recognized_extensions(List<String> *p_extensions) const; + void get_recognized_extensions(List<String> *p_extensions) const override; #ifdef TOOLS_ENABLED - virtual Error open_in_external_editor(const Ref<Script> &p_script, int p_line, int p_col); - virtual bool overrides_external_editor(); + Error open_in_external_editor(const Ref<Script> &p_script, int p_line, int p_col) override; + bool overrides_external_editor() override; #endif /* THREAD ATTACHING */ - virtual void thread_enter(); - virtual void thread_exit(); + void thread_enter() override; + void thread_exit() override; // Don't use these. I'm watching you - virtual void *alloc_instance_binding_data(Object *p_object); - virtual void free_instance_binding_data(void *p_data); - virtual void refcount_incremented_instance_binding(Object *p_object); - virtual bool refcount_decremented_instance_binding(Object *p_object); + void *alloc_instance_binding_data(Object *p_object) override; + void free_instance_binding_data(void *p_data) override; + void refcount_incremented_instance_binding(Object *p_object) override; + bool refcount_decremented_instance_binding(Object *p_object) override; Map<Object *, CSharpScriptBinding>::Element *insert_script_binding(Object *p_object, const CSharpScriptBinding &p_script_binding); bool setup_csharp_script_binding(CSharpScriptBinding &r_script_binding, Object *p_object); @@ -531,17 +536,17 @@ public: class ResourceFormatLoaderCSharpScript : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); - virtual void get_recognized_extensions(List<String> *p_extensions) const; - virtual bool handles_type(const String &p_type) const; - virtual String get_resource_type(const String &p_path) const; + RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false) override; + void get_recognized_extensions(List<String> *p_extensions) const override; + bool handles_type(const String &p_type) const override; + String get_resource_type(const String &p_path) const override; }; class ResourceFormatSaverCSharpScript : public ResourceFormatSaver { public: - virtual Error save(const String &p_path, const RES &p_resource, uint32_t p_flags = 0); - virtual void get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const; - virtual bool recognize(const RES &p_resource) const; + Error save(const String &p_path, const RES &p_resource, uint32_t p_flags = 0) override; + void get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const override; + bool recognize(const RES &p_resource) const override; }; #endif // CSHARP_SCRIPT_H diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp index 730ffcb945..79e4b7c794 100644 --- a/modules/mono/editor/bindings_generator.cpp +++ b/modules/mono/editor/bindings_generator.cpp @@ -62,10 +62,8 @@ #define OPEN_BLOCK_L2 INDENT2 OPEN_BLOCK INDENT3 #define OPEN_BLOCK_L3 INDENT3 OPEN_BLOCK INDENT4 -#define OPEN_BLOCK_L4 INDENT4 OPEN_BLOCK INDENT5 #define CLOSE_BLOCK_L2 INDENT2 CLOSE_BLOCK #define CLOSE_BLOCK_L3 INDENT3 CLOSE_BLOCK -#define CLOSE_BLOCK_L4 INDENT4 CLOSE_BLOCK #define CS_FIELD_MEMORYOWN "memoryOwn" #define CS_PARAM_METHODBIND "method" diff --git a/modules/mono/editor/code_completion.cpp b/modules/mono/editor/code_completion.cpp index 7a5e465e7a..942c6d26a6 100644 --- a/modules/mono/editor/code_completion.cpp +++ b/modules/mono/editor/code_completion.cpp @@ -45,8 +45,9 @@ _FORCE_INLINE_ String quoted(const String &p_str) { } void _add_nodes_suggestions(const Node *p_base, const Node *p_node, PackedStringArray &r_suggestions) { - if (p_node != p_base && !p_node->get_owner()) + if (p_node != p_base && !p_node->get_owner()) { return; + } String path_relative_to_orig = p_base->get_path_to(p_node); @@ -58,18 +59,21 @@ void _add_nodes_suggestions(const Node *p_base, const Node *p_node, PackedString } Node *_find_node_for_script(Node *p_base, Node *p_current, const Ref<Script> &p_script) { - if (p_current->get_owner() != p_base && p_base != p_current) + if (p_current->get_owner() != p_base && p_base != p_current) { return nullptr; + } Ref<Script> c = p_current->get_script(); - if (c == p_script) + if (c == p_script) { return p_current; + } for (int i = 0; i < p_current->get_child_count(); i++) { Node *found = _find_node_for_script(p_base, p_current->get_child(i), p_script); - if (found) + if (found) { return found; + } } return nullptr; @@ -87,8 +91,9 @@ void _get_directory_contents(EditorFileSystemDirectory *p_dir, PackedStringArray Node *_try_find_owner_node_in_tree(const Ref<Script> p_script) { SceneTree *tree = SceneTree::get_singleton(); - if (!tree) + if (!tree) { return nullptr; + } Node *base = tree->get_edited_scene_root(); if (base) { base = _find_node_for_script(base, base, p_script); @@ -107,8 +112,9 @@ PackedStringArray get_code_completion(CompletionKind p_kind, const String &p_scr for (List<PropertyInfo>::Element *E = project_props.front(); E; E = E->next()) { const PropertyInfo &prop = E->get(); - if (!prop.name.begins_with("input/")) + if (!prop.name.begins_with("input/")) { continue; + } String name = prop.name.substr(prop.name.find("/") + 1, prop.name.length()); suggestions.push_back(quoted(name)); @@ -117,16 +123,11 @@ PackedStringArray get_code_completion(CompletionKind p_kind, const String &p_scr case CompletionKind::NODE_PATHS: { { // AutoLoads - List<PropertyInfo> props; - ProjectSettings::get_singleton()->get_property_list(&props); + Map<StringName, ProjectSettings::AutoloadInfo> autoloads = ProjectSettings::get_singleton()->get_autoload_list(); - for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) { - String s = E->get().name; - if (!s.begins_with("autoload/")) { - continue; - } - String name = s.get_slice("/", 1); - suggestions.push_back(quoted("/root/" + name)); + for (Map<StringName, ProjectSettings::AutoloadInfo>::Element *E = autoloads.front(); E; E = E->next()) { + const ProjectSettings::AutoloadInfo &info = E->value(); + suggestions.push_back(quoted("/root/" + String(info.name))); } } diff --git a/modules/mono/editor/csharp_project.cpp b/modules/mono/editor/csharp_project.cpp index 3a30f3106c..6f54eb09a2 100644 --- a/modules/mono/editor/csharp_project.cpp +++ b/modules/mono/editor/csharp_project.cpp @@ -45,8 +45,9 @@ namespace CSharpProject { void add_item(const String &p_project_path, const String &p_item_type, const String &p_include) { - if (!GLOBAL_DEF("mono/project/auto_update_project", true)) + if (!GLOBAL_DEF("mono/project/auto_update_project", true)) { return; + } GDMonoAssembly *tools_project_editor_assembly = GDMono::get_singleton()->get_tools_project_editor_assembly(); diff --git a/modules/mono/editor/editor_internal_calls.cpp b/modules/mono/editor/editor_internal_calls.cpp index b183787618..68fc372959 100644 --- a/modules/mono/editor/editor_internal_calls.cpp +++ b/modules/mono/editor/editor_internal_calls.cpp @@ -324,7 +324,7 @@ MonoObject *godot_icall_Internal_GetScriptsMetadataOrNothing(MonoReflectionType MonoType *dict_type = mono_reflection_type_get_type(p_dict_reftype); - uint32_t type_encoding = mono_type_get_type(dict_type); + int type_encoding = mono_type_get_type(dict_type); MonoClass *type_class_raw = mono_class_from_mono_type(dict_type); GDMonoClass *type_class = GDMono::get_singleton()->get_class(type_class_raw); diff --git a/modules/mono/editor/godotsharp_export.cpp b/modules/mono/editor/godotsharp_export.cpp index 1cdb08d50e..b15e9b060a 100644 --- a/modules/mono/editor/godotsharp_export.cpp +++ b/modules/mono/editor/godotsharp_export.cpp @@ -75,8 +75,9 @@ Error get_assembly_dependencies(GDMonoAssembly *p_assembly, const Vector<String> const String &ref_name = ref_info.name; - if (r_assembly_dependencies.has(ref_name)) + if (r_assembly_dependencies.has(ref_name)) { continue; + } GDMonoAssembly *ref_assembly = nullptr; @@ -130,8 +131,9 @@ Error get_exported_assembly_dependencies(const Dictionary &p_initial_assemblies, ERR_FAIL_COND_V_MSG(!load_success, ERR_CANT_RESOLVE, "Cannot load assembly (refonly): '" + assembly_name + "'."); Error err = get_assembly_dependencies(assembly, search_dirs, r_assembly_dependencies); - if (err != OK) + if (err != OK) { return err; + } } return OK; diff --git a/modules/mono/editor/script_class_parser.cpp b/modules/mono/editor/script_class_parser.cpp index 7276612230..012ccd5339 100644 --- a/modules/mono/editor/script_class_parser.cpp +++ b/modules/mono/editor/script_class_parser.cpp @@ -208,8 +208,9 @@ ScriptClassParser::Token ScriptClassParser::get_token() { tk_string += res; } else { - if (code[idx] == '\n') + if (code[idx] == '\n') { line++; + } tk_string += code[idx]; } idx++; @@ -300,15 +301,17 @@ Error ScriptClassParser::_skip_generic_type_params() { tk = get_token(); - if (tk != TK_PERIOD) + if (tk != TK_PERIOD) { break; + } } } if (tk == TK_OP_LESS) { Error err = _skip_generic_type_params(); - if (err) + if (err) { return err; + } tk = get_token(); } @@ -349,12 +352,14 @@ Error ScriptClassParser::_parse_type_full_name(String &r_full_name) { // We don't mind if the base is generic, but we skip it any ways since this information is not needed Error err = _skip_generic_type_params(); - if (err) + if (err) { return err; + } } - if (code[idx] != '.') // We only want to take the next token if it's a period + if (code[idx] != '.') { // We only want to take the next token if it's a period return OK; + } tk = get_token(); @@ -369,15 +374,17 @@ Error ScriptClassParser::_parse_class_base(Vector<String> &r_base) { String name; Error err = _parse_type_full_name(name); - if (err) + if (err) { return err; + } Token tk = get_token(); if (tk == TK_COMMA) { err = _parse_class_base(r_base); - if (err) + if (err) { return err; + } } else if (tk == TK_IDENTIFIER && String(value) == "where") { err = _parse_type_constraints(); if (err) { @@ -433,8 +440,9 @@ Error ScriptClassParser::_parse_type_constraints() { tk = get_token(); - if (tk != TK_PERIOD) + if (tk != TK_PERIOD) { break; + } } } } @@ -452,8 +460,9 @@ Error ScriptClassParser::_parse_type_constraints() { } } else if (tk == TK_OP_LESS) { Error err = _skip_generic_type_params(); - if (err) + if (err) { return err; + } } else if (tk == TK_CURLY_BRACKET_OPEN) { return OK; } else { @@ -522,8 +531,9 @@ Error ScriptClassParser::parse(const String &p_code) { const NameDecl &name_decl = E->value(); if (name_decl.type == NameDecl::NAMESPACE_DECL) { - if (E != name_stack.front()) + if (E != name_stack.front()) { class_decl.namespace_ += "."; + } class_decl.namespace_ += name_decl.name; } else { class_decl.name += name_decl.name + "."; @@ -540,8 +550,9 @@ Error ScriptClassParser::parse(const String &p_code) { if (tk == TK_COLON) { Error err = _parse_class_base(class_decl.base); - if (err) + if (err) { return err; + } curly_stack++; type_curly_stack++; @@ -555,8 +566,9 @@ Error ScriptClassParser::parse(const String &p_code) { generic = true; Error err = _skip_generic_type_params(); - if (err) + if (err) { return err; + } } else if (tk == TK_IDENTIFIER && String(value) == "where") { Error err = _parse_type_constraints(); if (err) { @@ -584,8 +596,9 @@ Error ScriptClassParser::parse(const String &p_code) { classes.push_back(class_decl); } else if (OS::get_singleton()->is_stdout_verbose()) { String full_name = class_decl.namespace_; - if (full_name.length()) + if (full_name.length()) { full_name += "."; + } full_name += class_decl.name; OS::get_singleton()->print("Ignoring generic class declaration: %s\n", full_name.utf8().get_data()); } @@ -602,8 +615,9 @@ Error ScriptClassParser::parse(const String &p_code) { int at_level = curly_stack; Error err = _parse_namespace_name(name, curly_stack); - if (err) + if (err) { return err; + } NameDecl name_decl; name_decl.name = name; @@ -614,8 +628,9 @@ Error ScriptClassParser::parse(const String &p_code) { } else if (tk == TK_CURLY_BRACKET_CLOSE) { curly_stack--; if (name_stack.has(curly_stack)) { - if (name_stack[curly_stack].type != NameDecl::NAMESPACE_DECL) + if (name_stack[curly_stack].type != NameDecl::NAMESPACE_DECL) { type_curly_stack--; + } name_stack.erase(curly_stack); } } @@ -628,8 +643,9 @@ Error ScriptClassParser::parse(const String &p_code) { error = true; } - if (error) + if (error) { return ERR_PARSE_ERROR; + } return OK; } @@ -702,8 +718,9 @@ static void run_dummy_preprocessor(String &r_source, const String &p_filepath) { // Custom join ignoring lines removed by the preprocessor for (int i = 0; i < lines.size(); i++) { - if (i > 0 && include_lines[i - 1]) + if (i > 0 && include_lines[i - 1]) { r_source += '\n'; + } if (include_lines[i]) { r_source += lines[i]; diff --git a/modules/mono/editor/script_class_parser.h b/modules/mono/editor/script_class_parser.h index c194ed1422..d611e8fb74 100644 --- a/modules/mono/editor/script_class_parser.h +++ b/modules/mono/editor/script_class_parser.h @@ -53,7 +53,6 @@ public: String namespace_; Vector<String> base; bool nested; - bool has_script_attr; }; private: diff --git a/modules/mono/glue/arguments_vector.h b/modules/mono/glue/arguments_vector.h index 4ee553fc11..ab48904571 100644 --- a/modules/mono/glue/arguments_vector.h +++ b/modules/mono/glue/arguments_vector.h @@ -40,8 +40,8 @@ private: T *_ptr; int size; - ArgumentsVector(); - ArgumentsVector(const ArgumentsVector &); + ArgumentsVector() = delete; + ArgumentsVector(const ArgumentsVector &) = delete; public: T *ptr() { return _ptr; } diff --git a/modules/mono/glue/base_object_glue.cpp b/modules/mono/glue/base_object_glue.cpp index f370883320..ebcd6d5e9c 100644 --- a/modules/mono/glue/base_object_glue.cpp +++ b/modules/mono/glue/base_object_glue.cpp @@ -28,10 +28,10 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "base_object_glue.h" - #ifdef MONO_GLUE_ENABLED +#include "core/class_db.h" +#include "core/object.h" #include "core/reference.h" #include "core/string_name.h" @@ -39,6 +39,7 @@ #include "../mono_gd/gd_mono_cache.h" #include "../mono_gd/gd_mono_class.h" #include "../mono_gd/gd_mono_internals.h" +#include "../mono_gd/gd_mono_marshal.h" #include "../mono_gd/gd_mono_utils.h" #include "../signal_awaiter_utils.h" #include "arguments_vector.h" @@ -140,16 +141,18 @@ MethodBind *godot_icall_Object_ClassDB_get_method(StringName *p_type, MonoString } MonoObject *godot_icall_Object_weakref(Object *p_ptr) { - if (!p_ptr) + if (!p_ptr) { return nullptr; + } Ref<WeakRef> wref; Reference *ref = Object::cast_to<Reference>(p_ptr); if (ref) { REF r = ref; - if (!r.is_valid()) + if (!r.is_valid()) { return nullptr; + } wref.instance(); wref->set_ref(r); @@ -241,6 +244,7 @@ void godot_register_object_icalls() { mono_add_internal_call("Godot.Object::godot_icall_Object_Ctor", (void *)godot_icall_Object_Ctor); mono_add_internal_call("Godot.Object::godot_icall_Object_Disposed", (void *)godot_icall_Object_Disposed); mono_add_internal_call("Godot.Object::godot_icall_Reference_Disposed", (void *)godot_icall_Reference_Disposed); + mono_add_internal_call("Godot.Object::godot_icall_Object_ConnectEventSignals", (void *)godot_icall_Object_ConnectEventSignals); mono_add_internal_call("Godot.Object::godot_icall_Object_ClassDB_get_method", (void *)godot_icall_Object_ClassDB_get_method); mono_add_internal_call("Godot.Object::godot_icall_Object_ToString", (void *)godot_icall_Object_ToString); mono_add_internal_call("Godot.Object::godot_icall_Object_weakref", (void *)godot_icall_Object_weakref); diff --git a/modules/mono/glue/base_object_glue.h b/modules/mono/glue/base_object_glue.h deleted file mode 100644 index 67769f3061..0000000000 --- a/modules/mono/glue/base_object_glue.h +++ /dev/null @@ -1,73 +0,0 @@ -/*************************************************************************/ -/* base_object_glue.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef BASE_OBJECT_GLUE_H -#define BASE_OBJECT_GLUE_H - -#ifdef MONO_GLUE_ENABLED - -#include "core/class_db.h" -#include "core/object.h" - -#include "../mono_gd/gd_mono_marshal.h" - -Object *godot_icall_Object_Ctor(MonoObject *p_obj); - -void godot_icall_Object_Disposed(MonoObject *p_obj, Object *p_ptr); - -void godot_icall_Reference_Disposed(MonoObject *p_obj, Object *p_ptr, MonoBoolean p_is_finalizer); - -void godot_icall_Object_ConnectEventSignals(Object *p_ptr); - -MethodBind *godot_icall_Object_ClassDB_get_method(StringName *p_type, MonoString *p_method); - -MonoObject *godot_icall_Object_weakref(Object *p_ptr); - -Error godot_icall_SignalAwaiter_connect(Object *p_source, StringName *p_signal, Object *p_target, MonoObject *p_awaiter); - -// DynamicGodotObject - -MonoArray *godot_icall_DynamicGodotObject_SetMemberList(Object *p_ptr); - -MonoBoolean godot_icall_DynamicGodotObject_InvokeMember(Object *p_ptr, MonoString *p_name, MonoArray *p_args, MonoObject **r_result); - -MonoBoolean godot_icall_DynamicGodotObject_GetMember(Object *p_ptr, MonoString *p_name, MonoObject **r_result); - -MonoBoolean godot_icall_DynamicGodotObject_SetMember(Object *p_ptr, MonoString *p_name, MonoObject *p_value); - -MonoString *godot_icall_Object_ToString(Object *p_ptr); - -// Register internal calls - -void godot_register_object_icalls(); - -#endif // MONO_GLUE_ENABLED - -#endif // BASE_OBJECT_GLUE_H diff --git a/modules/mono/glue/collections_glue.cpp b/modules/mono/glue/collections_glue.cpp index 4e3dc9c4ea..766b00d612 100644 --- a/modules/mono/glue/collections_glue.cpp +++ b/modules/mono/glue/collections_glue.cpp @@ -28,14 +28,15 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "collections_glue.h" - #ifdef MONO_GLUE_ENABLED #include <mono/metadata/exception.h> +#include "core/array.h" + #include "../mono_gd/gd_mono_cache.h" #include "../mono_gd/gd_mono_class.h" +#include "../mono_gd/gd_mono_marshal.h" #include "../mono_gd/gd_mono_utils.h" Array *godot_icall_Array_Ctor() { diff --git a/modules/mono/glue/collections_glue.h b/modules/mono/glue/collections_glue.h deleted file mode 100644 index f8351a1fc7..0000000000 --- a/modules/mono/glue/collections_glue.h +++ /dev/null @@ -1,124 +0,0 @@ -/*************************************************************************/ -/* collections_glue.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef COLLECTIONS_GLUE_H -#define COLLECTIONS_GLUE_H - -#ifdef MONO_GLUE_ENABLED - -#include "core/array.h" - -#include "../mono_gd/gd_mono_marshal.h" - -// Array - -Array *godot_icall_Array_Ctor(); - -void godot_icall_Array_Dtor(Array *ptr); - -MonoObject *godot_icall_Array_At(Array *ptr, int index); - -MonoObject *godot_icall_Array_At_Generic(Array *ptr, int index, uint32_t type_encoding, GDMonoClass *type_class); - -void godot_icall_Array_SetAt(Array *ptr, int index, MonoObject *value); - -int godot_icall_Array_Count(Array *ptr); - -int godot_icall_Array_Add(Array *ptr, MonoObject *item); - -void godot_icall_Array_Clear(Array *ptr); - -MonoBoolean godot_icall_Array_Contains(Array *ptr, MonoObject *item); - -void godot_icall_Array_CopyTo(Array *ptr, MonoArray *array, int array_index); - -Array *godot_icall_Array_Duplicate(Array *ptr, MonoBoolean deep); - -int godot_icall_Array_IndexOf(Array *ptr, MonoObject *item); - -void godot_icall_Array_Insert(Array *ptr, int index, MonoObject *item); - -MonoBoolean godot_icall_Array_Remove(Array *ptr, MonoObject *item); - -void godot_icall_Array_RemoveAt(Array *ptr, int index); - -Error godot_icall_Array_Resize(Array *ptr, int new_size); - -void godot_icall_Array_Generic_GetElementTypeInfo(MonoReflectionType *refltype, uint32_t *type_encoding, GDMonoClass **type_class); - -MonoString *godot_icall_Array_ToString(Array *ptr); - -// Dictionary - -Dictionary *godot_icall_Dictionary_Ctor(); - -void godot_icall_Dictionary_Dtor(Dictionary *ptr); - -MonoObject *godot_icall_Dictionary_GetValue(Dictionary *ptr, MonoObject *key); - -MonoObject *godot_icall_Dictionary_GetValue_Generic(Dictionary *ptr, MonoObject *key, uint32_t type_encoding, GDMonoClass *type_class); - -void godot_icall_Dictionary_SetValue(Dictionary *ptr, MonoObject *key, MonoObject *value); - -Array *godot_icall_Dictionary_Keys(Dictionary *ptr); - -Array *godot_icall_Dictionary_Values(Dictionary *ptr); - -int godot_icall_Dictionary_Count(Dictionary *ptr); - -void godot_icall_Dictionary_Add(Dictionary *ptr, MonoObject *key, MonoObject *value); - -void godot_icall_Dictionary_Clear(Dictionary *ptr); - -MonoBoolean godot_icall_Dictionary_Contains(Dictionary *ptr, MonoObject *key, MonoObject *value); - -MonoBoolean godot_icall_Dictionary_ContainsKey(Dictionary *ptr, MonoObject *key); - -Dictionary *godot_icall_Dictionary_Duplicate(Dictionary *ptr, MonoBoolean deep); - -MonoBoolean godot_icall_Dictionary_RemoveKey(Dictionary *ptr, MonoObject *key); - -MonoBoolean godot_icall_Dictionary_Remove(Dictionary *ptr, MonoObject *key, MonoObject *value); - -MonoBoolean godot_icall_Dictionary_TryGetValue(Dictionary *ptr, MonoObject *key, MonoObject **value); - -MonoBoolean godot_icall_Dictionary_TryGetValue_Generic(Dictionary *ptr, MonoObject *key, MonoObject **value, uint32_t type_encoding, GDMonoClass *type_class); - -void godot_icall_Dictionary_Generic_GetValueTypeInfo(MonoReflectionType *refltype, uint32_t *type_encoding, GDMonoClass **type_class); - -MonoString *godot_icall_Dictionary_ToString(Dictionary *ptr); - -// Register internal calls - -void godot_register_collections_icalls(); - -#endif // MONO_GLUE_ENABLED - -#endif // COLLECTIONS_GLUE_H diff --git a/modules/mono/glue/gd_glue.cpp b/modules/mono/glue/gd_glue.cpp index e43b06d18e..5e892b616b 100644 --- a/modules/mono/glue/gd_glue.cpp +++ b/modules/mono/glue/gd_glue.cpp @@ -28,8 +28,6 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "gd_glue.h" - #ifdef MONO_GLUE_ENABLED #include "core/array.h" @@ -40,6 +38,7 @@ #include "core/variant_parser.h" #include "../mono_gd/gd_mono_cache.h" +#include "../mono_gd/gd_mono_marshal.h" #include "../mono_gd/gd_mono_utils.h" MonoObject *godot_icall_GD_bytes2var(MonoArray *p_bytes, MonoBoolean p_allow_objects) { @@ -147,8 +146,9 @@ void godot_icall_GD_prints(MonoArray *p_what) { return; } - if (i) + if (i) { str += " "; + } str += elem_str; } @@ -171,8 +171,9 @@ void godot_icall_GD_printt(MonoArray *p_what) { return; } - if (i) + if (i) { str += "\t"; + } str += elem_str; } @@ -197,7 +198,7 @@ double godot_icall_GD_rand_range(double from, double to) { } uint32_t godot_icall_GD_rand_seed(uint64_t seed, uint64_t *newSeed) { - int ret = Math::rand_from_seed(&seed); + uint32_t ret = Math::rand_from_seed(&seed); *newSeed = seed; return ret; } @@ -213,10 +214,11 @@ MonoString *godot_icall_GD_str(MonoArray *p_what) { for (int i = 0; i < what.size(); i++) { String os = what[i].operator String(); - if (i == 0) + if (i == 0) { str = os; - else + } else { str += os; + } } return GDMonoMarshal::mono_string_from_godot(str); diff --git a/modules/mono/glue/gd_glue.h b/modules/mono/glue/gd_glue.h deleted file mode 100644 index 3ad6058205..0000000000 --- a/modules/mono/glue/gd_glue.h +++ /dev/null @@ -1,86 +0,0 @@ -/*************************************************************************/ -/* gd_glue.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef GD_GLUE_H -#define GD_GLUE_H - -#ifdef MONO_GLUE_ENABLED - -#include "../mono_gd/gd_mono_marshal.h" - -MonoObject *godot_icall_GD_bytes2var(MonoArray *p_bytes, MonoBoolean p_allow_objects); - -MonoObject *godot_icall_GD_convert(MonoObject *p_what, int32_t p_type); - -int godot_icall_GD_hash(MonoObject *p_var); - -MonoObject *godot_icall_GD_instance_from_id(uint64_t p_instance_id); - -void godot_icall_GD_print(MonoArray *p_what); - -void godot_icall_GD_printerr(MonoArray *p_what); - -void godot_icall_GD_printraw(MonoArray *p_what); - -void godot_icall_GD_prints(MonoArray *p_what); - -void godot_icall_GD_printt(MonoArray *p_what); - -float godot_icall_GD_randf(); - -uint32_t godot_icall_GD_randi(); - -void godot_icall_GD_randomize(); - -double godot_icall_GD_rand_range(double from, double to); - -uint32_t godot_icall_GD_rand_seed(uint64_t seed, uint64_t *newSeed); - -void godot_icall_GD_seed(uint64_t p_seed); - -MonoString *godot_icall_GD_str(MonoArray *p_what); - -MonoObject *godot_icall_GD_str2var(MonoString *p_str); - -MonoBoolean godot_icall_GD_type_exists(StringName *p_type); - -MonoArray *godot_icall_GD_var2bytes(MonoObject *p_var, MonoBoolean p_full_objects); - -MonoString *godot_icall_GD_var2str(MonoObject *p_var); - -MonoObject *godot_icall_DefaultGodotTaskScheduler(); - -// Register internal calls - -void godot_register_gd_icalls(); - -#endif // MONO_GLUE_ENABLED - -#endif // GD_GLUE_H diff --git a/modules/mono/glue/glue_header.h b/modules/mono/glue/glue_header.h index f6999d01fb..c1f1936711 100644 --- a/modules/mono/glue/glue_header.h +++ b/modules/mono/glue/glue_header.h @@ -30,14 +30,16 @@ #ifdef MONO_GLUE_ENABLED -#include "base_object_glue.h" -#include "collections_glue.h" -#include "gd_glue.h" -#include "nodepath_glue.h" -#include "rid_glue.h" -#include "scene_tree_glue.h" -#include "string_glue.h" -#include "string_name_glue.h" +#include "../mono_gd/gd_mono_marshal.h" + +void godot_register_collections_icalls(); +void godot_register_gd_icalls(); +void godot_register_string_name_icalls(); +void godot_register_nodepath_icalls(); +void godot_register_object_icalls(); +void godot_register_rid_icalls(); +void godot_register_string_icalls(); +void godot_register_scene_tree_icalls(); /** * Registers internal calls that were not generated. This function is called diff --git a/modules/mono/glue/nodepath_glue.cpp b/modules/mono/glue/nodepath_glue.cpp index e413f404d8..2aa75dd309 100644 --- a/modules/mono/glue/nodepath_glue.cpp +++ b/modules/mono/glue/nodepath_glue.cpp @@ -28,12 +28,13 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "nodepath_glue.h" - #ifdef MONO_GLUE_ENABLED +#include "core/node_path.h" #include "core/ustring.h" +#include "../mono_gd/gd_mono_marshal.h" + NodePath *godot_icall_NodePath_Ctor(MonoString *p_path) { return memnew(NodePath(GDMonoMarshal::mono_string_to_godot(p_path))); } @@ -51,7 +52,7 @@ MonoBoolean godot_icall_NodePath_is_absolute(NodePath *p_ptr) { return (MonoBoolean)p_ptr->is_absolute(); } -uint32_t godot_icall_NodePath_get_name_count(NodePath *p_ptr) { +int32_t godot_icall_NodePath_get_name_count(NodePath *p_ptr) { return p_ptr->get_name_count(); } @@ -59,7 +60,7 @@ MonoString *godot_icall_NodePath_get_name(NodePath *p_ptr, uint32_t p_idx) { return GDMonoMarshal::mono_string_from_godot(p_ptr->get_name(p_idx)); } -uint32_t godot_icall_NodePath_get_subname_count(NodePath *p_ptr) { +int32_t godot_icall_NodePath_get_subname_count(NodePath *p_ptr) { return p_ptr->get_subname_count(); } diff --git a/modules/mono/glue/nodepath_glue.h b/modules/mono/glue/nodepath_glue.h deleted file mode 100644 index 727679c278..0000000000 --- a/modules/mono/glue/nodepath_glue.h +++ /dev/null @@ -1,68 +0,0 @@ -/*************************************************************************/ -/* nodepath_glue.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef NODEPATH_GLUE_H -#define NODEPATH_GLUE_H - -#ifdef MONO_GLUE_ENABLED - -#include "core/node_path.h" - -#include "../mono_gd/gd_mono_marshal.h" - -NodePath *godot_icall_NodePath_Ctor(MonoString *p_path); - -void godot_icall_NodePath_Dtor(NodePath *p_ptr); - -MonoString *godot_icall_NodePath_operator_String(NodePath *p_np); - -MonoBoolean godot_icall_NodePath_is_absolute(NodePath *p_ptr); - -uint32_t godot_icall_NodePath_get_name_count(NodePath *p_ptr); - -MonoString *godot_icall_NodePath_get_name(NodePath *p_ptr, uint32_t p_idx); - -uint32_t godot_icall_NodePath_get_subname_count(NodePath *p_ptr); - -MonoString *godot_icall_NodePath_get_subname(NodePath *p_ptr, uint32_t p_idx); - -MonoString *godot_icall_NodePath_get_concatenated_subnames(NodePath *p_ptr); - -NodePath *godot_icall_NodePath_get_as_property_path(NodePath *p_ptr); - -MonoBoolean godot_icall_NodePath_is_empty(NodePath *p_ptr); - -// Register internal calls - -void godot_register_nodepath_icalls(); - -#endif // MONO_GLUE_ENABLED - -#endif // NODEPATH_GLUE_H diff --git a/modules/mono/glue/rid_glue.cpp b/modules/mono/glue/rid_glue.cpp index 66a49d8fec..6d2e6b559f 100644 --- a/modules/mono/glue/rid_glue.cpp +++ b/modules/mono/glue/rid_glue.cpp @@ -28,17 +28,20 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "rid_glue.h" - #ifdef MONO_GLUE_ENABLED +#include "core/object.h" #include "core/resource.h" +#include "core/rid.h" + +#include "../mono_gd/gd_mono_marshal.h" RID *godot_icall_RID_Ctor(Object *p_from) { Resource *res_from = Object::cast_to<Resource>(p_from); - if (res_from) + if (res_from) { return memnew(RID(res_from->get_rid())); + } return memnew(RID); } diff --git a/modules/mono/glue/rid_glue.h b/modules/mono/glue/rid_glue.h deleted file mode 100644 index 506d715451..0000000000 --- a/modules/mono/glue/rid_glue.h +++ /dev/null @@ -1,53 +0,0 @@ -/*************************************************************************/ -/* rid_glue.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef RID_GLUE_H -#define RID_GLUE_H - -#ifdef MONO_GLUE_ENABLED - -#include "core/object.h" -#include "core/rid.h" - -#include "../mono_gd/gd_mono_marshal.h" - -RID *godot_icall_RID_Ctor(Object *p_from); - -void godot_icall_RID_Dtor(RID *p_ptr); - -uint32_t godot_icall_RID_get_id(RID *p_ptr); - -// Register internal calls - -void godot_register_rid_icalls(); - -#endif // MONO_GLUE_ENABLED - -#endif // RID_GLUE_H diff --git a/modules/mono/glue/scene_tree_glue.cpp b/modules/mono/glue/scene_tree_glue.cpp index bea9544b08..b43daccc1b 100644 --- a/modules/mono/glue/scene_tree_glue.cpp +++ b/modules/mono/glue/scene_tree_glue.cpp @@ -28,14 +28,17 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "scene_tree_glue.h" - #ifdef MONO_GLUE_ENABLED +#include "core/array.h" #include "core/class_db.h" -#include "modules/mono/csharp_script.h" -#include "modules/mono/mono_gd/gd_mono_utils.h" +#include "core/string_name.h" #include "scene/main/node.h" +#include "scene/main/scene_tree.h" + +#include "../csharp_script.h" +#include "../mono_gd/gd_mono_marshal.h" +#include "../mono_gd/gd_mono_utils.h" Array *godot_icall_SceneTree_get_nodes_in_group_Generic(SceneTree *ptr, StringName *group, MonoReflectionType *refltype) { List<Node *> nodes; @@ -54,8 +57,9 @@ Array *godot_icall_SceneTree_get_nodes_in_group_Generic(SceneTree *ptr, StringNa // If we're trying to get native objects, just check the inheritance list StringName native_class_name = GDMonoUtils::get_native_godot_class_name(klass); for (int i = 0; i < nodes.size(); ++i) { - if (ClassDB::is_parent_class(nodes[i]->get_class(), native_class_name)) + if (ClassDB::is_parent_class(nodes[i]->get_class(), native_class_name)) { ret.push_back(nodes[i]); + } } } else { // If we're trying to get csharpscript instances, get the mono object and compare the classes diff --git a/modules/mono/glue/scene_tree_glue.h b/modules/mono/glue/scene_tree_glue.h deleted file mode 100644 index e9af35a30b..0000000000 --- a/modules/mono/glue/scene_tree_glue.h +++ /dev/null @@ -1,50 +0,0 @@ -/*************************************************************************/ -/* scene_tree_glue.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef SCENE_TREE_GLUE_H -#define SCENE_TREE_GLUE_H - -#ifdef MONO_GLUE_ENABLED - -#include "core/array.h" -#include "core/string_name.h" -#include "scene/main/scene_tree.h" - -#include "../mono_gd/gd_mono_marshal.h" - -Array *godot_icall_SceneTree_get_nodes_in_group_Generic(SceneTree *ptr, StringName *group, MonoReflectionType *refltype); - -// Register internal calls - -void godot_register_scene_tree_icalls(); - -#endif // MONO_GLUE_ENABLED - -#endif // SCENE_TREE_GLUE_H diff --git a/modules/mono/glue/string_glue.cpp b/modules/mono/glue/string_glue.cpp index e407a70db9..595b8d71f1 100644 --- a/modules/mono/glue/string_glue.cpp +++ b/modules/mono/glue/string_glue.cpp @@ -28,14 +28,14 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "string_glue.h" - #ifdef MONO_GLUE_ENABLED #include "core/ustring.h" #include "core/variant.h" #include "core/vector.h" +#include "../mono_gd/gd_mono_marshal.h" + MonoArray *godot_icall_String_md5_buffer(MonoString *p_str) { Vector<uint8_t> ret = GDMonoMarshal::mono_string_to_godot(p_str).md5_buffer(); // TODO Check possible Array/Vector<uint8_t> problem? diff --git a/modules/mono/glue/string_glue.h b/modules/mono/glue/string_glue.h deleted file mode 100644 index a5e833ba61..0000000000 --- a/modules/mono/glue/string_glue.h +++ /dev/null @@ -1,56 +0,0 @@ -/*************************************************************************/ -/* string_glue.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef STRING_GLUE_H -#define STRING_GLUE_H - -#ifdef MONO_GLUE_ENABLED - -#include "../mono_gd/gd_mono_marshal.h" - -MonoArray *godot_icall_String_md5_buffer(MonoString *p_str); - -MonoString *godot_icall_String_md5_text(MonoString *p_str); - -int godot_icall_String_rfind(MonoString *p_str, MonoString *p_what, int p_from); - -int godot_icall_String_rfindn(MonoString *p_str, MonoString *p_what, int p_from); - -MonoArray *godot_icall_String_sha256_buffer(MonoString *p_str); - -MonoString *godot_icall_String_sha256_text(MonoString *p_str); - -// Register internal calls - -void godot_register_string_icalls(); - -#endif // MONO_GLUE_ENABLED - -#endif // STRING_GLUE_H diff --git a/modules/mono/glue/string_name_glue.cpp b/modules/mono/glue/string_name_glue.cpp index 81006e5849..4b2e88569b 100644 --- a/modules/mono/glue/string_name_glue.cpp +++ b/modules/mono/glue/string_name_glue.cpp @@ -28,12 +28,13 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "string_name_glue.h" - #ifdef MONO_GLUE_ENABLED +#include "core/string_name.h" #include "core/ustring.h" +#include "../mono_gd/gd_mono_marshal.h" + StringName *godot_icall_StringName_Ctor(MonoString *p_path) { return memnew(StringName(GDMonoMarshal::mono_string_to_godot(p_path))); } @@ -48,7 +49,7 @@ MonoString *godot_icall_StringName_operator_String(StringName *p_np) { } MonoBoolean godot_icall_StringName_is_empty(StringName *p_ptr) { - return (MonoBoolean)(p_ptr == StringName()); + return (MonoBoolean)(*p_ptr == StringName()); } void godot_register_string_name_icalls() { diff --git a/modules/mono/glue/string_name_glue.h b/modules/mono/glue/string_name_glue.h deleted file mode 100644 index 88354ddd84..0000000000 --- a/modules/mono/glue/string_name_glue.h +++ /dev/null @@ -1,54 +0,0 @@ -/*************************************************************************/ -/* string_name_glue.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef STRING_NAME_GLUE_H -#define STRING_NAME_GLUE_H - -#ifdef MONO_GLUE_ENABLED - -#include "core/string_name.h" - -#include "../mono_gd/gd_mono_marshal.h" - -StringName *godot_icall_StringName_Ctor(MonoString *p_path); - -void godot_icall_StringName_Dtor(StringName *p_ptr); - -MonoString *godot_icall_StringName_operator_String(StringName *p_np); - -MonoBoolean godot_icall_StringName_is_empty(StringName *p_ptr); - -// Register internal calls - -void godot_register_string_name_icalls(); - -#endif // MONO_GLUE_ENABLED - -#endif // STRING_NAME_GLUE_H diff --git a/modules/mono/managed_callable.cpp b/modules/mono/managed_callable.cpp index 26347e9162..dbe9c7fc5d 100644 --- a/modules/mono/managed_callable.cpp +++ b/modules/mono/managed_callable.cpp @@ -48,8 +48,9 @@ bool ManagedCallable::compare_equal(const CallableCustom *p_a, const CallableCus MonoDelegate *delegate_b = (MonoDelegate *)b->delegate_handle.get_target(); if (!delegate_a || !delegate_b) { - if (!delegate_a && !delegate_b) + if (!delegate_a && !delegate_b) { return true; + } return false; } @@ -58,8 +59,9 @@ bool ManagedCallable::compare_equal(const CallableCustom *p_a, const CallableCus } bool ManagedCallable::compare_less(const CallableCustom *p_a, const CallableCustom *p_b) { - if (compare_equal(p_a, p_b)) + if (compare_equal(p_a, p_b)) { return false; + } return p_a < p_b; } diff --git a/modules/mono/mono_gd/gd_mono.cpp b/modules/mono/mono_gd/gd_mono.cpp index 39c3bd8934..cf5ac33d20 100644 --- a/modules/mono/mono_gd/gd_mono.cpp +++ b/modules/mono/mono_gd/gd_mono.cpp @@ -144,8 +144,9 @@ void gd_mono_debug_init() { if (Engine::get_singleton()->is_editor_hint() || ProjectSettings::get_singleton()->get_resource_path().empty() || Main::is_project_manager()) { - if (da_args.size() == 0) + if (da_args.size() == 0) { return; + } } if (da_args.length() == 0) { @@ -423,24 +424,27 @@ void GDMono::initialize_load_assemblies() { bool tool_assemblies_loaded = _load_tools_assemblies(); CRASH_COND_MSG(!tool_assemblies_loaded, "Mono: Failed to load '" TOOLS_ASM_NAME "' assemblies."); - if (Main::is_project_manager()) + if (Main::is_project_manager()) { return; + } #endif // Load the project's main assembly. This doesn't necessarily need to succeed. // The game may not be using .NET at all, or if the project does use .NET and // we're running in the editor, it may just happen to be it wasn't built yet. if (!_load_project_assembly()) { - if (OS::get_singleton()->is_stdout_verbose()) + if (OS::get_singleton()->is_stdout_verbose()) { print_error("Mono: Failed to load project assembly"); + } } } bool GDMono::_are_api_assemblies_out_of_sync() { bool out_of_sync = core_api_assembly.assembly && (core_api_assembly.out_of_sync || !GDMonoCache::cached_data.godot_api_cache_updated); #ifdef TOOLS_ENABLED - if (!out_of_sync) + if (!out_of_sync) { out_of_sync = editor_api_assembly.assembly && editor_api_assembly.out_of_sync; + } #endif return out_of_sync; } @@ -512,16 +516,17 @@ void GDMono::_init_exception_policy() { } } -void GDMono::add_assembly(uint32_t p_domain_id, GDMonoAssembly *p_assembly) { +void GDMono::add_assembly(int32_t p_domain_id, GDMonoAssembly *p_assembly) { assemblies[p_domain_id][p_assembly->get_name()] = p_assembly; } GDMonoAssembly *GDMono::get_loaded_assembly(const String &p_name) { - if (p_name == "mscorlib" && corlib_assembly) + if (p_name == "mscorlib" && corlib_assembly) { return corlib_assembly; + } MonoDomain *domain = mono_domain_get(); - uint32_t domain_id = domain ? mono_domain_get_id(domain) : 0; + int32_t domain_id = domain ? mono_domain_get_id(domain) : 0; GDMonoAssembly **result = assemblies[domain_id].getptr(p_name); return result ? *result : nullptr; } @@ -556,8 +561,9 @@ bool GDMono::load_assembly(const String &p_name, MonoAssemblyName *p_aname, GDMo GDMonoAssembly *assembly = GDMonoAssembly::load(p_name, p_aname, p_refonly, p_search_dirs); - if (!assembly) + if (!assembly) { return false; + } *r_assembly = assembly; @@ -573,8 +579,9 @@ bool GDMono::load_assembly_from(const String &p_name, const String &p_path, GDMo GDMonoAssembly *assembly = GDMonoAssembly::load_from(p_name, p_path, p_refonly); - if (!assembly) + if (!assembly) { return false; + } *r_assembly = assembly; @@ -594,16 +601,19 @@ ApiAssemblyInfo::Version ApiAssemblyInfo::Version::get_from_loaded_assembly(GDMo if (nativecalls_klass) { GDMonoField *api_hash_field = nativecalls_klass->get_field("godot_api_hash"); - if (api_hash_field) + if (api_hash_field) { api_assembly_version.godot_api_hash = GDMonoMarshal::unbox<uint64_t>(api_hash_field->get_value(nullptr)); + } GDMonoField *binds_ver_field = nativecalls_klass->get_field("bindings_version"); - if (binds_ver_field) + if (binds_ver_field) { api_assembly_version.bindings_version = GDMonoMarshal::unbox<uint32_t>(binds_ver_field->get_value(nullptr)); + } GDMonoField *cs_glue_ver_field = nativecalls_klass->get_field("cs_glue_version"); - if (cs_glue_ver_field) + if (cs_glue_ver_field) { api_assembly_version.cs_glue_version = GDMonoMarshal::unbox<uint32_t>(cs_glue_ver_field->get_value(nullptr)); + } } return api_assembly_version; @@ -614,13 +624,15 @@ String ApiAssemblyInfo::to_string(ApiAssemblyInfo::Type p_type) { } bool GDMono::_load_corlib_assembly() { - if (corlib_assembly) + if (corlib_assembly) { return true; + } bool success = load_assembly("mscorlib", &corlib_assembly); - if (success) + if (success) { GDMonoCache::update_corlib_cache(); + } return success; } @@ -647,12 +659,14 @@ bool GDMono::copy_prebuilt_api_assembly(ApiAssemblyInfo::Type p_api_type, const DirAccessRef da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); String xml_file = assembly_name + ".xml"; - if (da->copy(src_dir.plus_file(xml_file), dst_dir.plus_file(xml_file)) != OK) + if (da->copy(src_dir.plus_file(xml_file), dst_dir.plus_file(xml_file)) != OK) { WARN_PRINT("Failed to copy '" + xml_file + "'."); + } String pdb_file = assembly_name + ".pdb"; - if (da->copy(src_dir.plus_file(pdb_file), dst_dir.plus_file(pdb_file)) != OK) + if (da->copy(src_dir.plus_file(pdb_file), dst_dir.plus_file(pdb_file)) != OK) { WARN_PRINT("Failed to copy '" + pdb_file + "'."); + } String assembly_file = assembly_name + ".dll"; if (da->copy(src_dir.plus_file(assembly_file), dst_dir.plus_file(assembly_file)) != OK) { @@ -667,13 +681,15 @@ static bool try_get_cached_api_hash_for(const String &p_api_assemblies_dir, bool String core_api_assembly_path = p_api_assemblies_dir.plus_file(CORE_API_ASSEMBLY_NAME ".dll"); String editor_api_assembly_path = p_api_assemblies_dir.plus_file(EDITOR_API_ASSEMBLY_NAME ".dll"); - if (!FileAccess::exists(core_api_assembly_path) || !FileAccess::exists(editor_api_assembly_path)) + if (!FileAccess::exists(core_api_assembly_path) || !FileAccess::exists(editor_api_assembly_path)) { return false; + } String cached_api_hash_path = p_api_assemblies_dir.plus_file("api_hash_cache.cfg"); - if (!FileAccess::exists(cached_api_hash_path)) + if (!FileAccess::exists(cached_api_hash_path)) { return false; + } Ref<ConfigFile> cfg; cfg.instance(); @@ -766,8 +782,9 @@ String GDMono::update_api_assemblies_from_prebuilt(const String &p_config, const // Note: Even if only one of the assemblies if missing or out of sync, we update both - if (!api_assemblies_out_of_sync && FileAccess::exists(core_assembly_path) && FileAccess::exists(editor_assembly_path)) + if (!api_assemblies_out_of_sync && FileAccess::exists(core_assembly_path) && FileAccess::exists(editor_assembly_path)) { return String(); // No update needed + } print_verbose("Updating '" + p_config + "' API assemblies"); @@ -795,8 +812,9 @@ String GDMono::update_api_assemblies_from_prebuilt(const String &p_config, const #endif bool GDMono::_load_core_api_assembly(LoadedApiAssembly &r_loaded_api_assembly, const String &p_config, bool p_refonly) { - if (r_loaded_api_assembly.assembly) + if (r_loaded_api_assembly.assembly) { return true; + } #ifdef TOOLS_ENABLED // For the editor and the editor player we want to load it from a specific path to make sure we can keep it up to date @@ -828,8 +846,9 @@ bool GDMono::_load_core_api_assembly(LoadedApiAssembly &r_loaded_api_assembly, c #ifdef TOOLS_ENABLED bool GDMono::_load_editor_api_assembly(LoadedApiAssembly &r_loaded_api_assembly, const String &p_config, bool p_refonly) { - if (r_loaded_api_assembly.assembly) + if (r_loaded_api_assembly.assembly) { return true; + } // For the editor and the editor player we want to load it from a specific path to make sure we can keep it up to date @@ -859,30 +878,35 @@ bool GDMono::_load_editor_api_assembly(LoadedApiAssembly &r_loaded_api_assembly, bool GDMono::_try_load_api_assemblies(LoadedApiAssembly &r_core_api_assembly, LoadedApiAssembly &r_editor_api_assembly, const String &p_config, bool p_refonly, CoreApiAssemblyLoadedCallback p_callback) { if (!_load_core_api_assembly(r_core_api_assembly, p_config, p_refonly)) { - if (OS::get_singleton()->is_stdout_verbose()) + if (OS::get_singleton()->is_stdout_verbose()) { print_error("Mono: Failed to load Core API assembly"); + } return false; } #ifdef TOOLS_ENABLED if (!_load_editor_api_assembly(r_editor_api_assembly, p_config, p_refonly)) { - if (OS::get_singleton()->is_stdout_verbose()) + if (OS::get_singleton()->is_stdout_verbose()) { print_error("Mono: Failed to load Editor API assembly"); + } return false; } - if (r_editor_api_assembly.out_of_sync) + if (r_editor_api_assembly.out_of_sync) { return false; + } #endif // Check if the core API assembly is out of sync only after trying to load the // editor API assembly. Otherwise, if both assemblies are out of sync, we would // only update the former as we won't know the latter also needs to be updated. - if (r_core_api_assembly.out_of_sync) + if (r_core_api_assembly.out_of_sync) { return false; + } - if (p_callback) + if (p_callback) { return p_callback(); + } return true; } @@ -890,8 +914,9 @@ bool GDMono::_try_load_api_assemblies(LoadedApiAssembly &r_core_api_assembly, Lo bool GDMono::_on_core_api_assembly_loaded() { GDMonoCache::update_godot_api_cache(); - if (!GDMonoCache::cached_data.godot_api_cache_updated) + if (!GDMonoCache::cached_data.godot_api_cache_updated) { return false; + } get_singleton()->_install_trace_listener(); @@ -956,8 +981,9 @@ void GDMono::_load_api_assemblies() { #ifdef TOOLS_ENABLED bool GDMono::_load_tools_assemblies() { - if (tools_assembly && tools_project_editor_assembly) + if (tools_assembly && tools_project_editor_assembly) { return true; + } bool success = load_assembly(TOOLS_ASM_NAME, &tools_assembly) && load_assembly(TOOLS_PROJECT_EDITOR_ASM_NAME, &tools_project_editor_assembly); @@ -967,8 +993,9 @@ bool GDMono::_load_tools_assemblies() { #endif bool GDMono::_load_project_assembly() { - if (project_assembly) + if (project_assembly) { return true; + } String appname = ProjectSettings::get_singleton()->get("application/config/name"); String appname_safe = OS::get_singleton()->get_safe_dir_name(appname); @@ -1020,8 +1047,9 @@ Error GDMono::_unload_scripts_domain() { print_verbose("Mono: Finalizing scripts domain..."); - if (mono_domain_get() != root_domain) + if (mono_domain_get() != root_domain) { mono_domain_set(root_domain, true); + } finalizing_scripts_domain = true; @@ -1111,8 +1139,9 @@ Error GDMono::finalize_and_unload_domain(MonoDomain *p_domain) { print_verbose("Mono: Unloading domain '" + domain_name + "'..."); - if (mono_domain_get() == p_domain) + if (mono_domain_get() == p_domain) { mono_domain_set(root_domain, true); + } if (!mono_domain_finalize(p_domain, 2000)) { ERR_PRINT("Mono: Domain finalization timeout."); @@ -1138,10 +1167,11 @@ Error GDMono::finalize_and_unload_domain(MonoDomain *p_domain) { GDMonoClass *GDMono::get_class(MonoClass *p_raw_class) { MonoImage *image = mono_class_get_image(p_raw_class); - if (image == corlib_assembly->get_image()) + if (image == corlib_assembly->get_image()) { return corlib_assembly->get_class(p_raw_class); + } - uint32_t domain_id = mono_domain_get_id(mono_domain_get()); + int32_t domain_id = mono_domain_get_id(mono_domain_get()); HashMap<String, GDMonoAssembly *> &domain_assemblies = assemblies[domain_id]; const String *k = nullptr; @@ -1149,9 +1179,9 @@ GDMonoClass *GDMono::get_class(MonoClass *p_raw_class) { GDMonoAssembly *assembly = domain_assemblies.get(*k); if (assembly->get_image() == image) { GDMonoClass *klass = assembly->get_class(p_raw_class); - - if (klass) + if (klass) { return klass; + } } } @@ -1160,24 +1190,26 @@ GDMonoClass *GDMono::get_class(MonoClass *p_raw_class) { GDMonoClass *GDMono::get_class(const StringName &p_namespace, const StringName &p_name) { GDMonoClass *klass = corlib_assembly->get_class(p_namespace, p_name); - if (klass) + if (klass) { return klass; + } - uint32_t domain_id = mono_domain_get_id(mono_domain_get()); + int32_t domain_id = mono_domain_get_id(mono_domain_get()); HashMap<String, GDMonoAssembly *> &domain_assemblies = assemblies[domain_id]; const String *k = nullptr; while ((k = domain_assemblies.next(k))) { GDMonoAssembly *assembly = domain_assemblies.get(*k); klass = assembly->get_class(p_namespace, p_name); - if (klass) + if (klass) { return klass; + } } return nullptr; } -void GDMono::_domain_assemblies_cleanup(uint32_t p_domain_id) { +void GDMono::_domain_assemblies_cleanup(int32_t p_domain_id) { HashMap<String, GDMonoAssembly *> &domain_assemblies = assemblies[p_domain_id]; const String *k = nullptr; @@ -1195,8 +1227,9 @@ void GDMono::unhandled_exception_hook(MonoObject *p_exc, void *) { #ifdef DEBUG_ENABLED GDMonoUtils::debug_send_unhandled_exception_error((MonoException *)p_exc); - if (EngineDebugger::is_active()) + if (EngineDebugger::is_active()) { EngineDebugger::get_singleton()->poll_events(false); + } #endif exit(mono_environment_exitcode_get()); @@ -1271,7 +1304,7 @@ GDMono::~GDMono() { // Leave the rest to 'mono_jit_cleanup' #endif - const uint32_t *k = nullptr; + const int32_t *k = nullptr; while ((k = assemblies.next(k))) { HashMap<String, GDMonoAssembly *> &domain_assemblies = assemblies.get(*k); @@ -1295,8 +1328,9 @@ GDMono::~GDMono() { gdmono::android::support::cleanup(); #endif - if (gdmono_log) + if (gdmono_log) { memdelete(gdmono_log); + } singleton = nullptr; } @@ -1313,37 +1347,44 @@ void _GodotSharp::detach_thread() { int32_t _GodotSharp::get_domain_id() { MonoDomain *domain = mono_domain_get(); - CRASH_COND(!domain); // User must check if runtime is initialized before calling this method + ERR_FAIL_NULL_V(domain, -1); return mono_domain_get_id(domain); } int32_t _GodotSharp::get_scripts_domain_id() { + ERR_FAIL_NULL_V_MSG(GDMono::get_singleton(), + -1, "The Mono runtime is not initialized"); MonoDomain *domain = GDMono::get_singleton()->get_scripts_domain(); - CRASH_COND(!domain); // User must check if scripts domain is loaded before calling this method + ERR_FAIL_NULL_V(domain, -1); return mono_domain_get_id(domain); } bool _GodotSharp::is_scripts_domain_loaded() { - return GDMono::get_singleton()->is_runtime_initialized() && GDMono::get_singleton()->get_scripts_domain() != nullptr; + return GDMono::get_singleton() != nullptr && + GDMono::get_singleton()->is_runtime_initialized() && + GDMono::get_singleton()->get_scripts_domain() != nullptr; } bool _GodotSharp::_is_domain_finalizing_for_unload(int32_t p_domain_id) { return is_domain_finalizing_for_unload(p_domain_id); } -bool _GodotSharp::is_domain_finalizing_for_unload() { - return is_domain_finalizing_for_unload(mono_domain_get()); -} - bool _GodotSharp::is_domain_finalizing_for_unload(int32_t p_domain_id) { return is_domain_finalizing_for_unload(mono_domain_get_by_id(p_domain_id)); } bool _GodotSharp::is_domain_finalizing_for_unload(MonoDomain *p_domain) { - if (!p_domain) - return true; - if (p_domain == GDMono::get_singleton()->get_scripts_domain() && GDMono::get_singleton()->is_finalizing_scripts_domain()) + GDMono *gd_mono = GDMono::get_singleton(); + + ERR_FAIL_COND_V_MSG(!gd_mono || !gd_mono->is_runtime_initialized(), + false, "The Mono runtime is not initialized"); + + ERR_FAIL_NULL_V(p_domain, true); + + if (p_domain == gd_mono->get_scripts_domain() && gd_mono->is_finalizing_scripts_domain()) { return true; + } + return mono_domain_is_unloading(p_domain); } @@ -1352,15 +1393,17 @@ bool _GodotSharp::is_runtime_shutting_down() { } bool _GodotSharp::is_runtime_initialized() { - return GDMono::get_singleton()->is_runtime_initialized(); + return GDMono::get_singleton() != nullptr && GDMono::get_singleton()->is_runtime_initialized(); } void _GodotSharp::_reload_assemblies(bool p_soft_reload) { #ifdef GD_MONO_HOT_RELOAD + CRASH_COND(CSharpLanguage::get_singleton() == nullptr); // This method may be called more than once with `call_deferred`, so we need to check // again if reloading is needed to avoid reloading multiple times unnecessarily. - if (CSharpLanguage::get_singleton()->is_assembly_reloading_needed()) + if (CSharpLanguage::get_singleton()->is_assembly_reloading_needed()) { CSharpLanguage::get_singleton()->reload_assemblies(p_soft_reload); + } #endif } diff --git a/modules/mono/mono_gd/gd_mono.h b/modules/mono/mono_gd/gd_mono.h index 833855b371..18f7418049 100644 --- a/modules/mono/mono_gd/gd_mono.h +++ b/modules/mono/mono_gd/gd_mono.h @@ -97,7 +97,7 @@ private: MonoDomain *root_domain; MonoDomain *scripts_domain; - HashMap<uint32_t, HashMap<String, GDMonoAssembly *>> assemblies; + HashMap<int32_t, HashMap<String, GDMonoAssembly *>> assemblies; GDMonoAssembly *corlib_assembly; GDMonoAssembly *project_assembly; @@ -141,7 +141,7 @@ private: Error _unload_scripts_domain(); #endif - void _domain_assemblies_cleanup(uint32_t p_domain_id); + void _domain_assemblies_cleanup(int32_t p_domain_id); uint64_t api_core_hash; #ifdef TOOLS_ENABLED @@ -165,14 +165,16 @@ protected: public: #ifdef DEBUG_METHODS_ENABLED uint64_t get_api_core_hash() { - if (api_core_hash == 0) + if (api_core_hash == 0) { api_core_hash = ClassDB::get_api_hash(ClassDB::API_CORE); + } return api_core_hash; } #ifdef TOOLS_ENABLED uint64_t get_api_editor_hash() { - if (api_editor_hash == 0) + if (api_editor_hash == 0) { api_editor_hash = ClassDB::get_api_hash(ClassDB::API_EDITOR); + } return api_editor_hash; } #endif // TOOLS_ENABLED @@ -202,7 +204,7 @@ public: UnhandledExceptionPolicy get_unhandled_exception_policy() const { return unhandled_exception_policy; } // Do not use these, unless you know what you're doing - void add_assembly(uint32_t p_domain_id, GDMonoAssembly *p_assembly); + void add_assembly(int32_t p_domain_id, GDMonoAssembly *p_assembly); GDMonoAssembly *get_loaded_assembly(const String &p_name); _FORCE_INLINE_ bool is_runtime_initialized() const { return runtime_initialized && !mono_runtime_is_shutting_down() /* stays true after shutdown finished */; } @@ -252,18 +254,18 @@ class ScopeDomain { public: ScopeDomain(MonoDomain *p_domain) { - MonoDomain *prev_domain = mono_domain_get(); + prev_domain = mono_domain_get(); if (prev_domain != p_domain) { - this->prev_domain = prev_domain; mono_domain_set(p_domain, false); } else { - this->prev_domain = nullptr; + prev_domain = nullptr; } } ~ScopeDomain() { - if (prev_domain) + if (prev_domain) { mono_domain_set(prev_domain, false); + } } }; @@ -276,8 +278,9 @@ public: } ~ScopeExitDomainUnload() { - if (domain) + if (domain) { GDMono::get_singleton()->finalize_and_unload_domain(domain); + } } }; @@ -298,9 +301,6 @@ class _GodotSharp : public Object { bool _is_domain_finalizing_for_unload(int32_t p_domain_id); - List<NodePath *> np_delete_queue; - List<RID *> rid_delete_queue; - void _reload_assemblies(bool p_soft_reload); protected: @@ -318,7 +318,6 @@ public: bool is_scripts_domain_loaded(); - bool is_domain_finalizing_for_unload(); bool is_domain_finalizing_for_unload(int32_t p_domain_id); bool is_domain_finalizing_for_unload(MonoDomain *p_domain); diff --git a/modules/mono/mono_gd/gd_mono_assembly.cpp b/modules/mono/mono_gd/gd_mono_assembly.cpp index 073c9a5214..a170fd36e7 100644 --- a/modules/mono/mono_gd/gd_mono_assembly.cpp +++ b/modules/mono/mono_gd/gd_mono_assembly.cpp @@ -108,8 +108,9 @@ void GDMonoAssembly::assembly_load_hook(MonoAssembly *assembly, [[maybe_unused]] #ifdef GD_MONO_HOT_RELOAD const char *path = mono_image_get_filename(image); - if (FileAccess::exists(path)) + if (FileAccess::exists(path)) { gdassembly->modified_time = FileAccess::get_modified_time(path); + } #endif MonoDomain *domain = mono_domain_get(); @@ -137,8 +138,9 @@ MonoAssembly *GDMonoAssembly::_search_hook(MonoAssemblyName *aname, [[maybe_unus bool has_extension = name.ends_with(".dll") || name.ends_with(".exe"); GDMonoAssembly *loaded_asm = GDMono::get_singleton()->get_loaded_assembly(has_extension ? name.get_basename() : name); - if (loaded_asm) + if (loaded_asm) { return loaded_asm->get_assembly(); + } return nullptr; } @@ -161,22 +163,25 @@ MonoAssembly *GDMonoAssembly::_load_assembly_search(const String &p_name, MonoAs path = search_dir.plus_file(p_name); if (FileAccess::exists(path)) { res = _real_load_assembly_from(path, p_refonly, p_aname); - if (res != nullptr) + if (res != nullptr) { return res; + } } } else { path = search_dir.plus_file(p_name + ".dll"); if (FileAccess::exists(path)) { res = _real_load_assembly_from(path, p_refonly, p_aname); - if (res != nullptr) + if (res != nullptr) { return res; + } } path = search_dir.plus_file(p_name + ".exe"); if (FileAccess::exists(path)) { res = _real_load_assembly_from(path, p_refonly, p_aname); - if (res != nullptr) + if (res != nullptr) { return res; + } } } } @@ -194,16 +199,19 @@ String GDMonoAssembly::find_assembly(const String &p_name) { if (has_extension) { path = search_dir.plus_file(p_name); - if (FileAccess::exists(path)) + if (FileAccess::exists(path)) { return path; + } } else { path = search_dir.plus_file(p_name + ".dll"); - if (FileAccess::exists(path)) + if (FileAccess::exists(path)) { return path; + } path = search_dir.plus_file(p_name + ".exe"); - if (FileAccess::exists(path)) + if (FileAccess::exists(path)) { return path; + } } } @@ -279,8 +287,9 @@ MonoAssembly *GDMonoAssembly::_real_load_assembly_from(const String &p_path, boo if (!FileAccess::exists(pdb_path)) { pdb_path = p_path.get_basename() + ".pdb"; // without .dll - if (!FileAccess::exists(pdb_path)) + if (!FileAccess::exists(pdb_path)) { goto no_pdb; + } } pdb_data = FileAccess::get_file_as_array(pdb_path); @@ -307,8 +316,9 @@ no_pdb: String name = String::utf8(mono_assembly_name_get_name(mono_assembly_get_name(assembly))); bool has_extension = name.ends_with(".dll") || name.ends_with(".exe"); GDMonoAssembly *loaded_asm = GDMono::get_singleton()->get_loaded_assembly(has_extension ? name.get_basename() : name); - if (!loaded_asm) + if (!loaded_asm) { assembly_load_hook(assembly, nullptr); + } } // Decrement refcount which was previously incremented by mono_image_open_from_data_with_name @@ -342,13 +352,15 @@ GDMonoClass *GDMonoAssembly::get_class(const StringName &p_namespace, const Stri GDMonoClass **match = cached_classes.getptr(key); - if (match) + if (match) { return *match; + } MonoClass *mono_class = mono_class_from_name(image, String(p_namespace).utf8(), String(p_name).utf8()); - if (!mono_class) + if (!mono_class) { return nullptr; + } GDMonoClass *wrapped_class = memnew(GDMonoClass(p_namespace, p_name, mono_class, this)); @@ -363,8 +375,9 @@ GDMonoClass *GDMonoAssembly::get_class(MonoClass *p_mono_class) { Map<MonoClass *, GDMonoClass *>::Element *match = cached_raw.find(p_mono_class); - if (match) + if (match) { return match->value(); + } StringName namespace_name = mono_class_get_namespace(p_mono_class); StringName class_name = mono_class_get_name(p_mono_class); @@ -383,8 +396,9 @@ GDMonoClass *GDMonoAssembly::get_object_derived_class(const StringName &p_class) if (gdobject_class_cache_updated) { Map<StringName, GDMonoClass *>::Element *result = gdobject_class_cache.find(p_class); - if (result) + if (result) { match = result->get(); + } } else { List<GDMonoClass *> nested_classes; @@ -393,18 +407,21 @@ GDMonoClass *GDMonoAssembly::get_object_derived_class(const StringName &p_class) for (int i = 1; i < rows; i++) { MonoClass *mono_class = mono_class_get(image, (i + 1) | MONO_TOKEN_TYPE_DEF); - if (!mono_class_is_assignable_from(CACHED_CLASS_RAW(GodotObject), mono_class)) + if (!mono_class_is_assignable_from(CACHED_CLASS_RAW(GodotObject), mono_class)) { continue; + } GDMonoClass *current = get_class(mono_class); - if (!current) + if (!current) { continue; + } nested_classes.push_back(current); - if (!match && current->get_name() == p_class) + if (!match && current->get_name() == p_class) { match = current; + } while (!nested_classes.empty()) { GDMonoClass *current_nested = nested_classes.front()->get(); @@ -415,8 +432,9 @@ GDMonoClass *GDMonoAssembly::get_object_derived_class(const StringName &p_class) while (true) { MonoClass *raw_nested = mono_class_get_nested_types(current_nested->get_mono_ptr(), &iter); - if (!raw_nested) + if (!raw_nested) { break; + } GDMonoClass *nested_class = get_class(raw_nested); @@ -437,8 +455,9 @@ GDMonoClass *GDMonoAssembly::get_object_derived_class(const StringName &p_class) } GDMonoAssembly *GDMonoAssembly::load(const String &p_name, MonoAssemblyName *p_aname, bool p_refonly, const Vector<String> &p_search_dirs) { - if (GDMono::get_singleton()->get_corlib_assembly() && (p_name == "mscorlib" || p_name == "mscorlib.dll")) + if (GDMono::get_singleton()->get_corlib_assembly() && (p_name == "mscorlib" || p_name == "mscorlib.dll")) { return GDMono::get_singleton()->get_corlib_assembly(); + } // We need to manually call the search hook in this case, as it won't be called in the next step MonoAssembly *assembly = mono_assembly_invoke_search_hook(p_aname); @@ -456,8 +475,9 @@ GDMonoAssembly *GDMonoAssembly::load(const String &p_name, MonoAssemblyName *p_a } GDMonoAssembly *GDMonoAssembly::load_from(const String &p_name, const String &p_path, bool p_refonly) { - if (p_name == "mscorlib" || p_name == "mscorlib.dll") + if (p_name == "mscorlib" || p_name == "mscorlib.dll") { return GDMono::get_singleton()->get_corlib_assembly(); + } // We need to manually call the search hook in this case, as it won't be called in the next step MonoAssemblyName *aname = mono_assembly_name_new(p_name.utf8()); @@ -477,6 +497,7 @@ GDMonoAssembly *GDMonoAssembly::load_from(const String &p_name, const String &p_ } GDMonoAssembly::~GDMonoAssembly() { - if (image) + if (image) { unload(); + } } diff --git a/modules/mono/mono_gd/gd_mono_cache.cpp b/modules/mono/mono_gd/gd_mono_cache.cpp index c002ad2139..29aef6e609 100644 --- a/modules/mono/mono_gd/gd_mono_cache.cpp +++ b/modules/mono/mono_gd/gd_mono_cache.cpp @@ -217,7 +217,7 @@ void update_corlib_cache() { CACHE_METHOD_AND_CHECK(System_Diagnostics_StackTrace, ctor_Exception_bool, CACHED_CLASS(System_Diagnostics_StackTrace)->get_method_with_desc("System.Diagnostics.StackTrace:.ctor(System.Exception,bool)", true)); #endif - CACHE_METHOD_THUNK_AND_CHECK(Delegate, Equals, GDMono::get_singleton()->get_corlib_assembly()->get_class("System", "Delegate")->get_method_with_desc("System.Delegate:Equals(object)", 1)); + CACHE_METHOD_THUNK_AND_CHECK(Delegate, Equals, GDMono::get_singleton()->get_corlib_assembly()->get_class("System", "Delegate")->get_method_with_desc("System.Delegate:Equals(object)", true)); CACHE_CLASS_AND_CHECK(KeyNotFoundException, GDMono::get_singleton()->get_corlib_assembly()->get_class("System.Collections.Generic", "KeyNotFoundException")); diff --git a/modules/mono/mono_gd/gd_mono_class.cpp b/modules/mono/mono_gd/gd_mono_class.cpp index 691da55b10..6575cbc1c8 100644 --- a/modules/mono/mono_gd/gd_mono_class.cpp +++ b/modules/mono/mono_gd/gd_mono_class.cpp @@ -81,15 +81,17 @@ bool GDMonoClass::is_assignable_from(GDMonoClass *p_from) const { StringName GDMonoClass::get_namespace() const { GDMonoClass *nesting_class = get_nesting_class(); - if (!nesting_class) + if (!nesting_class) { return namespace_name; + } return nesting_class->get_namespace(); } String GDMonoClass::get_name_for_lookup() const { GDMonoClass *nesting_class = get_nesting_class(); - if (!nesting_class) + if (!nesting_class) { return class_name; + } return nesting_class->get_name_for_lookup() + "/" + class_name; } @@ -131,11 +133,13 @@ bool GDMonoClass::has_attribute(GDMonoClass *p_attr_class) { ERR_FAIL_NULL_V(p_attr_class, false); #endif - if (!attrs_fetched) + if (!attrs_fetched) { fetch_attributes(); + } - if (!attributes) + if (!attributes) { return false; + } return mono_custom_attrs_has_attr(attributes, p_attr_class->get_mono_ptr()); } @@ -145,11 +149,13 @@ MonoObject *GDMonoClass::get_attribute(GDMonoClass *p_attr_class) { ERR_FAIL_NULL_V(p_attr_class, nullptr); #endif - if (!attrs_fetched) + if (!attrs_fetched) { fetch_attributes(); + } - if (!attributes) + if (!attributes) { return nullptr; + } return mono_custom_attrs_get_attr(attributes, p_attr_class->get_mono_ptr()); } @@ -164,8 +170,9 @@ void GDMonoClass::fetch_attributes() { void GDMonoClass::fetch_methods_with_godot_api_checks(GDMonoClass *p_native_base) { CRASH_COND(!CACHED_CLASS(GodotObject)->is_assignable_from(this)); - if (methods_fetched) + if (methods_fetched) { return; + } void *iter = nullptr; MonoMethod *raw_method = nullptr; @@ -202,8 +209,9 @@ void GDMonoClass::fetch_methods_with_godot_api_checks(GDMonoClass *p_native_base break; } - if (native_top == CACHED_CLASS(GodotObject)) + if (native_top == CACHED_CLASS(GodotObject)) { break; + } native_top = native_top->get_parent_class(); } @@ -212,8 +220,9 @@ void GDMonoClass::fetch_methods_with_godot_api_checks(GDMonoClass *p_native_base uint32_t flags = mono_method_get_flags(method->mono_method, nullptr); - if (!(flags & MONO_METHOD_ATTR_VIRTUAL)) + if (!(flags & MONO_METHOD_ATTR_VIRTUAL)) { continue; + } // Virtual method of Godot Object derived type, let's try to find GodotMethod attribute @@ -235,15 +244,17 @@ void GDMonoClass::fetch_methods_with_godot_api_checks(GDMonoClass *p_native_base #endif MethodKey key = MethodKey(godot_method_name, method->get_parameters_count()); GDMonoMethod **existing_method = methods.getptr(key); - if (existing_method) + if (existing_method) { memdelete(*existing_method); // Must delete old one + } methods.set(key, method); break; } - if (top == CACHED_CLASS(GodotObject)) + if (top == CACHED_CLASS(GodotObject)) { break; + } top = top->get_parent_class(); } @@ -258,8 +269,9 @@ GDMonoMethod *GDMonoClass::get_fetched_method_unknown_params(const StringName &p const MethodKey *k = nullptr; while ((k = methods.next(k))) { - if (k->name == p_name) + if (k->name == p_name) { return methods.get(*k); + } } return nullptr; @@ -283,11 +295,13 @@ GDMonoMethod *GDMonoClass::get_method(const StringName &p_name, int p_params_cou GDMonoMethod **match = methods.getptr(key); - if (match) + if (match) { return *match; + } - if (methods_fetched) + if (methods_fetched) { return nullptr; + } MonoMethod *raw_method = mono_class_get_method_from_name(mono_class, String(p_name).utf8().get_data(), p_params_count); @@ -323,8 +337,9 @@ GDMonoMethod *GDMonoClass::get_method(MonoMethod *p_raw_method, const StringName GDMonoMethod **match = methods.getptr(key); - if (match) + if (match) { return *match; + } GDMonoMethod *method = memnew(GDMonoMethod(p_name, p_raw_method)); methods.set(key, method); @@ -337,8 +352,9 @@ GDMonoMethod *GDMonoClass::get_method_with_desc(const String &p_description, boo MonoMethod *method = mono_method_desc_search_in_class(desc, mono_class); mono_method_desc_free(desc); - if (!method) + if (!method) { return nullptr; + } ERR_FAIL_COND_V(mono_method_get_class(method) != mono_class, nullptr); @@ -348,11 +364,13 @@ GDMonoMethod *GDMonoClass::get_method_with_desc(const String &p_description, boo GDMonoField *GDMonoClass::get_field(const StringName &p_name) { Map<StringName, GDMonoField *>::Element *result = fields.find(p_name); - if (result) + if (result) { return result->value(); + } - if (fields_fetched) + if (fields_fetched) { return nullptr; + } MonoClassField *raw_field = mono_class_get_field_from_name(mono_class, String(p_name).utf8().get_data()); @@ -367,8 +385,9 @@ GDMonoField *GDMonoClass::get_field(const StringName &p_name) { } const Vector<GDMonoField *> &GDMonoClass::get_all_fields() { - if (fields_fetched) + if (fields_fetched) { return fields_list; + } void *iter = nullptr; MonoClassField *raw_field = nullptr; @@ -394,11 +413,13 @@ const Vector<GDMonoField *> &GDMonoClass::get_all_fields() { GDMonoProperty *GDMonoClass::get_property(const StringName &p_name) { Map<StringName, GDMonoProperty *>::Element *result = properties.find(p_name); - if (result) + if (result) { return result->value(); + } - if (properties_fetched) + if (properties_fetched) { return nullptr; + } MonoProperty *raw_property = mono_class_get_property_from_name(mono_class, String(p_name).utf8().get_data()); @@ -413,8 +434,9 @@ GDMonoProperty *GDMonoClass::get_property(const StringName &p_name) { } const Vector<GDMonoProperty *> &GDMonoClass::get_all_properties() { - if (properties_fetched) + if (properties_fetched) { return properties_list; + } void *iter = nullptr; MonoProperty *raw_property = nullptr; @@ -438,8 +460,9 @@ const Vector<GDMonoProperty *> &GDMonoClass::get_all_properties() { } const Vector<GDMonoClass *> &GDMonoClass::get_all_delegates() { - if (delegates_fetched) + if (delegates_fetched) { return delegates_list; + } void *iter = nullptr; MonoClass *raw_class = nullptr; diff --git a/modules/mono/mono_gd/gd_mono_field.cpp b/modules/mono/mono_gd/gd_mono_field.cpp index 948170f51c..563c45e71f 100644 --- a/modules/mono/mono_gd/gd_mono_field.cpp +++ b/modules/mono/mono_gd/gd_mono_field.cpp @@ -597,11 +597,13 @@ String GDMonoField::get_string_value(MonoObject *p_object) { bool GDMonoField::has_attribute(GDMonoClass *p_attr_class) { ERR_FAIL_NULL_V(p_attr_class, false); - if (!attrs_fetched) + if (!attrs_fetched) { fetch_attributes(); + } - if (!attributes) + if (!attributes) { return false; + } return mono_custom_attrs_has_attr(attributes, p_attr_class->get_mono_ptr()); } @@ -609,11 +611,13 @@ bool GDMonoField::has_attribute(GDMonoClass *p_attr_class) { MonoObject *GDMonoField::get_attribute(GDMonoClass *p_attr_class) { ERR_FAIL_NULL_V(p_attr_class, nullptr); - if (!attrs_fetched) + if (!attrs_fetched) { fetch_attributes(); + } - if (!attributes) + if (!attributes) { return nullptr; + } return mono_custom_attrs_get_attr(attributes, p_attr_class->get_mono_ptr()); } diff --git a/modules/mono/mono_gd/gd_mono_internals.cpp b/modules/mono/mono_gd/gd_mono_internals.cpp index abb2761909..fe1c2d28dd 100644 --- a/modules/mono/mono_gd/gd_mono_internals.cpp +++ b/modules/mono/mono_gd/gd_mono_internals.cpp @@ -122,9 +122,10 @@ void unhandled_exception(MonoException *p_exc) { GD_UNREACHABLE(); } else { #ifdef DEBUG_ENABLED - GDMonoUtils::debug_send_unhandled_exception_error((MonoException *)p_exc); - if (EngineDebugger::is_active()) + GDMonoUtils::debug_send_unhandled_exception_error(p_exc); + if (EngineDebugger::is_active()) { EngineDebugger::get_singleton()->poll_events(false); + } #endif } } diff --git a/modules/mono/mono_gd/gd_mono_log.cpp b/modules/mono/mono_gd/gd_mono_log.cpp index 04728be725..c5a988b8c3 100644 --- a/modules/mono/mono_gd/gd_mono_log.cpp +++ b/modules/mono/mono_gd/gd_mono_log.cpp @@ -55,8 +55,9 @@ static int get_log_level_id(const char *p_log_level) { int i = 0; while (valid_log_levels[i]) { - if (!strcmp(valid_log_levels[i], p_log_level)) + if (!strcmp(valid_log_levels[i], p_log_level)) { return i; + } i++; } @@ -115,10 +116,12 @@ void GDMonoLog::_delete_old_log_files(const String &p_logs_dir) { String current; while ((current = da->get_next()).length()) { - if (da->current_is_dir()) + if (da->current_is_dir()) { continue; - if (!current.ends_with(".txt")) + } + if (!current.ends_with(".txt")) { continue; + } uint64_t modified_time = FileAccess::get_modified_time(da->get_current_dir().plus_file(current)); diff --git a/modules/mono/mono_gd/gd_mono_marshal.cpp b/modules/mono/mono_gd/gd_mono_marshal.cpp index 92734a0792..6d7d5f76cd 100644 --- a/modules/mono/mono_gd/gd_mono_marshal.cpp +++ b/modules/mono/mono_gd/gd_mono_marshal.cpp @@ -72,92 +72,119 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type, bool *r_nil_is_ case MONO_TYPE_VALUETYPE: { GDMonoClass *vtclass = p_type.type_class; - if (vtclass == CACHED_CLASS(Vector2)) + if (vtclass == CACHED_CLASS(Vector2)) { return Variant::VECTOR2; + } - if (vtclass == CACHED_CLASS(Vector2i)) + if (vtclass == CACHED_CLASS(Vector2i)) { return Variant::VECTOR2I; + } - if (vtclass == CACHED_CLASS(Rect2)) + if (vtclass == CACHED_CLASS(Rect2)) { return Variant::RECT2; + } - if (vtclass == CACHED_CLASS(Rect2i)) + if (vtclass == CACHED_CLASS(Rect2i)) { return Variant::RECT2I; + } - if (vtclass == CACHED_CLASS(Transform2D)) + if (vtclass == CACHED_CLASS(Transform2D)) { return Variant::TRANSFORM2D; + } - if (vtclass == CACHED_CLASS(Vector3)) + if (vtclass == CACHED_CLASS(Vector3)) { return Variant::VECTOR3; + } - if (vtclass == CACHED_CLASS(Vector3i)) + if (vtclass == CACHED_CLASS(Vector3i)) { return Variant::VECTOR3I; + } - if (vtclass == CACHED_CLASS(Basis)) + if (vtclass == CACHED_CLASS(Basis)) { return Variant::BASIS; + } - if (vtclass == CACHED_CLASS(Quat)) + if (vtclass == CACHED_CLASS(Quat)) { return Variant::QUAT; + } - if (vtclass == CACHED_CLASS(Transform)) + if (vtclass == CACHED_CLASS(Transform)) { return Variant::TRANSFORM; + } - if (vtclass == CACHED_CLASS(AABB)) + if (vtclass == CACHED_CLASS(AABB)) { return Variant::AABB; + } - if (vtclass == CACHED_CLASS(Color)) + if (vtclass == CACHED_CLASS(Color)) { return Variant::COLOR; + } - if (vtclass == CACHED_CLASS(Plane)) + if (vtclass == CACHED_CLASS(Plane)) { return Variant::PLANE; + } - if (vtclass == CACHED_CLASS(Callable)) + if (vtclass == CACHED_CLASS(Callable)) { return Variant::CALLABLE; + } - if (vtclass == CACHED_CLASS(SignalInfo)) + if (vtclass == CACHED_CLASS(SignalInfo)) { return Variant::SIGNAL; + } - if (mono_class_is_enum(vtclass->get_mono_ptr())) + if (mono_class_is_enum(vtclass->get_mono_ptr())) { return Variant::INT; + } } break; case MONO_TYPE_ARRAY: case MONO_TYPE_SZARRAY: { MonoArrayType *array_type = mono_type_get_array_type(p_type.type_class->get_mono_type()); - if (array_type->eklass == CACHED_CLASS_RAW(MonoObject)) + if (array_type->eklass == CACHED_CLASS_RAW(MonoObject)) { return Variant::ARRAY; + } - if (array_type->eklass == CACHED_CLASS_RAW(uint8_t)) + if (array_type->eklass == CACHED_CLASS_RAW(uint8_t)) { return Variant::PACKED_BYTE_ARRAY; + } - if (array_type->eklass == CACHED_CLASS_RAW(int32_t)) + if (array_type->eklass == CACHED_CLASS_RAW(int32_t)) { return Variant::PACKED_INT32_ARRAY; + } - if (array_type->eklass == CACHED_CLASS_RAW(int64_t)) + if (array_type->eklass == CACHED_CLASS_RAW(int64_t)) { return Variant::PACKED_INT64_ARRAY; + } - if (array_type->eklass == CACHED_CLASS_RAW(float)) + if (array_type->eklass == CACHED_CLASS_RAW(float)) { return Variant::PACKED_FLOAT32_ARRAY; + } - if (array_type->eklass == CACHED_CLASS_RAW(double)) + if (array_type->eklass == CACHED_CLASS_RAW(double)) { return Variant::PACKED_FLOAT64_ARRAY; + } - if (array_type->eklass == CACHED_CLASS_RAW(String)) + if (array_type->eklass == CACHED_CLASS_RAW(String)) { return Variant::PACKED_STRING_ARRAY; + } - if (array_type->eklass == CACHED_CLASS_RAW(Vector2)) + if (array_type->eklass == CACHED_CLASS_RAW(Vector2)) { return Variant::PACKED_VECTOR2_ARRAY; + } - if (array_type->eklass == CACHED_CLASS_RAW(Vector3)) + if (array_type->eklass == CACHED_CLASS_RAW(Vector3)) { return Variant::PACKED_VECTOR3_ARRAY; + } - if (array_type->eklass == CACHED_CLASS_RAW(Color)) + if (array_type->eklass == CACHED_CLASS_RAW(Color)) { return Variant::PACKED_COLOR_ARRAY; + } GDMonoClass *array_type_class = GDMono::get_singleton()->get_class(array_type->eklass); - if (CACHED_CLASS(GodotObject)->is_assignable_from(array_type_class)) + if (CACHED_CLASS(GodotObject)->is_assignable_from(array_type_class)) { return Variant::ARRAY; + } } break; case MONO_TYPE_CLASS: { @@ -201,8 +228,9 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type, bool *r_nil_is_ } break; case MONO_TYPE_OBJECT: { - if (r_nil_is_variant) + if (r_nil_is_variant) { *r_nil_is_variant = true; + } return Variant::NIL; } break; @@ -244,8 +272,9 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type, bool *r_nil_is_ } break; } - if (r_nil_is_variant) + if (r_nil_is_variant) { *r_nil_is_variant = false; + } // Unknown return Variant::NIL; @@ -282,31 +311,6 @@ bool try_get_array_element_type(const ManagedType &p_array_type, ManagedType &r_ return false; } -bool try_get_dictionary_key_value_types(const ManagedType &p_dictionary_type, ManagedType &r_key_type, ManagedType &r_value_type) { - switch (p_dictionary_type.type_encoding) { - case MONO_TYPE_GENERICINST: { - MonoReflectionType *dict_reftype = mono_type_get_object(mono_domain_get(), p_dictionary_type.type_class->get_mono_type()); - - if (GDMonoUtils::Marshal::type_is_generic_dictionary(dict_reftype) || - GDMonoUtils::Marshal::type_is_system_generic_dictionary(dict_reftype) || - GDMonoUtils::Marshal::type_is_generic_idictionary(dict_reftype)) { - MonoReflectionType *key_reftype; - MonoReflectionType *value_reftype; - - GDMonoUtils::Marshal::dictionary_get_key_value_types(dict_reftype, &key_reftype, &value_reftype); - - r_key_type = ManagedType::from_reftype(key_reftype); - r_value_type = ManagedType::from_reftype(value_reftype); - return true; - } - } break; - default: { - } break; - } - - return false; -} - String mono_to_utf8_string(MonoString *p_mono_string) { MonoError error; char *utf8 = mono_string_to_utf8_checked(p_mono_string, &error); @@ -328,8 +332,9 @@ String mono_to_utf16_string(MonoString *p_mono_string) { int len = mono_string_length(p_mono_string); String ret; - if (len == 0) + if (len == 0) { return ret; + } ret.resize(len + 1); ret.set(len, 0); @@ -409,8 +414,9 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty } case MONO_TYPE_STRING: { - if (p_var->get_type() == Variant::NIL) + if (p_var->get_type() == Variant::NIL) { return nullptr; // Otherwise, Variant -> String would return the string "Null" + } return (MonoObject *)mono_string_from_godot(p_var->operator String()); } break; @@ -547,39 +553,50 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty case MONO_TYPE_SZARRAY: { MonoArrayType *array_type = mono_type_get_array_type(p_type.type_class->get_mono_type()); - if (array_type->eklass == CACHED_CLASS_RAW(MonoObject)) + if (array_type->eklass == CACHED_CLASS_RAW(MonoObject)) { return (MonoObject *)Array_to_mono_array(p_var->operator Array()); + } - if (array_type->eklass == CACHED_CLASS_RAW(uint8_t)) + if (array_type->eklass == CACHED_CLASS_RAW(uint8_t)) { return (MonoObject *)PackedByteArray_to_mono_array(p_var->operator PackedByteArray()); + } - if (array_type->eklass == CACHED_CLASS_RAW(int32_t)) + if (array_type->eklass == CACHED_CLASS_RAW(int32_t)) { return (MonoObject *)PackedInt32Array_to_mono_array(p_var->operator PackedInt32Array()); + } - if (array_type->eklass == CACHED_CLASS_RAW(int64_t)) + if (array_type->eklass == CACHED_CLASS_RAW(int64_t)) { return (MonoObject *)PackedInt64Array_to_mono_array(p_var->operator PackedInt64Array()); + } - if (array_type->eklass == CACHED_CLASS_RAW(float)) + if (array_type->eklass == CACHED_CLASS_RAW(float)) { return (MonoObject *)PackedFloat32Array_to_mono_array(p_var->operator PackedFloat32Array()); + } - if (array_type->eklass == CACHED_CLASS_RAW(double)) + if (array_type->eklass == CACHED_CLASS_RAW(double)) { return (MonoObject *)PackedFloat64Array_to_mono_array(p_var->operator PackedFloat64Array()); + } - if (array_type->eklass == CACHED_CLASS_RAW(String)) + if (array_type->eklass == CACHED_CLASS_RAW(String)) { return (MonoObject *)PackedStringArray_to_mono_array(p_var->operator PackedStringArray()); + } - if (array_type->eklass == CACHED_CLASS_RAW(Vector2)) + if (array_type->eklass == CACHED_CLASS_RAW(Vector2)) { return (MonoObject *)PackedVector2Array_to_mono_array(p_var->operator PackedVector2Array()); + } - if (array_type->eklass == CACHED_CLASS_RAW(Vector3)) + if (array_type->eklass == CACHED_CLASS_RAW(Vector3)) { return (MonoObject *)PackedVector3Array_to_mono_array(p_var->operator PackedVector3Array()); + } - if (array_type->eklass == CACHED_CLASS_RAW(Color)) + if (array_type->eklass == CACHED_CLASS_RAW(Color)) { return (MonoObject *)PackedColorArray_to_mono_array(p_var->operator PackedColorArray()); + } GDMonoClass *array_type_class = GDMono::get_singleton()->get_class(array_type->eklass); - if (CACHED_CLASS(GodotObject)->is_assignable_from(array_type_class)) + if (CACHED_CLASS(GodotObject)->is_assignable_from(array_type_class)) { return (MonoObject *)Array_to_mono_array(p_var->operator Array(), array_type_class); + } ERR_FAIL_V_MSG(nullptr, "Attempted to convert Variant to a managed array of unmarshallable element type."); } break; @@ -820,100 +837,128 @@ Variant mono_object_to_variant_impl(MonoObject *p_obj, const ManagedType &p_type return unbox<double>(p_obj); case MONO_TYPE_STRING: { - if (p_obj == nullptr) + if (p_obj == nullptr) { return Variant(); // NIL + } return mono_string_to_godot_not_null((MonoString *)p_obj); } break; case MONO_TYPE_VALUETYPE: { GDMonoClass *vtclass = p_type.type_class; - if (vtclass == CACHED_CLASS(Vector2)) + if (vtclass == CACHED_CLASS(Vector2)) { return MARSHALLED_IN(Vector2, unbox_addr<GDMonoMarshal::M_Vector2>(p_obj)); + } - if (vtclass == CACHED_CLASS(Vector2i)) + if (vtclass == CACHED_CLASS(Vector2i)) { return MARSHALLED_IN(Vector2i, unbox_addr<GDMonoMarshal::M_Vector2i>(p_obj)); + } - if (vtclass == CACHED_CLASS(Rect2)) + if (vtclass == CACHED_CLASS(Rect2)) { return MARSHALLED_IN(Rect2, unbox_addr<GDMonoMarshal::M_Rect2>(p_obj)); + } - if (vtclass == CACHED_CLASS(Rect2i)) + if (vtclass == CACHED_CLASS(Rect2i)) { return MARSHALLED_IN(Rect2i, unbox_addr<GDMonoMarshal::M_Rect2i>(p_obj)); + } - if (vtclass == CACHED_CLASS(Transform2D)) + if (vtclass == CACHED_CLASS(Transform2D)) { return MARSHALLED_IN(Transform2D, unbox_addr<GDMonoMarshal::M_Transform2D>(p_obj)); + } - if (vtclass == CACHED_CLASS(Vector3)) + if (vtclass == CACHED_CLASS(Vector3)) { return MARSHALLED_IN(Vector3, unbox_addr<GDMonoMarshal::M_Vector3>(p_obj)); + } - if (vtclass == CACHED_CLASS(Vector3i)) + if (vtclass == CACHED_CLASS(Vector3i)) { return MARSHALLED_IN(Vector3i, unbox_addr<GDMonoMarshal::M_Vector3i>(p_obj)); + } - if (vtclass == CACHED_CLASS(Basis)) + if (vtclass == CACHED_CLASS(Basis)) { return MARSHALLED_IN(Basis, unbox_addr<GDMonoMarshal::M_Basis>(p_obj)); + } - if (vtclass == CACHED_CLASS(Quat)) + if (vtclass == CACHED_CLASS(Quat)) { return MARSHALLED_IN(Quat, unbox_addr<GDMonoMarshal::M_Quat>(p_obj)); + } - if (vtclass == CACHED_CLASS(Transform)) + if (vtclass == CACHED_CLASS(Transform)) { return MARSHALLED_IN(Transform, unbox_addr<GDMonoMarshal::M_Transform>(p_obj)); + } - if (vtclass == CACHED_CLASS(AABB)) + if (vtclass == CACHED_CLASS(AABB)) { return MARSHALLED_IN(AABB, unbox_addr<GDMonoMarshal::M_AABB>(p_obj)); + } - if (vtclass == CACHED_CLASS(Color)) + if (vtclass == CACHED_CLASS(Color)) { return MARSHALLED_IN(Color, unbox_addr<GDMonoMarshal::M_Color>(p_obj)); + } - if (vtclass == CACHED_CLASS(Plane)) + if (vtclass == CACHED_CLASS(Plane)) { return MARSHALLED_IN(Plane, unbox_addr<GDMonoMarshal::M_Plane>(p_obj)); + } - if (vtclass == CACHED_CLASS(Callable)) + if (vtclass == CACHED_CLASS(Callable)) { return managed_to_callable(unbox<GDMonoMarshal::M_Callable>(p_obj)); + } - if (vtclass == CACHED_CLASS(SignalInfo)) + if (vtclass == CACHED_CLASS(SignalInfo)) { return managed_to_signal_info(unbox<GDMonoMarshal::M_SignalInfo>(p_obj)); + } - if (mono_class_is_enum(vtclass->get_mono_ptr())) + if (mono_class_is_enum(vtclass->get_mono_ptr())) { return unbox<int32_t>(p_obj); + } } break; case MONO_TYPE_ARRAY: case MONO_TYPE_SZARRAY: { MonoArrayType *array_type = mono_type_get_array_type(p_type.type_class->get_mono_type()); - if (array_type->eklass == CACHED_CLASS_RAW(MonoObject)) + if (array_type->eklass == CACHED_CLASS_RAW(MonoObject)) { return mono_array_to_Array((MonoArray *)p_obj); + } - if (array_type->eklass == CACHED_CLASS_RAW(uint8_t)) + if (array_type->eklass == CACHED_CLASS_RAW(uint8_t)) { return mono_array_to_PackedByteArray((MonoArray *)p_obj); + } - if (array_type->eklass == CACHED_CLASS_RAW(int32_t)) + if (array_type->eklass == CACHED_CLASS_RAW(int32_t)) { return mono_array_to_PackedInt32Array((MonoArray *)p_obj); + } - if (array_type->eklass == CACHED_CLASS_RAW(int64_t)) + if (array_type->eklass == CACHED_CLASS_RAW(int64_t)) { return mono_array_to_PackedInt64Array((MonoArray *)p_obj); + } - if (array_type->eklass == CACHED_CLASS_RAW(float)) + if (array_type->eklass == CACHED_CLASS_RAW(float)) { return mono_array_to_PackedFloat32Array((MonoArray *)p_obj); + } - if (array_type->eklass == CACHED_CLASS_RAW(double)) + if (array_type->eklass == CACHED_CLASS_RAW(double)) { return mono_array_to_PackedFloat64Array((MonoArray *)p_obj); + } - if (array_type->eklass == CACHED_CLASS_RAW(String)) + if (array_type->eklass == CACHED_CLASS_RAW(String)) { return mono_array_to_PackedStringArray((MonoArray *)p_obj); + } - if (array_type->eklass == CACHED_CLASS_RAW(Vector2)) + if (array_type->eklass == CACHED_CLASS_RAW(Vector2)) { return mono_array_to_PackedVector2Array((MonoArray *)p_obj); + } - if (array_type->eklass == CACHED_CLASS_RAW(Vector3)) + if (array_type->eklass == CACHED_CLASS_RAW(Vector3)) { return mono_array_to_PackedVector3Array((MonoArray *)p_obj); + } - if (array_type->eklass == CACHED_CLASS_RAW(Color)) + if (array_type->eklass == CACHED_CLASS_RAW(Color)) { return mono_array_to_PackedColorArray((MonoArray *)p_obj); + } GDMonoClass *array_type_class = GDMono::get_singleton()->get_class(array_type->eklass); - if (CACHED_CLASS(GodotObject)->is_assignable_from(array_type_class)) + if (CACHED_CLASS(GodotObject)->is_assignable_from(array_type_class)) { return mono_array_to_Array((MonoArray *)p_obj); + } if (p_fail_with_err) { ERR_FAIL_V_MSG(Variant(), "Attempted to convert a managed array of unmarshallable element type to Variant."); @@ -1012,8 +1057,9 @@ Variant mono_object_to_variant_impl(MonoObject *p_obj, const ManagedType &p_type } Variant mono_object_to_variant(MonoObject *p_obj) { - if (!p_obj) + if (!p_obj) { return Variant(); + } ManagedType type = ManagedType::from_class(mono_object_get_class(p_obj)); @@ -1021,15 +1067,17 @@ Variant mono_object_to_variant(MonoObject *p_obj) { } Variant mono_object_to_variant(MonoObject *p_obj, const ManagedType &p_type) { - if (!p_obj) + if (!p_obj) { return Variant(); + } return mono_object_to_variant_impl(p_obj, p_type); } Variant mono_object_to_variant_no_err(MonoObject *p_obj, const ManagedType &p_type) { - if (!p_obj) + if (!p_obj) { return Variant(); + } return mono_object_to_variant_impl(p_obj, p_type, /* fail_with_err: */ false); } @@ -1048,8 +1096,9 @@ String mono_object_to_variant_string(MonoObject *p_obj, MonoException **r_exc) { MonoString *mono_str = GDMonoUtils::object_to_string(p_obj, &exc); if (exc) { - if (r_exc) + if (r_exc) { *r_exc = exc; + } return String(); } @@ -1159,8 +1208,9 @@ MonoArray *Array_to_mono_array(const Array &p_array, GDMonoClass *p_array_type_c Array mono_array_to_Array(MonoArray *p_array) { Array ret; - if (!p_array) + if (!p_array) { return ret; + } int length = mono_array_length(p_array); ret.resize(length); @@ -1178,22 +1228,23 @@ MonoArray *PackedInt32Array_to_mono_array(const PackedInt32Array &p_array) { MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(int32_t), length); - int32_t *dst = (int32_t *)mono_array_addr(ret, int32_t, 0); - memcpy(dst, src, length); + int32_t *dst = mono_array_addr(ret, int32_t, 0); + memcpy(dst, src, length * sizeof(int32_t)); return ret; } PackedInt32Array mono_array_to_PackedInt32Array(MonoArray *p_array) { PackedInt32Array ret; - if (!p_array) + if (!p_array) { return ret; + } int length = mono_array_length(p_array); ret.resize(length); int32_t *dst = ret.ptrw(); - const int32_t *src = (const int32_t *)mono_array_addr(p_array, int32_t, 0); - memcpy(dst, src, length); + const int32_t *src = mono_array_addr(p_array, int32_t, 0); + memcpy(dst, src, length * sizeof(int32_t)); return ret; } @@ -1204,22 +1255,23 @@ MonoArray *PackedInt64Array_to_mono_array(const PackedInt64Array &p_array) { MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(int64_t), length); - int64_t *dst = (int64_t *)mono_array_addr(ret, int64_t, 0); - memcpy(dst, src, length); + int64_t *dst = mono_array_addr(ret, int64_t, 0); + memcpy(dst, src, length * sizeof(int64_t)); return ret; } PackedInt64Array mono_array_to_PackedInt64Array(MonoArray *p_array) { PackedInt64Array ret; - if (!p_array) + if (!p_array) { return ret; + } int length = mono_array_length(p_array); ret.resize(length); int64_t *dst = ret.ptrw(); - const int64_t *src = (const int64_t *)mono_array_addr(p_array, int64_t, 0); - memcpy(dst, src, length); + const int64_t *src = mono_array_addr(p_array, int64_t, 0); + memcpy(dst, src, length * sizeof(int64_t)); return ret; } @@ -1230,22 +1282,23 @@ MonoArray *PackedByteArray_to_mono_array(const PackedByteArray &p_array) { MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(uint8_t), length); - uint8_t *dst = (uint8_t *)mono_array_addr(ret, uint8_t, 0); - memcpy(dst, src, length); + uint8_t *dst = mono_array_addr(ret, uint8_t, 0); + memcpy(dst, src, length * sizeof(uint8_t)); return ret; } PackedByteArray mono_array_to_PackedByteArray(MonoArray *p_array) { PackedByteArray ret; - if (!p_array) + if (!p_array) { return ret; + } int length = mono_array_length(p_array); ret.resize(length); uint8_t *dst = ret.ptrw(); - const uint8_t *src = (const uint8_t *)mono_array_addr(p_array, uint8_t, 0); - memcpy(dst, src, length); + const uint8_t *src = mono_array_addr(p_array, uint8_t, 0); + memcpy(dst, src, length * sizeof(uint8_t)); return ret; } @@ -1256,22 +1309,23 @@ MonoArray *PackedFloat32Array_to_mono_array(const PackedFloat32Array &p_array) { MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(float), length); - float *dst = (float *)mono_array_addr(ret, float, 0); - memcpy(dst, src, length); + float *dst = mono_array_addr(ret, float, 0); + memcpy(dst, src, length * sizeof(float)); return ret; } PackedFloat32Array mono_array_to_PackedFloat32Array(MonoArray *p_array) { PackedFloat32Array ret; - if (!p_array) + if (!p_array) { return ret; + } int length = mono_array_length(p_array); ret.resize(length); float *dst = ret.ptrw(); - const float *src = (const float *)mono_array_addr(p_array, float, 0); - memcpy(dst, src, length); + const float *src = mono_array_addr(p_array, float, 0); + memcpy(dst, src, length * sizeof(float)); return ret; } @@ -1282,22 +1336,23 @@ MonoArray *PackedFloat64Array_to_mono_array(const PackedFloat64Array &p_array) { MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(double), length); - double *dst = (double *)mono_array_addr(ret, double, 0); - memcpy(dst, src, length); + double *dst = mono_array_addr(ret, double, 0); + memcpy(dst, src, length * sizeof(double)); return ret; } PackedFloat64Array mono_array_to_PackedFloat64Array(MonoArray *p_array) { PackedFloat64Array ret; - if (!p_array) + if (!p_array) { return ret; + } int length = mono_array_length(p_array); ret.resize(length); double *dst = ret.ptrw(); - const double *src = (const double *)mono_array_addr(p_array, double, 0); - memcpy(dst, src, length); + const double *src = mono_array_addr(p_array, double, 0); + memcpy(dst, src, length * sizeof(double)); return ret; } @@ -1318,8 +1373,9 @@ MonoArray *PackedStringArray_to_mono_array(const PackedStringArray &p_array) { PackedStringArray mono_array_to_PackedStringArray(MonoArray *p_array) { PackedStringArray ret; - if (!p_array) + if (!p_array) { return ret; + } int length = mono_array_length(p_array); ret.resize(length); String *w = ret.ptrw(); @@ -1339,8 +1395,8 @@ MonoArray *PackedColorArray_to_mono_array(const PackedColorArray &p_array) { MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(Color), length); if constexpr (InteropLayout::MATCHES_Color) { - Color *dst = (Color *)mono_array_addr(ret, Color, 0); - memcpy(dst, src, length); + Color *dst = mono_array_addr(ret, Color, 0); + memcpy(dst, src, length * sizeof(Color)); } else { for (int i = 0; i < length; i++) { M_Color *raw = (M_Color *)mono_array_addr_with_size(ret, sizeof(M_Color), i); @@ -1353,15 +1409,16 @@ MonoArray *PackedColorArray_to_mono_array(const PackedColorArray &p_array) { PackedColorArray mono_array_to_PackedColorArray(MonoArray *p_array) { PackedColorArray ret; - if (!p_array) + if (!p_array) { return ret; + } int length = mono_array_length(p_array); ret.resize(length); Color *dst = ret.ptrw(); if constexpr (InteropLayout::MATCHES_Color) { - const Color *src = (const Color *)mono_array_addr(p_array, Color, 0); - memcpy(dst, src, length); + const Color *src = mono_array_addr(p_array, Color, 0); + memcpy(dst, src, length * sizeof(Color)); } else { for (int i = 0; i < length; i++) { dst[i] = MARSHALLED_IN(Color, (M_Color *)mono_array_addr_with_size(p_array, sizeof(M_Color), i)); @@ -1378,8 +1435,8 @@ MonoArray *PackedVector2Array_to_mono_array(const PackedVector2Array &p_array) { MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(Vector2), length); if constexpr (InteropLayout::MATCHES_Vector2) { - Vector2 *dst = (Vector2 *)mono_array_addr(ret, Vector2, 0); - memcpy(dst, src, length); + Vector2 *dst = mono_array_addr(ret, Vector2, 0); + memcpy(dst, src, length * sizeof(Vector2)); } else { for (int i = 0; i < length; i++) { M_Vector2 *raw = (M_Vector2 *)mono_array_addr_with_size(ret, sizeof(M_Vector2), i); @@ -1392,15 +1449,16 @@ MonoArray *PackedVector2Array_to_mono_array(const PackedVector2Array &p_array) { PackedVector2Array mono_array_to_PackedVector2Array(MonoArray *p_array) { PackedVector2Array ret; - if (!p_array) + if (!p_array) { return ret; + } int length = mono_array_length(p_array); ret.resize(length); Vector2 *dst = ret.ptrw(); if constexpr (InteropLayout::MATCHES_Vector2) { - const Vector2 *src = (const Vector2 *)mono_array_addr(p_array, Vector2, 0); - memcpy(dst, src, length); + const Vector2 *src = mono_array_addr(p_array, Vector2, 0); + memcpy(dst, src, length * sizeof(Vector2)); } else { for (int i = 0; i < length; i++) { dst[i] = MARSHALLED_IN(Vector2, (M_Vector2 *)mono_array_addr_with_size(p_array, sizeof(M_Vector2), i)); @@ -1417,8 +1475,8 @@ MonoArray *PackedVector3Array_to_mono_array(const PackedVector3Array &p_array) { MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(Vector3), length); if constexpr (InteropLayout::MATCHES_Vector3) { - Vector3 *dst = (Vector3 *)mono_array_addr(ret, Vector3, 0); - memcpy(dst, src, length); + Vector3 *dst = mono_array_addr(ret, Vector3, 0); + memcpy(dst, src, length * sizeof(Vector3)); } else { for (int i = 0; i < length; i++) { M_Vector3 *raw = (M_Vector3 *)mono_array_addr_with_size(ret, sizeof(M_Vector3), i); @@ -1431,15 +1489,16 @@ MonoArray *PackedVector3Array_to_mono_array(const PackedVector3Array &p_array) { PackedVector3Array mono_array_to_PackedVector3Array(MonoArray *p_array) { PackedVector3Array ret; - if (!p_array) + if (!p_array) { return ret; + } int length = mono_array_length(p_array); ret.resize(length); Vector3 *dst = ret.ptrw(); if constexpr (InteropLayout::MATCHES_Vector3) { - const Vector3 *src = (const Vector3 *)mono_array_addr(p_array, Vector3, 0); - memcpy(dst, src, length); + const Vector3 *src = mono_array_addr(p_array, Vector3, 0); + memcpy(dst, src, length * sizeof(Vector3)); } else { for (int i = 0; i < length; i++) { dst[i] = MARSHALLED_IN(Vector3, (M_Vector3 *)mono_array_addr_with_size(p_array, sizeof(M_Vector3), i)); diff --git a/modules/mono/mono_gd/gd_mono_marshal.h b/modules/mono/mono_gd/gd_mono_marshal.h index f2d887e6d6..4ff330fd43 100644 --- a/modules/mono/mono_gd/gd_mono_marshal.h +++ b/modules/mono/mono_gd/gd_mono_marshal.h @@ -66,7 +66,6 @@ T *unbox_addr(MonoObject *p_obj) { Variant::Type managed_to_variant_type(const ManagedType &p_type, bool *r_nil_is_variant = nullptr); bool try_get_array_element_type(const ManagedType &p_array_type, ManagedType &r_elem_type); -bool try_get_dictionary_key_value_types(const ManagedType &p_dictionary_type, ManagedType &r_key_type, ManagedType &r_value_type); // String @@ -74,15 +73,17 @@ String mono_to_utf8_string(MonoString *p_mono_string); String mono_to_utf16_string(MonoString *p_mono_string); _FORCE_INLINE_ String mono_string_to_godot_not_null(MonoString *p_mono_string) { - if (sizeof(CharType) == 2) + if constexpr (sizeof(CharType) == 2) { return mono_to_utf16_string(p_mono_string); + } return mono_to_utf8_string(p_mono_string); } _FORCE_INLINE_ String mono_string_to_godot(MonoString *p_mono_string) { - if (p_mono_string == nullptr) + if (p_mono_string == nullptr) { return String(); + } return mono_string_to_godot_not_null(p_mono_string); } @@ -96,8 +97,9 @@ _FORCE_INLINE_ MonoString *mono_from_utf16_string(const String &p_string) { } _FORCE_INLINE_ MonoString *mono_string_from_godot(const String &p_string) { - if (sizeof(CharType) == 2) + if constexpr (sizeof(CharType) == 2) { return mono_from_utf16_string(p_string); + } return mono_from_utf8_string(p_string); } diff --git a/modules/mono/mono_gd/gd_mono_method.cpp b/modules/mono/mono_gd/gd_mono_method.cpp index e601bb12ad..04f3b25a70 100644 --- a/modules/mono/mono_gd/gd_mono_method.cpp +++ b/modules/mono/mono_gd/gd_mono_method.cpp @@ -155,11 +155,13 @@ MonoObject *GDMonoMethod::invoke_raw(MonoObject *p_object, void **p_params, Mono bool GDMonoMethod::has_attribute(GDMonoClass *p_attr_class) { ERR_FAIL_NULL_V(p_attr_class, false); - if (!attrs_fetched) + if (!attrs_fetched) { fetch_attributes(); + } - if (!attributes) + if (!attributes) { return false; + } return mono_custom_attrs_has_attr(attributes, p_attr_class->get_mono_ptr()); } @@ -167,11 +169,13 @@ bool GDMonoMethod::has_attribute(GDMonoClass *p_attr_class) { MonoObject *GDMonoMethod::get_attribute(GDMonoClass *p_attr_class) { ERR_FAIL_NULL_V(p_attr_class, nullptr); - if (!attrs_fetched) + if (!attrs_fetched) { fetch_attributes(); + } - if (!attributes) + if (!attributes) { return nullptr; + } return mono_custom_attrs_get_attr(attributes, p_attr_class->get_mono_ptr()); } @@ -250,8 +254,9 @@ const MethodInfo &GDMonoMethod::get_method_info() { bool nil_is_variant = false; method_info.return_val = PropertyInfo(GDMonoMarshal::managed_to_variant_type(return_type, &nil_is_variant), ""); - if (method_info.return_val.type == Variant::NIL && nil_is_variant) + if (method_info.return_val.type == Variant::NIL && nil_is_variant) { method_info.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT; + } Vector<StringName> names; get_parameter_names(names); @@ -259,8 +264,9 @@ const MethodInfo &GDMonoMethod::get_method_info() { for (int i = 0; i < params_count; ++i) { nil_is_variant = false; PropertyInfo arg_info = PropertyInfo(GDMonoMarshal::managed_to_variant_type(param_types[i], &nil_is_variant), names[i]); - if (arg_info.type == Variant::NIL && nil_is_variant) + if (arg_info.type == Variant::NIL && nil_is_variant) { arg_info.usage |= PROPERTY_USAGE_NIL_IS_VARIANT; + } method_info.arguments.push_back(arg_info); } diff --git a/modules/mono/mono_gd/gd_mono_property.cpp b/modules/mono/mono_gd/gd_mono_property.cpp index c3e7598f2d..bc3be97102 100644 --- a/modules/mono/mono_gd/gd_mono_property.cpp +++ b/modules/mono/mono_gd/gd_mono_property.cpp @@ -77,15 +77,17 @@ GDMonoProperty::~GDMonoProperty() { bool GDMonoProperty::is_static() { MonoMethod *prop_method = mono_property_get_get_method(mono_property); - if (prop_method == nullptr) + if (prop_method == nullptr) { prop_method = mono_property_get_set_method(mono_property); + } return mono_method_get_flags(prop_method, nullptr) & MONO_METHOD_ATTR_STATIC; } IMonoClassMember::Visibility GDMonoProperty::get_visibility() { MonoMethod *prop_method = mono_property_get_get_method(mono_property); - if (prop_method == nullptr) + if (prop_method == nullptr) { prop_method = mono_property_get_set_method(mono_property); + } switch (mono_method_get_flags(prop_method, nullptr) & MONO_METHOD_ATTR_ACCESS_MASK) { case MONO_METHOD_ATTR_PRIVATE: @@ -106,11 +108,13 @@ IMonoClassMember::Visibility GDMonoProperty::get_visibility() { bool GDMonoProperty::has_attribute(GDMonoClass *p_attr_class) { ERR_FAIL_NULL_V(p_attr_class, false); - if (!attrs_fetched) + if (!attrs_fetched) { fetch_attributes(); + } - if (!attributes) + if (!attributes) { return false; + } return mono_custom_attrs_has_attr(attributes, p_attr_class->get_mono_ptr()); } @@ -118,11 +122,13 @@ bool GDMonoProperty::has_attribute(GDMonoClass *p_attr_class) { MonoObject *GDMonoProperty::get_attribute(GDMonoClass *p_attr_class) { ERR_FAIL_NULL_V(p_attr_class, nullptr); - if (!attrs_fetched) + if (!attrs_fetched) { fetch_attributes(); + } - if (!attributes) + if (!attributes) { return nullptr; + } return mono_custom_attrs_get_attr(attributes, p_attr_class->get_mono_ptr()); } diff --git a/modules/mono/mono_gd/gd_mono_utils.cpp b/modules/mono/mono_gd/gd_mono_utils.cpp index 332744ae6e..3f1155f430 100644 --- a/modules/mono/mono_gd/gd_mono_utils.cpp +++ b/modules/mono/mono_gd/gd_mono_utils.cpp @@ -38,7 +38,6 @@ #include "core/os/dir_access.h" #include "core/os/mutex.h" #include "core/os/os.h" -#include "core/project_settings.h" #include "core/reference.h" #ifdef TOOLS_ENABLED @@ -51,13 +50,13 @@ #include "gd_mono_cache.h" #include "gd_mono_class.h" #include "gd_mono_marshal.h" -#include "gd_mono_method_thunk.h" namespace GDMonoUtils { MonoObject *unmanaged_get_managed(Object *unmanaged) { - if (!unmanaged) + if (!unmanaged) { return nullptr; + } if (unmanaged->get_script_instance()) { CSharpInstance *cs_instance = CAST_CSHARP_INSTANCE(unmanaged->get_script_instance()); @@ -90,8 +89,9 @@ MonoObject *unmanaged_get_managed(Object *unmanaged) { MonoObject *target = gchandle.get_target(); - if (target) + if (target) { return target; + } CSharpLanguage::get_singleton()->release_script_gchandle(gchandle); @@ -196,8 +196,9 @@ GDMonoClass *get_object_class(MonoObject *p_object) { GDMonoClass *type_get_proxy_class(const StringName &p_type) { String class_name = p_type; - if (class_name[0] == '_') + if (class_name[0] == '_') { class_name = class_name.substr(1, class_name.length()); + } GDMonoClass *klass = GDMono::get_singleton()->get_core_api_assembly()->get_class(BINDINGS_NAMESPACE, class_name); @@ -220,11 +221,14 @@ GDMonoClass *get_class_native_base(GDMonoClass *p_class) { do { const GDMonoAssembly *assembly = klass->get_assembly(); - if (assembly == GDMono::get_singleton()->get_core_api_assembly()) + + if (assembly == GDMono::get_singleton()->get_core_api_assembly()) { return klass; + } #ifdef TOOLS_ENABLED - if (assembly == GDMono::get_singleton()->get_editor_api_assembly()) + if (assembly == GDMono::get_singleton()->get_editor_api_assembly()) { return klass; + } #endif } while ((klass = klass->get_parent_class()) != nullptr); @@ -385,14 +389,6 @@ String get_exception_name_and_message(MonoException *p_exc) { return res; } -void set_exception_message(MonoException *p_exc, String message) { - MonoClass *klass = mono_object_get_class((MonoObject *)p_exc); - MonoProperty *prop = mono_class_get_property_from_name(klass, "Message"); - MonoString *msg = GDMonoMarshal::mono_string_from_godot(message); - void *params[1] = { msg }; - property_set_value(prop, (MonoObject *)p_exc, params, nullptr); -} - void debug_print_unhandled_exception(MonoException *p_exc) { print_unhandled_exception(p_exc); debug_send_unhandled_exception_error(p_exc); @@ -410,8 +406,9 @@ void debug_send_unhandled_exception_error(MonoException *p_exc) { } static thread_local bool _recursion_flag_ = false; - if (_recursion_flag_) + if (_recursion_flag_) { return; + } _recursion_flag_ = true; SCOPE_EXIT { _recursion_flag_ = false; }; @@ -441,8 +438,9 @@ void debug_send_unhandled_exception_error(MonoException *p_exc) { Vector<ScriptLanguage::StackInfo> _si; if (stack_trace != nullptr) { _si = CSharpLanguage::get_singleton()->stack_trace_get_info(stack_trace); - for (int i = _si.size() - 1; i >= 0; i--) + for (int i = _si.size() - 1; i >= 0; i--) { si.insert(0, _si[i]); + } } exc_msg += (exc_msg.length() > 0 ? " ---> " : "") + GDMonoUtils::get_exception_name_and_message(p_exc); @@ -452,8 +450,9 @@ void debug_send_unhandled_exception_error(MonoException *p_exc) { CRASH_COND(inner_exc_prop == nullptr); MonoObject *inner_exc = inner_exc_prop->get_value((MonoObject *)p_exc); - if (inner_exc != nullptr) + if (inner_exc != nullptr) { si.insert(0, separator); + } p_exc = (MonoException *)inner_exc; } diff --git a/modules/mono/mono_gd/gd_mono_utils.h b/modules/mono/mono_gd/gd_mono_utils.h index a7ca46f012..9db4a5f3f0 100644 --- a/modules/mono/mono_gd/gd_mono_utils.h +++ b/modules/mono/mono_gd/gd_mono_utils.h @@ -84,10 +84,6 @@ void detach_current_thread(MonoThread *p_mono_thread); MonoThread *get_current_thread(); bool is_thread_attached(); -_FORCE_INLINE_ bool is_main_thread() { - return mono_domain_get() != nullptr && mono_thread_get_main() == mono_thread_current(); -} - uint32_t new_strong_gchandle(MonoObject *p_object); uint32_t new_strong_gchandle_pinned(MonoObject *p_object); uint32_t new_weak_gchandle(MonoObject *p_object); @@ -115,7 +111,6 @@ String get_type_desc(MonoType *p_type); String get_type_desc(MonoReflectionType *p_reftype); String get_exception_name_and_message(MonoException *p_exc); -void set_exception_message(MonoException *p_exc, String message); void debug_print_unhandled_exception(MonoException *p_exc); void debug_send_unhandled_exception_error(MonoException *p_exc); diff --git a/modules/mono/register_types.cpp b/modules/mono/register_types.cpp index 94431e7c30..98c3ba1324 100644 --- a/modules/mono/register_types.cpp +++ b/modules/mono/register_types.cpp @@ -62,8 +62,9 @@ void register_mono_types() { void unregister_mono_types() { ScriptServer::unregister_language(script_language_cs); - if (script_language_cs) + if (script_language_cs) { memdelete(script_language_cs); + } ResourceLoader::remove_resource_format_loader(resource_loader_cs); resource_loader_cs.unref(); @@ -71,6 +72,7 @@ void unregister_mono_types() { ResourceSaver::remove_resource_format_saver(resource_saver_cs); resource_saver_cs.unref(); - if (_godotsharp) + if (_godotsharp) { memdelete(_godotsharp); + } } diff --git a/modules/mono/signal_awaiter_utils.cpp b/modules/mono/signal_awaiter_utils.cpp index ed0dc5cc28..bd67b03c8e 100644 --- a/modules/mono/signal_awaiter_utils.cpp +++ b/modules/mono/signal_awaiter_utils.cpp @@ -51,18 +51,21 @@ bool SignalAwaiterCallable::compare_equal(const CallableCustom *p_a, const Calla const SignalAwaiterCallable *a = static_cast<const SignalAwaiterCallable *>(p_a); const SignalAwaiterCallable *b = static_cast<const SignalAwaiterCallable *>(p_b); - if (a->target_id != b->target_id) + if (a->target_id != b->target_id) { return false; + } - if (a->signal != b->signal) + if (a->signal != b->signal) { return false; + } return true; } bool SignalAwaiterCallable::compare_less(const CallableCustom *p_a, const CallableCustom *p_b) { - if (compare_equal(p_a, p_b)) + if (compare_equal(p_a, p_b)) { return false; + } return p_a < p_b; } @@ -145,18 +148,21 @@ bool EventSignalCallable::compare_equal(const CallableCustom *p_a, const Callabl const EventSignalCallable *a = static_cast<const EventSignalCallable *>(p_a); const EventSignalCallable *b = static_cast<const EventSignalCallable *>(p_b); - if (a->owner != b->owner) + if (a->owner != b->owner) { return false; + } - if (a->event_signal != b->event_signal) + if (a->event_signal != b->event_signal) { return false; + } return true; } bool EventSignalCallable::compare_less(const CallableCustom *p_a, const CallableCustom *p_b) { - if (compare_equal(p_a, p_b)) + if (compare_equal(p_a, p_b)) { return false; + } return p_a < p_b; } diff --git a/modules/mono/utils/path_utils.cpp b/modules/mono/utils/path_utils.cpp index 973375a471..ccfaf5aba7 100644 --- a/modules/mono/utils/path_utils.cpp +++ b/modules/mono/utils/path_utils.cpp @@ -50,34 +50,6 @@ namespace path { -String find_executable(const String &p_name) { -#ifdef WINDOWS_ENABLED - Vector<String> exts = OS::get_singleton()->get_environment("PATHEXT").split(ENV_PATH_SEP, false); -#endif - Vector<String> env_path = OS::get_singleton()->get_environment("PATH").split(ENV_PATH_SEP, false); - - if (env_path.empty()) - return String(); - - for (int i = 0; i < env_path.size(); i++) { - String p = path::join(env_path[i], p_name); - -#ifdef WINDOWS_ENABLED - for (int j = 0; j < exts.size(); j++) { - String p2 = p + exts[j].to_lower(); // lowercase to reduce risk of case mismatch warning - - if (FileAccess::exists(p2)) - return p2; - } -#else - if (FileAccess::exists(p)) - return p; -#endif - } - - return String(); -} - String cwd() { #ifdef WINDOWS_ENABLED const DWORD expected_size = ::GetCurrentDirectoryW(0, nullptr); @@ -90,12 +62,14 @@ String cwd() { return buffer.simplify_path(); #else char buffer[PATH_MAX]; - if (::getcwd(buffer, sizeof(buffer)) == nullptr) + if (::getcwd(buffer, sizeof(buffer)) == nullptr) { return "."; + } String result; - if (result.parse_utf8(buffer)) + if (result.parse_utf8(buffer)) { return "."; + } return result.simplify_path(); #endif @@ -135,23 +109,26 @@ String realpath(const String &p_path) { #elif UNIX_ENABLED char *resolved_path = ::realpath(p_path.utf8().get_data(), nullptr); - if (!resolved_path) + if (!resolved_path) { return p_path; + } String result; bool parse_ok = result.parse_utf8(resolved_path); ::free(resolved_path); - if (parse_ok) + if (parse_ok) { return p_path; + } return result.simplify_path(); #endif } String join(const String &p_a, const String &p_b) { - if (p_a.empty()) + if (p_a.empty()) { return p_b; + } const CharType a_last = p_a[p_a.length() - 1]; if ((a_last == '/' || a_last == '\\') || @@ -178,8 +155,9 @@ String relative_to_impl(const String &p_path, const String &p_relative_to) { } else { String base_dir = p_relative_to.get_base_dir(); - if (base_dir.length() <= 2 && (base_dir.empty() || base_dir.ends_with(":"))) + if (base_dir.length() <= 2 && (base_dir.empty() || base_dir.ends_with(":"))) { return p_path; + } return String("..").plus_file(relative_to_impl(p_path, base_dir)); } diff --git a/modules/mono/utils/path_utils.h b/modules/mono/utils/path_utils.h index 9965f58b0a..bcd8af8bb9 100644 --- a/modules/mono/utils/path_utils.h +++ b/modules/mono/utils/path_utils.h @@ -40,8 +40,6 @@ String join(const String &p_a, const String &p_b); String join(const String &p_a, const String &p_b, const String &p_c); String join(const String &p_a, const String &p_b, const String &p_c, const String &p_d); -String find_executable(const String &p_name); - /// Returns a normalized absolute path to the current working directory String cwd(); diff --git a/modules/mono/utils/string_utils.cpp b/modules/mono/utils/string_utils.cpp index da1b719d99..f8d9804de4 100644 --- a/modules/mono/utils/string_utils.cpp +++ b/modules/mono/utils/string_utils.cpp @@ -38,14 +38,16 @@ namespace { int sfind(const String &p_text, int p_from) { - if (p_from < 0) + if (p_from < 0) { return -1; + } int src_len = 2; int len = p_text.length(); - if (len == 0) + if (len == 0) { return -1; + } const CharType *src = p_text.c_str(); @@ -75,8 +77,9 @@ int sfind(const String &p_text, int p_from) { } } - if (found) + if (found) { return i; + } } return -1; @@ -85,8 +88,9 @@ int sfind(const String &p_text, int p_from) { } // namespace String sformat(const String &p_text, const Variant &p1, const Variant &p2, const Variant &p3, const Variant &p4, const Variant &p5) { - if (p_text.length() < 2) + if (p_text.length() < 2) { return p_text; + } Array args; diff --git a/thirdparty/misc/stb_vorbis.c b/thirdparty/misc/stb_vorbis.c index b0d79b1724..52c9c666a2 100644 --- a/thirdparty/misc/stb_vorbis.c +++ b/thirdparty/misc/stb_vorbis.c @@ -3630,6 +3630,7 @@ static int start_decoder(vorb *f) //file vendor len = get32_packet(f); f->vendor = (char*)setup_malloc(f, sizeof(char) * (len+1)); + if (f->vendor == NULL) return error(f, VORBIS_outofmem); for(i=0; i < len; ++i) { f->vendor[i] = get8_packet(f); } @@ -3637,10 +3638,12 @@ static int start_decoder(vorb *f) //user comments f->comment_list_length = get32_packet(f); f->comment_list = (char**)setup_malloc(f, sizeof(char*) * (f->comment_list_length)); + if (f->comment_list == NULL) return error(f, VORBIS_outofmem); for(i=0; i < f->comment_list_length; ++i) { len = get32_packet(f); f->comment_list[i] = (char*)setup_malloc(f, sizeof(char) * (len+1)); + if (f->comment_list[i] == NULL) return error(f, VORBIS_outofmem); for(j=0; j < len; ++j) { f->comment_list[i][j] = get8_packet(f); |