diff options
Diffstat (limited to 'core')
46 files changed, 424 insertions, 593 deletions
diff --git a/core/config/project_settings.cpp b/core/config/project_settings.cpp index d33fce3cab..db3191334a 100644 --- a/core/config/project_settings.cpp +++ b/core/config/project_settings.cpp @@ -1069,23 +1069,6 @@ Variant _GLOBAL_DEF(const PropertyInfo &p_info, const Variant &p_default, bool p return ret; } -Vector<String> ProjectSettings::get_optimizer_presets() const { - List<PropertyInfo> pi; - ProjectSettings::get_singleton()->get_property_list(&pi); - Vector<String> names; - - for (const PropertyInfo &E : pi) { - if (!E.name.begins_with("optimizer_presets/")) { - continue; - } - names.push_back(E.name.get_slicec('/', 1)); - } - - names.sort(); - - return names; -} - void ProjectSettings::_add_property_info_bind(const Dictionary &p_info) { ERR_FAIL_COND(!p_info.has("name")); ERR_FAIL_COND(!p_info.has("type")); diff --git a/core/config/project_settings.h b/core/config/project_settings.h index 29c495c46b..d1704a7c31 100644 --- a/core/config/project_settings.h +++ b/core/config/project_settings.h @@ -178,8 +178,6 @@ public: const HashMap<StringName, PropertyInfo> &get_custom_property_info() const; uint64_t get_last_saved_time() { return last_save_time; } - Vector<String> get_optimizer_presets() const; - List<String> get_input_presets() const { return input_presets; } Variant get_setting_with_override(const StringName &p_name) const; diff --git a/core/debugger/script_debugger.cpp b/core/debugger/script_debugger.cpp index 8af1573bff..32725b76c1 100644 --- a/core/debugger/script_debugger.cpp +++ b/core/debugger/script_debugger.cpp @@ -73,10 +73,6 @@ bool ScriptDebugger::is_breakpoint(int p_line, const StringName &p_source) const return breakpoints[p_line].has(p_source); } -bool ScriptDebugger::is_breakpoint_line(int p_line) const { - return breakpoints.has(p_line); -} - String ScriptDebugger::breakpoint_find_source(const String &p_source) const { return p_source; } diff --git a/core/debugger/script_debugger.h b/core/debugger/script_debugger.h index c7aa90027b..edce089179 100644 --- a/core/debugger/script_debugger.h +++ b/core/debugger/script_debugger.h @@ -64,7 +64,6 @@ public: void insert_breakpoint(int p_line, const StringName &p_source); void remove_breakpoint(int p_line, const StringName &p_source); bool is_breakpoint(int p_line, const StringName &p_source) const; - bool is_breakpoint_line(int p_line) const; void clear_breakpoints(); const HashMap<int, HashSet<StringName>> &get_breakpoints() const { return breakpoints; } diff --git a/core/extension/gdextension_interface.cpp b/core/extension/gdextension_interface.cpp index bd4fa61bd5..a9063c8b27 100644 --- a/core/extension/gdextension_interface.cpp +++ b/core/extension/gdextension_interface.cpp @@ -31,8 +31,11 @@ #include "gdextension_interface.h" #include "core/config/engine.h" +#include "core/io/file_access.h" +#include "core/io/xml_parser.h" #include "core/object/class_db.h" #include "core/object/script_language_extension.h" +#include "core/object/worker_thread_pool.h" #include "core/os/memory.h" #include "core/variant/variant.h" #include "core/version.h" @@ -678,6 +681,59 @@ static const char32_t *gdextension_string_operator_index_const(GDExtensionConstS return &self->ptr()[p_index]; } +static void gdextension_string_operator_plus_eq_string(GDExtensionStringPtr p_self, GDExtensionConstStringPtr p_b) { + String *self = (String *)p_self; + const String *b = (const String *)p_b; + *self += *b; +} + +static void gdextension_string_operator_plus_eq_char(GDExtensionStringPtr p_self, char32_t p_b) { + String *self = (String *)p_self; + *self += p_b; +} + +static void gdextension_string_operator_plus_eq_cstr(GDExtensionStringPtr p_self, const char *p_b) { + String *self = (String *)p_self; + *self += p_b; +} + +static void gdextension_string_operator_plus_eq_wcstr(GDExtensionStringPtr p_self, const wchar_t *p_b) { + String *self = (String *)p_self; + *self += p_b; +} + +static void gdextension_string_operator_plus_eq_c32str(GDExtensionStringPtr p_self, const char32_t *p_b) { + String *self = (String *)p_self; + *self += p_b; +} + +static GDExtensionInt gdextension_xml_parser_open_buffer(GDExtensionObjectPtr p_instance, const uint8_t *p_buffer, size_t p_size) { + XMLParser *xml = (XMLParser *)p_instance; + return (GDExtensionInt)xml->_open_buffer(p_buffer, p_size); +} + +static void gdextension_file_access_store_buffer(GDExtensionObjectPtr p_instance, const uint8_t *p_src, uint64_t p_length) { + FileAccess *fa = (FileAccess *)p_instance; + fa->store_buffer(p_src, p_length); +} + +static uint64_t gdextension_file_access_get_buffer(GDExtensionConstObjectPtr p_instance, uint8_t *p_dst, uint64_t p_length) { + const FileAccess *fa = (FileAccess *)p_instance; + return fa->get_buffer(p_dst, p_length); +} + +static int64_t gdextension_worker_thread_pool_add_native_group_task(GDExtensionObjectPtr p_instance, void (*p_func)(void *, uint32_t), void *p_userdata, int p_elements, int p_tasks, GDExtensionBool p_high_priority, GDExtensionConstStringPtr p_description) { + WorkerThreadPool *p = (WorkerThreadPool *)p_instance; + const String *description = (const String *)p_description; + return (int64_t)p->add_native_group_task(p_func, p_userdata, p_elements, p_tasks, static_cast<bool>(p_high_priority), *description); +} + +static int64_t gdextension_worker_thread_pool_add_native_task(GDExtensionObjectPtr p_instance, void (*p_func)(void *), void *p_userdata, GDExtensionBool p_high_priority, GDExtensionConstStringPtr p_description) { + WorkerThreadPool *p = (WorkerThreadPool *)p_instance; + const String *description = (const String *)p_description; + return (int64_t)p->add_native_task(p_func, p_userdata, static_cast<bool>(p_high_priority), *description); +} + /* Packed array functions */ static uint8_t *gdextension_packed_byte_array_operator_index(GDExtensionTypePtr p_self, GDExtensionInt p_index) { @@ -1025,6 +1081,25 @@ void gdextension_setup_interface(GDExtensionInterface *p_interface) { gde_interface.string_to_wide_chars = gdextension_string_to_wide_chars; gde_interface.string_operator_index = gdextension_string_operator_index; gde_interface.string_operator_index_const = gdextension_string_operator_index_const; + gde_interface.string_operator_plus_eq_string = gdextension_string_operator_plus_eq_string; + gde_interface.string_operator_plus_eq_char = gdextension_string_operator_plus_eq_char; + gde_interface.string_operator_plus_eq_cstr = gdextension_string_operator_plus_eq_cstr; + gde_interface.string_operator_plus_eq_wcstr = gdextension_string_operator_plus_eq_wcstr; + gde_interface.string_operator_plus_eq_c32str = gdextension_string_operator_plus_eq_c32str; + + /* XMLParser extra utilities */ + + gde_interface.xml_parser_open_buffer = gdextension_xml_parser_open_buffer; + + /* FileAccess extra utilities */ + + gde_interface.file_access_store_buffer = gdextension_file_access_store_buffer; + gde_interface.file_access_get_buffer = gdextension_file_access_get_buffer; + + /* WorkerThreadPool extra utilities */ + + gde_interface.worker_thread_pool_add_native_group_task = gdextension_worker_thread_pool_add_native_group_task; + gde_interface.worker_thread_pool_add_native_task = gdextension_worker_thread_pool_add_native_task; /* Packed array functions */ diff --git a/core/extension/gdextension_interface.h b/core/extension/gdextension_interface.h index 190298ee8a..6e5dee8265 100644 --- a/core/extension/gdextension_interface.h +++ b/core/extension/gdextension_interface.h @@ -503,6 +503,26 @@ typedef struct { char32_t *(*string_operator_index)(GDExtensionStringPtr p_self, GDExtensionInt p_index); const char32_t *(*string_operator_index_const)(GDExtensionConstStringPtr p_self, GDExtensionInt p_index); + void (*string_operator_plus_eq_string)(GDExtensionStringPtr p_self, GDExtensionConstStringPtr p_b); + void (*string_operator_plus_eq_char)(GDExtensionStringPtr p_self, char32_t p_b); + void (*string_operator_plus_eq_cstr)(GDExtensionStringPtr p_self, const char *p_b); + void (*string_operator_plus_eq_wcstr)(GDExtensionStringPtr p_self, const wchar_t *p_b); + void (*string_operator_plus_eq_c32str)(GDExtensionStringPtr p_self, const char32_t *p_b); + + /* XMLParser extra utilities */ + + GDExtensionInt (*xml_parser_open_buffer)(GDExtensionObjectPtr p_instance, const uint8_t *p_buffer, size_t p_size); + + /* FileAccess extra utilities */ + + void (*file_access_store_buffer)(GDExtensionObjectPtr p_instance, const uint8_t *p_src, uint64_t p_length); + uint64_t (*file_access_get_buffer)(GDExtensionConstObjectPtr p_instance, uint8_t *p_dst, uint64_t p_length); + + /* WorkerThreadPool extra utilities */ + + int64_t (*worker_thread_pool_add_native_group_task)(GDExtensionObjectPtr p_instance, void (*p_func)(void *, uint32_t), void *p_userdata, int p_elements, int p_tasks, GDExtensionBool p_high_priority, GDExtensionConstStringPtr p_description); + int64_t (*worker_thread_pool_add_native_task)(GDExtensionObjectPtr p_instance, void (*p_func)(void *), void *p_userdata, GDExtensionBool p_high_priority, GDExtensionConstStringPtr p_description); + /* Packed array functions */ uint8_t *(*packed_byte_array_operator_index)(GDExtensionTypePtr p_self, GDExtensionInt p_index); // p_self should be a PackedByteArray diff --git a/core/io/file_access.cpp b/core/io/file_access.cpp index 77d1bdcc5c..cacbcb28a4 100644 --- a/core/io/file_access.cpp +++ b/core/io/file_access.cpp @@ -292,7 +292,7 @@ real_t FileAccess::get_real() const { Variant FileAccess::get_var(bool p_allow_objects) const { uint32_t len = get_32(); - Vector<uint8_t> buff = _get_buffer(len); + Vector<uint8_t> buff = get_buffer(len); ERR_FAIL_COND_V((uint32_t)buff.size() != len, Variant()); const uint8_t *r = buff.ptr(); @@ -469,7 +469,7 @@ uint64_t FileAccess::get_buffer(uint8_t *p_dst, uint64_t p_length) const { return i; } -Vector<uint8_t> FileAccess::_get_buffer(int64_t p_length) const { +Vector<uint8_t> FileAccess::get_buffer(int64_t p_length) const { Vector<uint8_t> data; ERR_FAIL_COND_V_MSG(p_length < 0, data, "Length of buffer cannot be smaller than 0."); @@ -663,7 +663,7 @@ void FileAccess::store_buffer(const uint8_t *p_src, uint64_t p_length) { } } -void FileAccess::_store_buffer(const Vector<uint8_t> &p_buffer) { +void FileAccess::store_buffer(const Vector<uint8_t> &p_buffer) { uint64_t len = p_buffer.size(); if (len == 0) { return; @@ -687,7 +687,7 @@ void FileAccess::store_var(const Variant &p_var, bool p_full_objects) { ERR_FAIL_COND_MSG(err != OK, "Error when trying to encode Variant."); store_32(len); - _store_buffer(buff); + store_buffer(buff); } Vector<uint8_t> FileAccess::get_file_as_bytes(const String &p_path, Error *r_error) { @@ -829,7 +829,7 @@ void FileAccess::_bind_methods() { ClassDB::bind_method(D_METHOD("get_float"), &FileAccess::get_float); ClassDB::bind_method(D_METHOD("get_double"), &FileAccess::get_double); ClassDB::bind_method(D_METHOD("get_real"), &FileAccess::get_real); - ClassDB::bind_method(D_METHOD("get_buffer", "length"), &FileAccess::_get_buffer); + ClassDB::bind_method(D_METHOD("get_buffer", "length"), (Vector<uint8_t>(FileAccess::*)(int64_t) const) & FileAccess::get_buffer); ClassDB::bind_method(D_METHOD("get_line"), &FileAccess::get_line); ClassDB::bind_method(D_METHOD("get_csv_line", "delim"), &FileAccess::get_csv_line, DEFVAL(",")); ClassDB::bind_method(D_METHOD("get_as_text", "skip_cr"), &FileAccess::get_as_text, DEFVAL(false)); @@ -847,7 +847,7 @@ void FileAccess::_bind_methods() { ClassDB::bind_method(D_METHOD("store_float", "value"), &FileAccess::store_float); ClassDB::bind_method(D_METHOD("store_double", "value"), &FileAccess::store_double); ClassDB::bind_method(D_METHOD("store_real", "value"), &FileAccess::store_real); - ClassDB::bind_method(D_METHOD("store_buffer", "buffer"), &FileAccess::_store_buffer); + ClassDB::bind_method(D_METHOD("store_buffer", "buffer"), (void(FileAccess::*)(const Vector<uint8_t> &)) & FileAccess::store_buffer); ClassDB::bind_method(D_METHOD("store_line", "line"), &FileAccess::store_line); ClassDB::bind_method(D_METHOD("store_csv_line", "values", "delim"), &FileAccess::store_csv_line, DEFVAL(",")); ClassDB::bind_method(D_METHOD("store_string", "string"), &FileAccess::store_string); diff --git a/core/io/file_access.h b/core/io/file_access.h index 3116ed521f..3e51ba11ed 100644 --- a/core/io/file_access.h +++ b/core/io/file_access.h @@ -127,7 +127,7 @@ public: Variant get_var(bool p_allow_objects = false) const; virtual uint64_t get_buffer(uint8_t *p_dst, uint64_t p_length) const; ///< get an array of bytes - Vector<uint8_t> _get_buffer(int64_t p_length) const; + Vector<uint8_t> get_buffer(int64_t p_length) const; virtual String get_line() const; virtual String get_token() const; virtual Vector<String> get_csv_line(const String &p_delim = ",") const; @@ -162,7 +162,7 @@ public: virtual String get_pascal_string(); virtual void store_buffer(const uint8_t *p_src, uint64_t p_length); ///< store an array of bytes - void _store_buffer(const Vector<uint8_t> &p_buffer); + void store_buffer(const Vector<uint8_t> &p_buffer); void store_var(const Variant &p_var, bool p_full_objects = false); diff --git a/core/io/image_loader.cpp b/core/io/image_loader.cpp index 17fb199811..c6452f1033 100644 --- a/core/io/image_loader.cpp +++ b/core/io/image_loader.cpp @@ -135,10 +135,6 @@ void ImageLoader::remove_image_format_loader(Ref<ImageFormatLoader> p_loader) { loader.erase(p_loader); } -const Vector<Ref<ImageFormatLoader>> &ImageLoader::get_image_format_loaders() { - return loader; -} - void ImageLoader::cleanup() { while (loader.size()) { remove_image_format_loader(loader[0]); diff --git a/core/io/image_loader.h b/core/io/image_loader.h index 1473f24186..ac51f13376 100644 --- a/core/io/image_loader.h +++ b/core/io/image_loader.h @@ -98,8 +98,6 @@ public: static void add_image_format_loader(Ref<ImageFormatLoader> p_loader); static void remove_image_format_loader(Ref<ImageFormatLoader> p_loader); - static const Vector<Ref<ImageFormatLoader>> &get_image_format_loaders(); - static void cleanup(); }; diff --git a/core/io/json.cpp b/core/io/json.cpp index ca29534c35..448e39b2c3 100644 --- a/core/io/json.cpp +++ b/core/io/json.cpp @@ -30,6 +30,7 @@ #include "json.h" +#include "core/config/engine.h" #include "core/string/print_string.h" const char *JSON::tk_name[TK_MAX] = { @@ -506,6 +507,7 @@ Error JSON::_parse_object(Dictionary &object, const char32_t *p_str, int &index, void JSON::set_data(const Variant &p_data) { data = p_data; + text.clear(); } Error JSON::_parse_string(const String &p_json, Variant &r_ret, String &r_err_str, int &r_err_line) { @@ -539,14 +541,21 @@ Error JSON::_parse_string(const String &p_json, Variant &r_ret, String &r_err_st return err; } -Error JSON::parse(const String &p_json_string) { +Error JSON::parse(const String &p_json_string, bool p_keep_text) { Error err = _parse_string(p_json_string, data, err_str, err_line); if (err == Error::OK) { err_line = 0; } + if (p_keep_text) { + text = p_json_string; + } return err; } +String JSON::get_parsed_text() const { + return text; +} + String JSON::stringify(const Variant &p_var, const String &p_indent, bool p_sort_keys, bool p_full_precision) { Ref<JSON> jason; jason.instantiate(); @@ -565,10 +574,11 @@ Variant JSON::parse_string(const String &p_json_string) { void JSON::_bind_methods() { ClassDB::bind_static_method("JSON", D_METHOD("stringify", "data", "indent", "sort_keys", "full_precision"), &JSON::stringify, DEFVAL(""), DEFVAL(true), DEFVAL(false)); ClassDB::bind_static_method("JSON", D_METHOD("parse_string", "json_string"), &JSON::parse_string); - ClassDB::bind_method(D_METHOD("parse", "json_string"), &JSON::parse); + ClassDB::bind_method(D_METHOD("parse", "json_text", "keep_text"), &JSON::parse, DEFVAL(false)); ClassDB::bind_method(D_METHOD("get_data"), &JSON::get_data); ClassDB::bind_method(D_METHOD("set_data", "data"), &JSON::set_data); + ClassDB::bind_method(D_METHOD("get_parsed_text"), &JSON::get_parsed_text); ClassDB::bind_method(D_METHOD("get_error_line"), &JSON::get_error_line); ClassDB::bind_method(D_METHOD("get_error_message"), &JSON::get_error_message); @@ -592,13 +602,20 @@ Ref<Resource> ResourceFormatLoaderJSON::load(const String &p_path, const String Ref<JSON> json; json.instantiate(); - Error err = json->parse(FileAccess::get_file_as_string(p_path)); + Error err = json->parse(FileAccess::get_file_as_string(p_path), Engine::get_singleton()->is_editor_hint()); if (err != OK) { - if (r_error) { - *r_error = err; + String err_text = "Error parsing JSON file at '" + p_path + "', on line " + itos(json->get_error_line()) + ": " + json->get_error_message(); + + if (Engine::get_singleton()->is_editor_hint()) { + // If running on editor, still allow opening the JSON so the code editor can edit it. + WARN_PRINT(err_text); + } else { + if (r_error) { + *r_error = err; + } + ERR_PRINT(err_text); + return Ref<Resource>(); } - ERR_PRINT("Error parsing JSON file at '" + p_path + "', on line " + itos(json->get_error_line()) + ": " + json->get_error_message()); - return Ref<Resource>(); } if (r_error) { @@ -628,7 +645,7 @@ Error ResourceFormatSaverJSON::save(const Ref<Resource> &p_resource, const Strin Ref<JSON> json = p_resource; ERR_FAIL_COND_V(json.is_null(), ERR_INVALID_PARAMETER); - String source = JSON::stringify(json->get_data(), "\t", false, true); + String source = json->get_parsed_text().is_empty() ? JSON::stringify(json->get_data(), "\t", false, true) : json->get_parsed_text(); Error err; Ref<FileAccess> file = FileAccess::open(p_path, FileAccess::WRITE, &err); diff --git a/core/io/json.h b/core/io/json.h index d66a4e24a3..a21cc542fd 100644 --- a/core/io/json.h +++ b/core/io/json.h @@ -36,8 +36,8 @@ #include "core/io/resource_saver.h" #include "core/variant/variant.h" -class JSON : public RefCounted { - GDCLASS(JSON, RefCounted); +class JSON : public Resource { + GDCLASS(JSON, Resource); enum TokenType { TK_CURLY_BRACKET_OPEN, @@ -65,6 +65,7 @@ class JSON : public RefCounted { Variant value; }; + String text; Variant data; String err_str; int err_line = 0; @@ -83,7 +84,9 @@ protected: static void _bind_methods(); public: - Error parse(const String &p_json_string); + Error parse(const String &p_json_string, bool p_keep_text = false); + String get_parsed_text() const; + static String stringify(const Variant &p_var, const String &p_indent = "", bool p_sort_keys = true, bool p_full_precision = false); static Variant parse_string(const String &p_json_string); diff --git a/core/io/resource.cpp b/core/io/resource.cpp index 2d6f09725f..6d3575b9fa 100644 --- a/core/io/resource.cpp +++ b/core/io/resource.cpp @@ -385,10 +385,6 @@ void Resource::set_as_translation_remapped(bool p_remapped) { ResourceCache::lock.unlock(); } -bool Resource::is_translation_remapped() const { - return remapped_list.in_list(); -} - #ifdef TOOLS_ENABLED //helps keep IDs same number when loading/saving scenes. -1 clears ID and it Returns -1 when no id stored void Resource::set_id_for_path(const String &p_path, const String &p_id) { @@ -481,9 +477,6 @@ void ResourceCache::clear() { resources.clear(); } -void ResourceCache::reload_externals() { -} - bool ResourceCache::has(const String &p_path) { lock.lock(); diff --git a/core/io/resource.h b/core/io/resource.h index 22ce5cef43..5135664f36 100644 --- a/core/io/resource.h +++ b/core/io/resource.h @@ -136,7 +136,6 @@ public: #endif void set_as_translation_remapped(bool p_remapped); - bool is_translation_remapped() const; virtual RID get_rid() const; // some resources may offer conversion to RID @@ -164,7 +163,6 @@ class ResourceCache { friend void register_core_types(); public: - static void reload_externals(); static bool has(const String &p_path); static Ref<Resource> get_ref(const String &p_path); static void get_cached_resources(List<Ref<Resource>> *p_resources); diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp index 45e1301930..c0463de427 100644 --- a/core/io/resource_format_binary.cpp +++ b/core/io/resource_format_binary.cpp @@ -91,7 +91,8 @@ enum { // Version 2: added 64 bits support for float and int. // Version 3: changed nodepath encoding. // Version 4: new string ID for ext/subresources, breaks forward compat. - FORMAT_VERSION = 4, + // Version 5: Ability to store script class in the header. + FORMAT_VERSION = 5, FORMAT_VERSION_CAN_RENAME_DEPS = 1, FORMAT_VERSION_NO_NODEPATH_PROPERTY = 3, }; @@ -661,10 +662,6 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) { return OK; //never reach anyway } -void ResourceLoaderBinary::set_local_path(const String &p_local_path) { - res_path = p_local_path; -} - Ref<Resource> ResourceLoaderBinary::get_resource() { return resource; } @@ -1013,6 +1010,10 @@ void ResourceLoaderBinary::open(Ref<FileAccess> p_f, bool p_no_resources, bool p uid = ResourceUID::INVALID_ID; } + if (flags & ResourceFormatSaverBinaryInstance::FORMAT_FLAG_HAS_SCRIPT_CLASS) { + script_class = get_unicode_string(); + } + for (int i = 0; i < ResourceFormatSaverBinaryInstance::RESERVED_FIELDS; i++) { f->get_32(); //skip a few reserved fields } @@ -1117,6 +1118,57 @@ String ResourceLoaderBinary::recognize(Ref<FileAccess> p_f) { return get_unicode_string(); } +String ResourceLoaderBinary::recognize_script_class(Ref<FileAccess> p_f) { + error = OK; + + f = p_f; + uint8_t header[4]; + f->get_buffer(header, 4); + if (header[0] == 'R' && header[1] == 'S' && header[2] == 'C' && header[3] == 'C') { + // Compressed. + Ref<FileAccessCompressed> fac; + fac.instantiate(); + error = fac->open_after_magic(f); + if (error != OK) { + f.unref(); + return ""; + } + f = fac; + + } else if (header[0] != 'R' || header[1] != 'S' || header[2] != 'R' || header[3] != 'C') { + // Not normal. + error = ERR_FILE_UNRECOGNIZED; + f.unref(); + return ""; + } + + bool big_endian = f->get_32(); + f->get_32(); // use_real64 + + f->set_big_endian(big_endian != 0); //read big endian if saved as big endian + + uint32_t ver_major = f->get_32(); + f->get_32(); // ver_minor + uint32_t ver_fmt = f->get_32(); + + if (ver_fmt > FORMAT_VERSION || ver_major > VERSION_MAJOR) { + f.unref(); + return ""; + } + + get_unicode_string(); // type + + f->get_64(); // Metadata offset + uint32_t flags = f->get_32(); + f->get_64(); // UID + + if (flags & ResourceFormatSaverBinaryInstance::FORMAT_FLAG_HAS_SCRIPT_CLASS) { + return get_unicode_string(); + } else { + return String(); + } +} + Ref<Resource> ResourceFormatLoaderBinary::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) { if (r_error) { *r_error = ERR_FILE_CANT_OPEN; @@ -1299,6 +1351,9 @@ Error ResourceFormatLoaderBinary::rename_dependencies(const String &p_path, cons fw->store_32(flags); fw->store_64(uid_data); + if (flags & ResourceFormatSaverBinaryInstance::FORMAT_FLAG_HAS_SCRIPT_CLASS) { + save_ustring(fw, get_ustring(f)); + } for (int i = 0; i < ResourceFormatSaverBinaryInstance::RESERVED_FIELDS; i++) { fw->store_32(0); // reserved @@ -1420,6 +1475,18 @@ String ResourceFormatLoaderBinary::get_resource_type(const String &p_path) const return ClassDB::get_compatibility_remapped_class(r); } +String ResourceFormatLoaderBinary::get_resource_script_class(const String &p_path) const { + Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::READ); + if (f.is_null()) { + return ""; //could not read + } + + ResourceLoaderBinary loader; + loader.local_path = ProjectSettings::get_singleton()->localize_path(p_path); + loader.res_path = loader.local_path; + return loader.recognize_script_class(f); +} + ResourceUID::ID ResourceFormatLoaderBinary::get_resource_uid(const String &p_path) const { String ext = p_path.get_extension().to_lower(); if (!ClassDB::is_resource_extension(ext)) { @@ -2037,15 +2104,31 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const Ref<Re save_unicode_string(f, _resource_get_class(p_resource)); f->store_64(0); //offset to import metadata + + String script_class; { uint32_t format_flags = FORMAT_FLAG_NAMED_SCENE_IDS | FORMAT_FLAG_UIDS; #ifdef REAL_T_IS_DOUBLE format_flags |= FORMAT_FLAG_REAL_T_IS_DOUBLE; #endif + if (!p_resource->is_class("PackedScene")) { + Ref<Script> s = p_resource->get_script(); + if (s.is_valid()) { + script_class = s->get_global_name(); + if (!script_class.is_empty()) { + format_flags |= ResourceFormatSaverBinaryInstance::FORMAT_FLAG_HAS_SCRIPT_CLASS; + } + } + } + f->store_32(format_flags); } ResourceUID::ID uid = ResourceSaver::get_resource_id_for_path(p_path, true); f->store_64(uid); + if (!script_class.is_empty()) { + save_unicode_string(f, script_class); + } + for (int i = 0; i < ResourceFormatSaverBinaryInstance::RESERVED_FIELDS; i++) { f->store_32(0); // reserved } @@ -2298,6 +2381,10 @@ Error ResourceFormatSaverBinaryInstance::set_uid(const String &p_path, ResourceU fw->store_32(flags); fw->store_64(p_uid); + if (flags & ResourceFormatSaverBinaryInstance::FORMAT_FLAG_HAS_SCRIPT_CLASS) { + save_ustring(fw, get_ustring(f)); + } + //rest of file uint8_t b = f->get_8(); while (!f->eof_reached()) { diff --git a/core/io/resource_format_binary.h b/core/io/resource_format_binary.h index 2e8988005f..add7cdf297 100644 --- a/core/io/resource_format_binary.h +++ b/core/io/resource_format_binary.h @@ -65,6 +65,7 @@ class ResourceLoaderBinary { bool using_named_scene_ids = false; bool using_uids = false; + String script_class; bool use_sub_threads = false; float *progress = nullptr; Vector<ExtResource> external_resources; @@ -92,7 +93,6 @@ class ResourceLoaderBinary { HashMap<String, Ref<Resource>> dependency_cache; public: - void set_local_path(const String &p_local_path); Ref<Resource> get_resource(); Error load(); void set_translation_remapped(bool p_remapped); @@ -100,6 +100,7 @@ public: void set_remaps(const HashMap<String, String> &p_remaps) { remaps = p_remaps; } void open(Ref<FileAccess> p_f, bool p_no_resources = false, bool p_keep_uuid_paths = false); String recognize(Ref<FileAccess> p_f); + String recognize_script_class(Ref<FileAccess> p_f); void get_dependencies(Ref<FileAccess> p_f, List<String> *p_dependencies, bool p_add_types); void get_classes_used(Ref<FileAccess> p_f, HashSet<StringName> *p_classes); @@ -113,6 +114,7 @@ public: 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; + virtual String get_resource_script_class(const String &p_path) const; virtual void get_classes_used(const String &p_path, HashSet<StringName> *r_classes); virtual ResourceUID::ID get_resource_uid(const String &p_path) const; virtual void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false); @@ -165,6 +167,7 @@ public: FORMAT_FLAG_NAMED_SCENE_IDS = 1, FORMAT_FLAG_UIDS = 2, FORMAT_FLAG_REAL_T_IS_DOUBLE = 4, + FORMAT_FLAG_HAS_SCRIPT_CLASS = 8, // Amount of reserved 32-bit fields in resource header RESERVED_FIELDS = 11 diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp index 946c31cf0d..7447119ab7 100644 --- a/core/io/resource_loader.cpp +++ b/core/io/resource_loader.cpp @@ -99,6 +99,12 @@ String ResourceFormatLoader::get_resource_type(const String &p_path) const { return ret; } +String ResourceFormatLoader::get_resource_script_class(const String &p_path) const { + String ret; + GDVIRTUAL_CALL(_get_resource_script_class, p_path, ret); + return ret; +} + ResourceUID::ID ResourceFormatLoader::get_resource_uid(const String &p_path) const { int64_t uid = ResourceUID::INVALID_ID; GDVIRTUAL_CALL(_get_resource_uid, p_path, uid); @@ -184,6 +190,7 @@ void ResourceFormatLoader::_bind_methods() { GDVIRTUAL_BIND(_recognize_path, "path", "type"); GDVIRTUAL_BIND(_handles_type, "type"); GDVIRTUAL_BIND(_get_resource_type, "path"); + GDVIRTUAL_BIND(_get_resource_script_class, "path"); GDVIRTUAL_BIND(_get_resource_uid, "path"); GDVIRTUAL_BIND(_get_dependencies, "path", "add_types"); GDVIRTUAL_BIND(_rename_dependencies, "path", "renames"); @@ -764,6 +771,19 @@ String ResourceLoader::get_resource_type(const String &p_path) { return ""; } +String ResourceLoader::get_resource_script_class(const String &p_path) { + String local_path = _validate_local_path(p_path); + + for (int i = 0; i < loader_count; i++) { + String result = loader[i]->get_resource_script_class(local_path); + if (!result.is_empty()) { + return result; + } + } + + return ""; +} + ResourceUID::ID ResourceLoader::get_resource_uid(const String &p_path) { String local_path = _validate_local_path(p_path); @@ -1011,13 +1031,6 @@ bool ResourceLoader::add_custom_resource_format_loader(String script_path) { return true; } -void ResourceLoader::remove_custom_resource_format_loader(String script_path) { - Ref<ResourceFormatLoader> custom_loader = _find_custom_resource_format_loader(script_path); - if (custom_loader.is_valid()) { - remove_resource_format_loader(custom_loader); - } -} - void ResourceLoader::set_create_missing_resources_if_class_unavailable(bool p_enable) { create_missing_resources_if_class_unavailable = p_enable; } diff --git a/core/io/resource_loader.h b/core/io/resource_loader.h index 41ba0dc6e6..eb8155e046 100644 --- a/core/io/resource_loader.h +++ b/core/io/resource_loader.h @@ -54,6 +54,7 @@ protected: GDVIRTUAL2RC(bool, _recognize_path, String, StringName) GDVIRTUAL1RC(bool, _handles_type, StringName) GDVIRTUAL1RC(String, _get_resource_type, String) + GDVIRTUAL1RC(String, _get_resource_script_class, String) GDVIRTUAL1RC(ResourceUID::ID, _get_resource_uid, String) GDVIRTUAL2RC(Vector<String>, _get_dependencies, String, bool) GDVIRTUAL1RC(Vector<String>, _get_classes_used, String) @@ -71,6 +72,7 @@ public: virtual bool handles_type(const String &p_type) const; virtual void get_classes_used(const String &p_path, HashSet<StringName> *r_classes); virtual String get_resource_type(const String &p_path) const; + virtual String get_resource_script_class(const String &p_path) const; virtual ResourceUID::ID get_resource_uid(const String &p_path) const; virtual void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false); virtual Error rename_dependencies(const String &p_path, const HashMap<String, String> &p_map); @@ -175,6 +177,7 @@ public: static void remove_resource_format_loader(Ref<ResourceFormatLoader> p_format_loader); static void get_classes_used(const String &p_path, HashSet<StringName> *r_classes); static String get_resource_type(const String &p_path); + static String get_resource_script_class(const String &p_path); static ResourceUID::ID get_resource_uid(const String &p_path); static void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false); static Error rename_dependencies(const String &p_path, const HashMap<String, String> &p_map); @@ -225,7 +228,6 @@ public: static ResourceLoaderImport import; static bool add_custom_resource_format_loader(String script_path); - static void remove_custom_resource_format_loader(String script_path); static void add_custom_loaders(); static void remove_custom_loaders(); diff --git a/core/io/resource_saver.cpp b/core/io/resource_saver.cpp index 9809b9a48f..b8201cc6b9 100644 --- a/core/io/resource_saver.cpp +++ b/core/io/resource_saver.cpp @@ -250,13 +250,6 @@ bool ResourceSaver::add_custom_resource_format_saver(String script_path) { return true; } -void ResourceSaver::remove_custom_resource_format_saver(String script_path) { - Ref<ResourceFormatSaver> custom_saver = _find_custom_resource_format_saver(script_path); - if (custom_saver.is_valid()) { - remove_resource_format_saver(custom_saver); - } -} - void ResourceSaver::add_custom_savers() { // Custom resource savers exploits global class names diff --git a/core/io/resource_saver.h b/core/io/resource_saver.h index 2043947963..9e88b2086b 100644 --- a/core/io/resource_saver.h +++ b/core/io/resource_saver.h @@ -101,7 +101,6 @@ public: static void set_get_resource_id_for_path(ResourceSaverGetResourceIDForPath p_callback); static bool add_custom_resource_format_saver(String script_path); - static void remove_custom_resource_format_saver(String script_path); static void add_custom_savers(); static void remove_custom_savers(); }; diff --git a/core/io/xml_parser.cpp b/core/io/xml_parser.cpp index 09836419be..5c0a017bfc 100644 --- a/core/io/xml_parser.cpp +++ b/core/io/xml_parser.cpp @@ -354,10 +354,10 @@ void XMLParser::_bind_methods() { ClassDB::bind_method(D_METHOD("get_node_offset"), &XMLParser::get_node_offset); ClassDB::bind_method(D_METHOD("get_attribute_count"), &XMLParser::get_attribute_count); ClassDB::bind_method(D_METHOD("get_attribute_name", "idx"), &XMLParser::get_attribute_name); - ClassDB::bind_method(D_METHOD("get_attribute_value", "idx"), (String(XMLParser::*)(int) const) & XMLParser::get_attribute_value); + ClassDB::bind_method(D_METHOD("get_attribute_value", "idx"), &XMLParser::get_attribute_value); ClassDB::bind_method(D_METHOD("has_attribute", "name"), &XMLParser::has_attribute); - ClassDB::bind_method(D_METHOD("get_named_attribute_value", "name"), (String(XMLParser::*)(const String &) const) & XMLParser::get_attribute_value); - ClassDB::bind_method(D_METHOD("get_named_attribute_value_safe", "name"), &XMLParser::get_attribute_value_safe); + ClassDB::bind_method(D_METHOD("get_named_attribute_value", "name"), &XMLParser::get_named_attribute_value); + ClassDB::bind_method(D_METHOD("get_named_attribute_value_safe", "name"), &XMLParser::get_named_attribute_value_safe); ClassDB::bind_method(D_METHOD("is_empty"), &XMLParser::is_empty); ClassDB::bind_method(D_METHOD("get_current_line"), &XMLParser::get_current_line); ClassDB::bind_method(D_METHOD("skip_section"), &XMLParser::skip_section); @@ -422,7 +422,7 @@ bool XMLParser::has_attribute(const String &p_name) const { return false; } -String XMLParser::get_attribute_value(const String &p_name) const { +String XMLParser::get_named_attribute_value(const String &p_name) const { int idx = -1; for (int i = 0; i < attributes.size(); i++) { if (attributes[i].name == p_name) { @@ -436,7 +436,7 @@ String XMLParser::get_attribute_value(const String &p_name) const { return attributes[idx].value; } -String XMLParser::get_attribute_value_safe(const String &p_name) const { +String XMLParser::get_named_attribute_value_safe(const String &p_name) const { int idx = -1; for (int i = 0; i < attributes.size(); i++) { if (attributes[i].name == p_name) { diff --git a/core/io/xml_parser.h b/core/io/xml_parser.h index b4ae5c93b6..b96478c7a5 100644 --- a/core/io/xml_parser.h +++ b/core/io/xml_parser.h @@ -109,8 +109,8 @@ public: String get_attribute_name(int p_idx) const; String get_attribute_value(int p_idx) const; bool has_attribute(const String &p_name) const; - String get_attribute_value(const String &p_name) const; - String get_attribute_value_safe(const String &p_name) const; // do not print error if doesn't exist + String get_named_attribute_value(const String &p_name) const; + String get_named_attribute_value_safe(const String &p_name) const; // do not print error if doesn't exist bool is_empty() const; int get_current_line() const; diff --git a/core/math/basis.cpp b/core/math/basis.cpp index 39e383fb49..234a4ddb79 100644 --- a/core/math/basis.cpp +++ b/core/math/basis.cpp @@ -36,23 +36,6 @@ #define cofac(row1, col1, row2, col2) \ (rows[row1][col1] * rows[row2][col2] - rows[row1][col2] * rows[row2][col1]) -void Basis::from_z(const Vector3 &p_z) { - if (Math::abs(p_z.z) > (real_t)Math_SQRT12) { - // choose p in y-z plane - real_t a = p_z[1] * p_z[1] + p_z[2] * p_z[2]; - real_t k = 1.0f / Math::sqrt(a); - rows[0] = Vector3(0, -p_z[2] * k, p_z[1] * k); - rows[1] = Vector3(a * k, -p_z[0] * rows[0][2], p_z[0] * rows[0][1]); - } else { - // choose p in x-y plane - real_t a = p_z.x * p_z.x + p_z.y * p_z.y; - real_t k = 1.0f / Math::sqrt(a); - rows[0] = Vector3(-p_z.y * k, p_z.x * k, 0); - rows[1] = Vector3(-p_z.z * rows[0].y, p_z.z * rows[0].x, a * k); - } - rows[2] = p_z; -} - void Basis::invert() { real_t co[3] = { cofac(1, 1, 2, 2), cofac(1, 2, 2, 0), cofac(1, 0, 2, 1) @@ -271,14 +254,6 @@ float Basis::get_uniform_scale() const { return (rows[0].length() + rows[1].length() + rows[2].length()) / 3.0f; } -void Basis::make_scale_uniform() { - float l = (rows[0].length() + rows[1].length() + rows[2].length()) / 3.0f; - for (int i = 0; i < 3; i++) { - rows[i].normalize(); - rows[i] *= l; - } -} - Basis Basis::scaled_local(const Vector3 &p_scale) const { return (*this) * Basis::from_scale(p_scale); } diff --git a/core/math/basis.h b/core/math/basis.h index b3197dbc84..bbc1d40469 100644 --- a/core/math/basis.h +++ b/core/math/basis.h @@ -56,8 +56,6 @@ struct _NO_DISCARD_ Basis { _FORCE_INLINE_ real_t determinant() const; - void from_z(const Vector3 &p_z); - void rotate(const Vector3 &p_axis, real_t p_angle); Basis rotated(const Vector3 &p_axis, real_t p_angle) const; @@ -101,8 +99,6 @@ struct _NO_DISCARD_ Basis { void scale_orthogonal(const Vector3 &p_scale); Basis scaled_orthogonal(const Vector3 &p_scale) const; - - void make_scale_uniform(); float get_uniform_scale() const; Vector3 get_scale() const; diff --git a/core/math/bvh.h b/core/math/bvh.h index 9de704834b..357d483375 100644 --- a/core/math/bvh.h +++ b/core/math/bvh.h @@ -444,9 +444,7 @@ private: params.result_array = nullptr; params.subindex_array = nullptr; - for (unsigned int n = 0; n < changed_items.size(); n++) { - const BVHHandle &h = changed_items[n]; - + for (const BVHHandle &h : changed_items) { // use the expanded aabb for pairing const BOUNDS &expanded_aabb = tree._pairs[h.id()].expanded_aabb; BVHABB_CLASS abb; @@ -465,9 +463,7 @@ private: params.result_count_overall = 0; // might not be needed tree.cull_aabb(params, false); - for (unsigned int i = 0; i < tree._cull_hits.size(); i++) { - uint32_t ref_id = tree._cull_hits[i]; - + for (const uint32_t ref_id : tree._cull_hits) { // don't collide against ourself if (ref_id == changed_item_ref_id) { continue; diff --git a/core/math/delaunay_3d.h b/core/math/delaunay_3d.h index 8ca38d571a..55923e0133 100644 --- a/core/math/delaunay_3d.h +++ b/core/math/delaunay_3d.h @@ -313,20 +313,20 @@ public: //remove simplex and continue simplex_list.erase(simplex->SE); - for (uint32_t k = 0; k < simplex->grid_positions.size(); k++) { - Vector3i p = simplex->grid_positions[k].pos; - acceleration_grid[p.x][p.y][p.z].erase(simplex->grid_positions[k].E); + for (const GridPos &gp : simplex->grid_positions) { + Vector3i p = gp.pos; + acceleration_grid[p.x][p.y][p.z].erase(gp.E); } memdelete(simplex); } E = N; } - for (uint32_t j = 0; j < triangles.size(); j++) { - if (triangles[j].bad) { + for (const Triangle &triangle : triangles) { + if (triangle.bad) { continue; } - Simplex *new_simplex = memnew(Simplex(triangles[j].triangle[0], triangles[j].triangle[1], triangles[j].triangle[2], i)); + Simplex *new_simplex = memnew(Simplex(triangle.triangle[0], triangle.triangle[1], triangle.triangle[2], i)); circum_sphere_compute(points, new_simplex); new_simplex->SE = simplex_list.push_back(new_simplex); { diff --git a/core/math/face3.cpp b/core/math/face3.cpp index e53bbf872b..1dff0ee4a6 100644 --- a/core/math/face3.cpp +++ b/core/math/face3.cpp @@ -120,36 +120,6 @@ bool Face3::is_degenerate() const { return (normal.length_squared() < (real_t)CMP_EPSILON2); } -Face3::Side Face3::get_side_of(const Face3 &p_face, ClockDirection p_clock_dir) const { - int over = 0, under = 0; - - Plane plane = get_plane(p_clock_dir); - - for (int i = 0; i < 3; i++) { - const Vector3 &v = p_face.vertex[i]; - - if (plane.has_point(v)) { //coplanar, don't bother - continue; - } - - if (plane.is_point_over(v)) { - over++; - } else { - under++; - } - } - - if (over > 0 && under == 0) { - return SIDE_OVER; - } else if (under > 0 && over == 0) { - return SIDE_UNDER; - } else if (under == 0 && over == 0) { - return SIDE_COPLANAR; - } else { - return SIDE_SPANNING; - } -} - Vector3 Face3::get_random_point_inside() const { real_t a = Math::random(0.0, 1.0); real_t b = Math::random(0.0, 1.0); @@ -164,20 +134,10 @@ Plane Face3::get_plane(ClockDirection p_dir) const { return Plane(vertex[0], vertex[1], vertex[2], p_dir); } -Vector3 Face3::get_median_point() const { - return (vertex[0] + vertex[1] + vertex[2]) / 3.0f; -} - real_t Face3::get_area() const { return vec3_cross(vertex[0] - vertex[1], vertex[0] - vertex[2]).length() * 0.5f; } -ClockDirection Face3::get_clock_dir() const { - Vector3 normal = vec3_cross(vertex[0] - vertex[1], vertex[0] - vertex[2]); - //printf("normal is %g,%g,%g x %g,%g,%g- wtfu is %g\n",tofloat(normal.x),tofloat(normal.y),tofloat(normal.z),tofloat(vertex[0].x),tofloat(vertex[0].y),tofloat(vertex[0].z),tofloat( normal.dot( vertex[0] ) ) ); - return (normal.dot(vertex[0]) >= 0) ? CLOCKWISE : COUNTERCLOCKWISE; -} - bool Face3::intersects_aabb(const AABB &p_aabb) const { /** TEST PLANE **/ if (!p_aabb.intersects_plane(get_plane())) { diff --git a/core/math/face3.h b/core/math/face3.h index 3d87de03dc..3dd47d0226 100644 --- a/core/math/face3.h +++ b/core/math/face3.h @@ -57,19 +57,14 @@ struct _NO_DISCARD_ Face3 { Plane get_plane(ClockDirection p_dir = CLOCKWISE) const; Vector3 get_random_point_inside() const; - Side get_side_of(const Face3 &p_face, ClockDirection p_clock_dir = CLOCKWISE) const; - bool is_degenerate() const; real_t get_area() const; - Vector3 get_median_point() const; Vector3 get_closest_point_to(const Vector3 &p_point) const; bool intersects_ray(const Vector3 &p_from, const Vector3 &p_dir, Vector3 *p_intersection = nullptr) const; bool intersects_segment(const Vector3 &p_from, const Vector3 &p_dir, Vector3 *p_intersection = nullptr) const; - ClockDirection get_clock_dir() const; ///< todo, test if this is returning the proper clockwisity - void get_support(const Vector3 &p_normal, const Transform3D &p_transform, Vector3 *p_vertices, int *p_count, int p_max) const; void project_range(const Vector3 &p_normal, const Transform3D &p_transform, real_t &r_min, real_t &r_max) const; diff --git a/core/math/geometry_2d.cpp b/core/math/geometry_2d.cpp index a0b76d31cb..74cb92539a 100644 --- a/core/math/geometry_2d.cpp +++ b/core/math/geometry_2d.cpp @@ -320,41 +320,6 @@ Vector<Vector<Point2>> Geometry2D::_polypath_offset(const Vector<Point2> &p_poly return polypaths; } -Vector<Point2i> Geometry2D::pack_rects(const Vector<Size2i> &p_sizes, const Size2i &p_atlas_size) { - Vector<stbrp_node> nodes; - nodes.resize(p_atlas_size.width); - - stbrp_context context; - stbrp_init_target(&context, p_atlas_size.width, p_atlas_size.height, nodes.ptrw(), p_atlas_size.width); - - Vector<stbrp_rect> rects; - rects.resize(p_sizes.size()); - - for (int i = 0; i < p_sizes.size(); i++) { - rects.write[i].id = 0; - rects.write[i].w = p_sizes[i].width; - rects.write[i].h = p_sizes[i].height; - rects.write[i].x = 0; - rects.write[i].y = 0; - rects.write[i].was_packed = 0; - } - - int res = stbrp_pack_rects(&context, rects.ptrw(), rects.size()); - if (res == 0) { //pack failed - return Vector<Point2i>(); - } - - Vector<Point2i> ret; - ret.resize(p_sizes.size()); - - for (int i = 0; i < p_sizes.size(); i++) { - Point2i r(rects[i].x, rects[i].y); - ret.write[i] = r; - } - - return ret; -} - Vector<Vector3i> Geometry2D::partial_pack_rects(const Vector<Vector2i> &p_sizes, const Size2i &p_atlas_size) { Vector<stbrp_node> nodes; nodes.resize(p_atlas_size.width); diff --git a/core/math/geometry_2d.h b/core/math/geometry_2d.h index b55aecf85e..0e5702e0af 100644 --- a/core/math/geometry_2d.h +++ b/core/math/geometry_2d.h @@ -464,7 +464,6 @@ public: static Vector<Vector<Vector2>> decompose_polygon_in_convex(Vector<Point2> polygon); static void make_atlas(const Vector<Size2i> &p_rects, Vector<Point2i> &r_result, Size2i &r_size); - static Vector<Point2i> pack_rects(const Vector<Size2i> &p_sizes, const Size2i &p_atlas_size); static Vector<Vector3i> partial_pack_rects(const Vector<Vector2i> &p_sizes, const Size2i &p_atlas_size); private: diff --git a/core/math/geometry_3d.cpp b/core/math/geometry_3d.cpp index c04fe7320d..4786110054 100644 --- a/core/math/geometry_3d.cpp +++ b/core/math/geometry_3d.cpp @@ -141,21 +141,19 @@ real_t Geometry3D::get_closest_distance_between_segments(const Vector3 &p_p0, co void Geometry3D::MeshData::optimize_vertices() { HashMap<int, int> vtx_remap; - for (uint32_t i = 0; i < faces.size(); i++) { - for (uint32_t j = 0; j < faces[i].indices.size(); j++) { - int idx = faces[i].indices[j]; - if (!vtx_remap.has(idx)) { + for (MeshData::Face &face : faces) { + for (int &index : face.indices) { + if (!vtx_remap.has(index)) { int ni = vtx_remap.size(); - vtx_remap[idx] = ni; + vtx_remap[index] = ni; } - - faces[i].indices[j] = vtx_remap[idx]; + index = vtx_remap[index]; } } - for (uint32_t i = 0; i < edges.size(); i++) { - int a = edges[i].vertex_a; - int b = edges[i].vertex_b; + for (MeshData::Edge edge : edges) { + int a = edge.vertex_a; + int b = edge.vertex_b; if (!vtx_remap.has(a)) { int ni = vtx_remap.size(); @@ -166,8 +164,8 @@ void Geometry3D::MeshData::optimize_vertices() { vtx_remap[b] = ni; } - edges[i].vertex_a = vtx_remap[a]; - edges[i].vertex_b = vtx_remap[b]; + edge.vertex_a = vtx_remap[a]; + edge.vertex_b = vtx_remap[b]; } LocalVector<Vector3> new_vertices; @@ -198,149 +196,6 @@ struct _FaceClassify { _FaceClassify() {} }; -static bool _connect_faces(_FaceClassify *p_faces, int len, int p_group) { - // Connect faces, error will occur if an edge is shared between more than 2 faces. - // Clear connections. - - bool error = false; - - for (int i = 0; i < len; i++) { - for (int j = 0; j < 3; j++) { - p_faces[i].links[j].clear(); - } - } - - for (int i = 0; i < len; i++) { - if (p_faces[i].group != p_group) { - continue; - } - for (int j = i + 1; j < len; j++) { - if (p_faces[j].group != p_group) { - continue; - } - - for (int k = 0; k < 3; k++) { - Vector3 vi1 = p_faces[i].face.vertex[k]; - Vector3 vi2 = p_faces[i].face.vertex[(k + 1) % 3]; - - for (int l = 0; l < 3; l++) { - Vector3 vj2 = p_faces[j].face.vertex[l]; - Vector3 vj1 = p_faces[j].face.vertex[(l + 1) % 3]; - - if (vi1.distance_to(vj1) < 0.00001f && - vi2.distance_to(vj2) < 0.00001f) { - if (p_faces[i].links[k].face != -1) { - ERR_PRINT("already linked\n"); - error = true; - break; - } - if (p_faces[j].links[l].face != -1) { - ERR_PRINT("already linked\n"); - error = true; - break; - } - - p_faces[i].links[k].face = j; - p_faces[i].links[k].edge = l; - p_faces[j].links[l].face = i; - p_faces[j].links[l].edge = k; - } - } - if (error) { - break; - } - } - if (error) { - break; - } - } - if (error) { - break; - } - } - - for (int i = 0; i < len; i++) { - p_faces[i].valid = true; - for (int j = 0; j < 3; j++) { - if (p_faces[i].links[j].face == -1) { - p_faces[i].valid = false; - } - } - } - return error; -} - -static bool _group_face(_FaceClassify *p_faces, int len, int p_index, int p_group) { - if (p_faces[p_index].group >= 0) { - return false; - } - - p_faces[p_index].group = p_group; - - for (int i = 0; i < 3; i++) { - ERR_FAIL_INDEX_V(p_faces[p_index].links[i].face, len, true); - _group_face(p_faces, len, p_faces[p_index].links[i].face, p_group); - } - - return true; -} - -Vector<Vector<Face3>> Geometry3D::separate_objects(Vector<Face3> p_array) { - Vector<Vector<Face3>> objects; - - int len = p_array.size(); - - const Face3 *arrayptr = p_array.ptr(); - - Vector<_FaceClassify> fc; - - fc.resize(len); - - _FaceClassify *_fcptr = fc.ptrw(); - - for (int i = 0; i < len; i++) { - _fcptr[i].face = arrayptr[i]; - } - - bool error = _connect_faces(_fcptr, len, -1); - - ERR_FAIL_COND_V_MSG(error, Vector<Vector<Face3>>(), "Invalid geometry."); - - // Group connected faces in separate objects. - - int group = 0; - for (int i = 0; i < len; i++) { - if (!_fcptr[i].valid) { - continue; - } - if (_group_face(_fcptr, len, i, group)) { - group++; - } - } - - // Group connected faces in separate objects. - - for (int i = 0; i < len; i++) { - _fcptr[i].face = arrayptr[i]; - } - - if (group >= 0) { - objects.resize(group); - Vector<Face3> *group_faces = objects.ptrw(); - - for (int i = 0; i < len; i++) { - if (!_fcptr[i].valid) { - continue; - } - if (_fcptr[i].group >= 0 && _fcptr[i].group < group) { - group_faces[_fcptr[i].group].push_back(_fcptr[i].face); - } - } - } - - return objects; -} - /*** GEOMETRY WRAPPER ***/ enum _CellFlags { @@ -816,10 +671,10 @@ Geometry3D::MeshData Geometry3D::build_convex_mesh(const Vector<Plane> &p_planes MeshData::Face face; // Add face indices. - for (uint32_t j = 0; j < vertices.size(); j++) { + for (const Vector3 &vertex : vertices) { int idx = -1; for (uint32_t k = 0; k < mesh.vertices.size(); k++) { - if (mesh.vertices[k].distance_to(vertices[j]) < 0.001f) { + if (mesh.vertices[k].distance_to(vertex) < 0.001f) { idx = k; break; } @@ -827,7 +682,7 @@ Geometry3D::MeshData Geometry3D::build_convex_mesh(const Vector<Plane> &p_planes if (idx == -1) { idx = mesh.vertices.size(); - mesh.vertices.push_back(vertices[j]); + mesh.vertices.push_back(vertex); } face.indices.push_back(idx); diff --git a/core/math/geometry_3d.h b/core/math/geometry_3d.h index 6759db5766..99c554fe05 100644 --- a/core/math/geometry_3d.h +++ b/core/math/geometry_3d.h @@ -532,8 +532,6 @@ public: return clipped; } - static Vector<Vector<Face3>> separate_objects(Vector<Face3> p_array); - // Create a "wrap" that encloses the given geometry. static Vector<Face3> wrap_geometry(Vector<Face3> p_array, real_t *p_error = nullptr); diff --git a/core/math/transform_2d.cpp b/core/math/transform_2d.cpp index 6a7ee32230..910995d717 100644 --- a/core/math/transform_2d.cpp +++ b/core/math/transform_2d.cpp @@ -221,12 +221,6 @@ Transform2D Transform2D::operator*(const Transform2D &p_transform) const { return t; } -Transform2D Transform2D::basis_scaled(const Size2 &p_scale) const { - Transform2D copy = *this; - copy.scale_basis(p_scale); - return copy; -} - Transform2D Transform2D::scaled(const Size2 &p_scale) const { // Equivalent to left multiplication Transform2D copy = *this; diff --git a/core/math/transform_2d.h b/core/math/transform_2d.h index 2a0917c63f..4a17a9db37 100644 --- a/core/math/transform_2d.h +++ b/core/math/transform_2d.h @@ -85,7 +85,6 @@ struct _NO_DISCARD_ Transform2D { _FORCE_INLINE_ const Vector2 &get_origin() const { return columns[2]; } _FORCE_INLINE_ void set_origin(const Vector2 &p_origin) { columns[2] = p_origin; } - Transform2D basis_scaled(const Size2 &p_scale) const; Transform2D scaled(const Size2 &p_scale) const; Transform2D scaled_local(const Size2 &p_scale) const; Transform2D translated(const Vector2 &p_offset) const; diff --git a/core/math/triangle_mesh.cpp b/core/math/triangle_mesh.cpp index 4b6921d38b..0da1b8c7ad 100644 --- a/core/math/triangle_mesh.cpp +++ b/core/math/triangle_mesh.cpp @@ -182,90 +182,6 @@ void TriangleMesh::create(const Vector<Vector3> &p_faces, const Vector<int32_t> valid = true; } -Vector3 TriangleMesh::get_area_normal(const AABB &p_aabb) const { - uint32_t *stack = (uint32_t *)alloca(sizeof(int) * max_depth); - - enum { - TEST_AABB_BIT = 0, - VISIT_LEFT_BIT = 1, - VISIT_RIGHT_BIT = 2, - VISIT_DONE_BIT = 3, - VISITED_BIT_SHIFT = 29, - NODE_IDX_MASK = (1 << VISITED_BIT_SHIFT) - 1, - VISITED_BIT_MASK = ~NODE_IDX_MASK, - - }; - - int n_count = 0; - Vector3 n; - - int level = 0; - - const Triangle *triangleptr = triangles.ptr(); - // const Vector3 *verticesr = vertices.ptr(); - const BVH *bvhptr = bvh.ptr(); - - int pos = bvh.size() - 1; - - stack[0] = pos; - while (true) { - uint32_t node = stack[level] & NODE_IDX_MASK; - const BVH &b = bvhptr[node]; - bool done = false; - - switch (stack[level] >> VISITED_BIT_SHIFT) { - case TEST_AABB_BIT: { - if (!b.aabb.intersects(p_aabb)) { - stack[level] = (VISIT_DONE_BIT << VISITED_BIT_SHIFT) | node; - } else { - if (b.face_index >= 0) { - const Triangle &s = triangleptr[b.face_index]; - n += s.normal; - n_count++; - - stack[level] = (VISIT_DONE_BIT << VISITED_BIT_SHIFT) | node; - - } else { - stack[level] = (VISIT_LEFT_BIT << VISITED_BIT_SHIFT) | node; - } - } - continue; - } - case VISIT_LEFT_BIT: { - stack[level] = (VISIT_RIGHT_BIT << VISITED_BIT_SHIFT) | node; - level++; - stack[level] = b.left | TEST_AABB_BIT; - continue; - } - case VISIT_RIGHT_BIT: { - stack[level] = (VISIT_DONE_BIT << VISITED_BIT_SHIFT) | node; - level++; - stack[level] = b.right | TEST_AABB_BIT; - continue; - } - case VISIT_DONE_BIT: { - if (level == 0) { - done = true; - break; - } else { - level--; - } - continue; - } - } - - if (done) { - break; - } - } - - if (n_count > 0) { - n /= n_count; - } - - return n; -} - bool TriangleMesh::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_point, Vector3 &r_normal, int32_t *r_surf_index) const { uint32_t *stack = (uint32_t *)alloca(sizeof(int) * max_depth); @@ -468,118 +384,6 @@ bool TriangleMesh::intersect_ray(const Vector3 &p_begin, const Vector3 &p_dir, V return inters; } -bool TriangleMesh::intersect_convex_shape(const Plane *p_planes, int p_plane_count, const Vector3 *p_points, int p_point_count) const { - uint32_t *stack = (uint32_t *)alloca(sizeof(int) * max_depth); - - //p_fully_inside = true; - - enum { - TEST_AABB_BIT = 0, - VISIT_LEFT_BIT = 1, - VISIT_RIGHT_BIT = 2, - VISIT_DONE_BIT = 3, - VISITED_BIT_SHIFT = 29, - NODE_IDX_MASK = (1 << VISITED_BIT_SHIFT) - 1, - VISITED_BIT_MASK = ~NODE_IDX_MASK, - - }; - - int level = 0; - - const Triangle *triangleptr = triangles.ptr(); - const Vector3 *vertexptr = vertices.ptr(); - const BVH *bvhptr = bvh.ptr(); - - int pos = bvh.size() - 1; - - stack[0] = pos; - while (true) { - uint32_t node = stack[level] & NODE_IDX_MASK; - const BVH &b = bvhptr[node]; - bool done = false; - - switch (stack[level] >> VISITED_BIT_SHIFT) { - case TEST_AABB_BIT: { - if (!b.aabb.intersects_convex_shape(p_planes, p_plane_count, p_points, p_point_count)) { - stack[level] = (VISIT_DONE_BIT << VISITED_BIT_SHIFT) | node; - } else { - if (b.face_index >= 0) { - const Triangle &s = triangleptr[b.face_index]; - - for (int j = 0; j < 3; ++j) { - const Vector3 &point = vertexptr[s.indices[j]]; - const Vector3 &next_point = vertexptr[s.indices[(j + 1) % 3]]; - Vector3 res; - bool over = true; - for (int i = 0; i < p_plane_count; i++) { - const Plane &p = p_planes[i]; - - if (p.intersects_segment(point, next_point, &res)) { - bool inisde = true; - for (int k = 0; k < p_plane_count; k++) { - if (k == i) { - continue; - } - const Plane &pp = p_planes[k]; - if (pp.is_point_over(res)) { - inisde = false; - break; - } - } - if (inisde) { - return true; - } - } - - if (p.is_point_over(point)) { - over = false; - break; - } - } - if (over) { - return true; - } - } - - stack[level] = (VISIT_DONE_BIT << VISITED_BIT_SHIFT) | node; - - } else { - stack[level] = (VISIT_LEFT_BIT << VISITED_BIT_SHIFT) | node; - } - } - continue; - } - case VISIT_LEFT_BIT: { - stack[level] = (VISIT_RIGHT_BIT << VISITED_BIT_SHIFT) | node; - level++; - stack[level] = b.left | TEST_AABB_BIT; - continue; - } - case VISIT_RIGHT_BIT: { - stack[level] = (VISIT_DONE_BIT << VISITED_BIT_SHIFT) | node; - level++; - stack[level] = b.right | TEST_AABB_BIT; - continue; - } - case VISIT_DONE_BIT: { - if (level == 0) { - done = true; - break; - } else { - level--; - } - continue; - } - } - - if (done) { - break; - } - } - - return false; -} - bool TriangleMesh::inside_convex_shape(const Plane *p_planes, int p_plane_count, const Vector3 *p_points, int p_point_count, Vector3 p_scale) const { uint32_t *stack = (uint32_t *)alloca(sizeof(int) * max_depth); diff --git a/core/math/triangle_mesh.h b/core/math/triangle_mesh.h index 728fd600d5..24fc12dda9 100644 --- a/core/math/triangle_mesh.h +++ b/core/math/triangle_mesh.h @@ -84,9 +84,7 @@ public: bool is_valid() const; bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_point, Vector3 &r_normal, int32_t *r_surf_index = nullptr) const; bool intersect_ray(const Vector3 &p_begin, const Vector3 &p_dir, Vector3 &r_point, Vector3 &r_normal, int32_t *r_surf_index = nullptr) const; - bool intersect_convex_shape(const Plane *p_planes, int p_plane_count, const Vector3 *p_points, int p_point_count) const; bool inside_convex_shape(const Plane *p_planes, int p_plane_count, const Vector3 *p_points, int p_point_count, Vector3 p_scale = Vector3(1, 1, 1)) const; - Vector3 get_area_normal(const AABB &p_aabb) const; Vector<Face3> get_faces() const; const Vector<Triangle> &get_triangles() const { return triangles; } diff --git a/core/object/script_language.cpp b/core/object/script_language.cpp index 66ef418e42..df5486512d 100644 --- a/core/object/script_language.cpp +++ b/core/object/script_language.cpp @@ -245,9 +245,12 @@ void ScriptServer::thread_exit() { } HashMap<StringName, ScriptServer::GlobalScriptClass> ScriptServer::global_classes; +HashMap<StringName, Vector<StringName>> ScriptServer::inheriters_cache; +bool ScriptServer::inheriters_cache_dirty = true; void ScriptServer::global_classes_clear() { global_classes.clear(); + inheriters_cache.clear(); } void ScriptServer::add_global_class(const StringName &p_class, const StringName &p_base, const StringName &p_language, const String &p_path) { @@ -257,16 +260,44 @@ void ScriptServer::add_global_class(const StringName &p_class, const StringName g.path = p_path; g.base = p_base; global_classes[p_class] = g; + inheriters_cache_dirty = true; } void ScriptServer::remove_global_class(const StringName &p_class) { global_classes.erase(p_class); + inheriters_cache_dirty = true; +} + +void ScriptServer::get_inheriters_list(const StringName &p_base_type, List<StringName> *r_classes) { + if (inheriters_cache_dirty) { + inheriters_cache.clear(); + for (const KeyValue<StringName, GlobalScriptClass> &K : global_classes) { + if (!inheriters_cache.has(K.value.base)) { + inheriters_cache[K.value.base] = Vector<StringName>(); + } + inheriters_cache[K.value.base].push_back(K.key); + } + for (KeyValue<StringName, Vector<StringName>> &K : inheriters_cache) { + K.value.sort_custom<StringName::AlphCompare>(); + } + inheriters_cache_dirty = false; + } + + if (!inheriters_cache.has(p_base_type)) { + return; + } + + const Vector<StringName> &v = inheriters_cache[p_base_type]; + for (int i = 0; i < v.size(); i++) { + r_classes->push_back(v[i]); + } } void ScriptServer::remove_global_class_by_path(const String &p_path) { for (const KeyValue<StringName, GlobalScriptClass> &kv : global_classes) { if (kv.value.path == p_path) { global_classes.erase(kv.key); + inheriters_cache_dirty = true; return; } } diff --git a/core/object/script_language.h b/core/object/script_language.h index 02d1880dc2..f82b58439f 100644 --- a/core/object/script_language.h +++ b/core/object/script_language.h @@ -56,10 +56,12 @@ class ScriptServer { struct GlobalScriptClass { StringName language; String path; - String base; + StringName base; }; static HashMap<StringName, GlobalScriptClass> global_classes; + static HashMap<StringName, Vector<StringName>> inheriters_cache; + static bool inheriters_cache_dirty; public: static ScriptEditRequestFunction edit_request_func; @@ -87,6 +89,7 @@ public: static StringName get_global_class_base(const String &p_class); static StringName get_global_class_native_base(const String &p_class); static void get_global_class_list(List<StringName> *r_global_classes); + static void get_inheriters_list(const StringName &p_base_type, List<StringName> *r_classes); static void save_global_classes(); static void init_languages(); @@ -120,7 +123,7 @@ public: virtual bool can_instantiate() const = 0; virtual Ref<Script> get_base_script() const = 0; //for script inheritance - + virtual StringName get_global_name() const = 0; virtual bool inherits_script(const Ref<Script> &p_script) const = 0; virtual StringName get_instance_base_type() const = 0; // this may not work in all scripts, will return empty if so diff --git a/core/object/script_language_extension.h b/core/object/script_language_extension.h index 912f2218c4..8e162a1b0f 100644 --- a/core/object/script_language_extension.h +++ b/core/object/script_language_extension.h @@ -53,6 +53,7 @@ protected: public: EXBIND0RC(bool, can_instantiate) EXBIND0RC(Ref<Script>, get_base_script) + EXBIND0RC(StringName, get_global_name) EXBIND1RC(bool, inherits_script, const Ref<Script> &) EXBIND0RC(StringName, get_instance_base_type) diff --git a/core/object/undo_redo.cpp b/core/object/undo_redo.cpp index e84933eb69..077929351e 100644 --- a/core/object/undo_redo.cpp +++ b/core/object/undo_redo.cpp @@ -99,8 +99,7 @@ void UndoRedo::create_action(const String &p_name, MergeMode p_mode) { } } - for (unsigned int i = 0; i < to_remove.size(); i++) { - List<Operation>::Element *E = to_remove[i]; + for (List<Operation>::Element *E : to_remove) { // Delete all object references E->get().delete_reference(); E->erase(); diff --git a/core/object/worker_thread_pool.cpp b/core/object/worker_thread_pool.cpp index fc907b2301..721c8d0a10 100644 --- a/core/object/worker_thread_pool.cpp +++ b/core/object/worker_thread_pool.cpp @@ -377,11 +377,11 @@ void WorkerThreadPool::wait_for_group_task_completion(GroupID p_group) { Group *group = *groupp; if (group->low_priority_native_tasks.size() > 0) { - for (uint32_t i = 0; i < group->low_priority_native_tasks.size(); i++) { - group->low_priority_native_tasks[i]->low_priority_thread->wait_to_finish(); - native_thread_allocator.free(group->low_priority_native_tasks[i]->low_priority_thread); + for (Task *task : group->low_priority_native_tasks) { + task->low_priority_thread->wait_to_finish(); + native_thread_allocator.free(task->low_priority_thread); task_mutex.lock(); - task_allocator.free(group->low_priority_native_tasks[i]); + task_allocator.free(task); task_mutex.unlock(); } @@ -449,8 +449,8 @@ void WorkerThreadPool::finish() { task_available_semaphore.post(); } - for (uint32_t i = 0; i < threads.size(); i++) { - threads[i].thread.wait_to_finish(); + for (ThreadData &data : threads) { + data.thread.wait_to_finish(); } threads.clear(); diff --git a/core/os/os.cpp b/core/os/os.cpp index c6fa8d307b..86469852e3 100644 --- a/core/os/os.cpp +++ b/core/os/os.cpp @@ -203,16 +203,26 @@ uint64_t OS::get_embedded_pck_offset() const { } // Helper function to ensure that a dir name/path will be valid on the OS -String OS::get_safe_dir_name(const String &p_dir_name, bool p_allow_dir_separator) const { +String OS::get_safe_dir_name(const String &p_dir_name, bool p_allow_paths) const { + String safe_dir_name = p_dir_name; Vector<String> invalid_chars = String(": * ? \" < > |").split(" "); - if (p_allow_dir_separator) { + if (p_allow_paths) { // Dir separators are allowed, but disallow ".." to avoid going up the filesystem invalid_chars.push_back(".."); + safe_dir_name = safe_dir_name.replace("\\", "/").strip_edges(); } else { invalid_chars.push_back("/"); + invalid_chars.push_back("\\"); + safe_dir_name = safe_dir_name.strip_edges(); + + // These directory names are invalid. + if (safe_dir_name == ".") { + safe_dir_name = "dot"; + } else if (safe_dir_name == "..") { + safe_dir_name = "twodots"; + } } - String safe_dir_name = p_dir_name.replace("\\", "/").strip_edges(); for (int i = 0; i < invalid_chars.size(); i++) { safe_dir_name = safe_dir_name.replace(invalid_chars[i], "-"); } diff --git a/core/os/os.h b/core/os/os.h index 4818e9281a..436a83eae3 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -238,7 +238,7 @@ public: virtual uint64_t get_embedded_pck_offset() const; - String get_safe_dir_name(const String &p_dir_name, bool p_allow_dir_separator = false) const; + String get_safe_dir_name(const String &p_dir_name, bool p_allow_paths = false) const; virtual String get_godot_dir_name() const; virtual String get_data_path() const; diff --git a/core/templates/local_vector.h b/core/templates/local_vector.h index 55761bb604..5311a94987 100644 --- a/core/templates/local_vector.h +++ b/core/templates/local_vector.h @@ -169,6 +169,70 @@ public: return data[p_index]; } + struct Iterator { + _FORCE_INLINE_ T &operator*() const { + return *elem_ptr; + } + _FORCE_INLINE_ T *operator->() const { return elem_ptr; } + _FORCE_INLINE_ Iterator &operator++() { + elem_ptr++; + return *this; + } + _FORCE_INLINE_ Iterator &operator--() { + elem_ptr--; + return *this; + } + + _FORCE_INLINE_ bool operator==(const Iterator &b) const { return elem_ptr == b.elem_ptr; } + _FORCE_INLINE_ bool operator!=(const Iterator &b) const { return elem_ptr != b.elem_ptr; } + + Iterator(T *p_ptr) { elem_ptr = p_ptr; } + Iterator() {} + Iterator(const Iterator &p_it) { elem_ptr = p_it.elem_ptr; } + + private: + T *elem_ptr = nullptr; + }; + + struct ConstIterator { + _FORCE_INLINE_ const T &operator*() const { + return *elem_ptr; + } + _FORCE_INLINE_ const T *operator->() const { return elem_ptr; } + _FORCE_INLINE_ ConstIterator &operator++() { + elem_ptr++; + return *this; + } + _FORCE_INLINE_ ConstIterator &operator--() { + elem_ptr--; + return *this; + } + + _FORCE_INLINE_ bool operator==(const ConstIterator &b) const { return elem_ptr == b.elem_ptr; } + _FORCE_INLINE_ bool operator!=(const ConstIterator &b) const { return elem_ptr != b.elem_ptr; } + + ConstIterator(const T *p_ptr) { elem_ptr = p_ptr; } + ConstIterator() {} + ConstIterator(const ConstIterator &p_it) { elem_ptr = p_it.elem_ptr; } + + private: + const T *elem_ptr = nullptr; + }; + + _FORCE_INLINE_ Iterator begin() { + return Iterator(data); + } + _FORCE_INLINE_ Iterator end() { + return Iterator(data + size()); + } + + _FORCE_INLINE_ ConstIterator begin() const { + return ConstIterator(ptr()); + } + _FORCE_INLINE_ ConstIterator end() const { + return ConstIterator(ptr() + size()); + } + void insert(U p_pos, T p_val) { ERR_FAIL_UNSIGNED_INDEX(p_pos, count + 1); if (p_pos == count) { diff --git a/core/variant/variant.h b/core/variant/variant.h index fff59c43a6..b9294de77d 100644 --- a/core/variant/variant.h +++ b/core/variant/variant.h @@ -655,6 +655,7 @@ public: static bool has_indexing(Variant::Type p_type); static Variant::Type get_indexed_element_type(Variant::Type p_type); + static uint32_t get_indexed_element_usage(Variant::Type p_type); typedef void (*ValidatedIndexedSetter)(Variant *base, int64_t index, const Variant *value, bool *oob); typedef void (*ValidatedIndexedGetter)(const Variant *base, int64_t index, Variant *value, bool *oob); diff --git a/core/variant/variant_setget.cpp b/core/variant/variant_setget.cpp index a74556d88f..30fb5d0e9f 100644 --- a/core/variant/variant_setget.cpp +++ b/core/variant/variant_setget.cpp @@ -151,8 +151,8 @@ void unregister_named_setters_getters() { bool Variant::has_member(Variant::Type p_type, const StringName &p_member) { ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, false); - for (uint32_t i = 0; i < variant_setters_getters_names[p_type].size(); i++) { - if (variant_setters_getters_names[p_type][i] == p_member) { + for (const StringName &member : variant_setters_getters_names[p_type]) { + if (member == p_member) { return true; } } @@ -172,8 +172,8 @@ Variant::Type Variant::get_member_type(Variant::Type p_type, const StringName &p } void Variant::get_member_list(Variant::Type p_type, List<StringName> *r_members) { - for (uint32_t i = 0; i < variant_setters_getters_names[p_type].size(); i++) { - r_members->push_back(variant_setters_getters_names[p_type][i]); + for (const StringName &member : variant_setters_getters_names[p_type]) { + r_members->push_back(member); } } @@ -389,6 +389,7 @@ Variant Variant::get_named(const StringName &p_member, bool &r_valid) const { v.write[index] = PtrToArg<m_elem_type>::convert(member); \ } \ static Variant::Type get_index_type() { return GetTypeInfo<m_elem_type>::VARIANT_TYPE; } \ + static uint32_t get_index_usage() { return GetTypeInfo<m_elem_type>::get_class_info().usage; } \ static uint64_t get_indexed_size(const Variant *base) { return VariantGetInternalPtr<m_base_type>::get_ptr(base)->size(); } \ }; @@ -460,6 +461,7 @@ Variant Variant::get_named(const StringName &p_member, bool &r_valid) const { v.write[index] = PtrToArg<m_elem_type>::convert(member); \ } \ static Variant::Type get_index_type() { return GetTypeInfo<m_elem_type>::VARIANT_TYPE; } \ + static uint32_t get_index_usage() { return GetTypeInfo<m_elem_type>::get_class_info().usage; } \ static uint64_t get_indexed_size(const Variant *base) { return VariantGetInternalPtr<m_base_type>::get_ptr(base)->size(); } \ }; @@ -515,6 +517,7 @@ Variant Variant::get_named(const StringName &p_member, bool &r_valid) const { v[index] = PtrToArg<m_elem_type>::convert(member); \ } \ static Variant::Type get_index_type() { return GetTypeInfo<m_elem_type>::VARIANT_TYPE; } \ + static uint32_t get_index_usage() { return GetTypeInfo<m_elem_type>::get_class_info().usage; } \ static uint64_t get_indexed_size(const Variant *base) { return m_max; } \ }; @@ -564,6 +567,7 @@ Variant Variant::get_named(const StringName &p_member, bool &r_valid) const { v m_accessor[index] = PtrToArg<m_elem_type>::convert(member); \ } \ static Variant::Type get_index_type() { return GetTypeInfo<m_elem_type>::VARIANT_TYPE; } \ + static uint32_t get_index_usage() { return GetTypeInfo<m_elem_type>::get_class_info().usage; } \ static uint64_t get_indexed_size(const Variant *base) { return m_max; } \ }; @@ -613,6 +617,7 @@ Variant Variant::get_named(const StringName &p_member, bool &r_valid) const { v.m_set(index, PtrToArg<m_elem_type>::convert(member)); \ } \ static Variant::Type get_index_type() { return GetTypeInfo<m_elem_type>::VARIANT_TYPE; } \ + static uint32_t get_index_usage() { return GetTypeInfo<m_elem_type>::get_class_info().usage; } \ static uint64_t get_indexed_size(const Variant *base) { return m_max; } \ }; @@ -683,6 +688,7 @@ struct VariantIndexedSetGet_Array { v.set(index, PtrToArg<Variant>::convert(member)); } static Variant::Type get_index_type() { return Variant::NIL; } + static uint32_t get_index_usage() { return PROPERTY_USAGE_NIL_IS_VARIANT; } static uint64_t get_indexed_size(const Variant *base) { return 0; } }; @@ -768,6 +774,7 @@ struct VariantIndexedSetGet_String { } } static Variant::Type get_index_type() { return Variant::STRING; } + static uint32_t get_index_usage() { return PROPERTY_USAGE_DEFAULT; } static uint64_t get_indexed_size(const Variant *base) { return VariantInternal::get_string(base)->length(); } }; @@ -812,6 +819,7 @@ struct VariantIndexedSetGet_String { v[index] = PtrToArg<Variant>::convert(member); \ } \ static Variant::Type get_index_type() { return Variant::NIL; } \ + static uint32_t get_index_usage() { return PROPERTY_USAGE_DEFAULT; } \ static uint64_t get_indexed_size(const Variant *base) { return VariantGetInternalPtr<m_base_type>::get_ptr(base)->size(); } \ }; @@ -852,7 +860,8 @@ struct VariantIndexedSetterGetterInfo { uint64_t (*get_indexed_size)(const Variant *base) = nullptr; - Variant::Type index_type; + Variant::Type index_type = Variant::NIL; + uint32_t index_usage = PROPERTY_USAGE_DEFAULT; bool valid = false; }; @@ -872,6 +881,7 @@ static void register_indexed_member(Variant::Type p_type) { sgi.ptr_getter = T::ptr_get; sgi.index_type = T::get_index_type(); + sgi.index_usage = T::get_index_usage(); sgi.get_indexed_size = T::get_indexed_size; sgi.valid = true; @@ -920,6 +930,11 @@ Variant::Type Variant::get_indexed_element_type(Variant::Type p_type) { return variant_indexed_setters_getters[p_type].index_type; } +uint32_t Variant::get_indexed_element_usage(Variant::Type p_type) { + ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, PROPERTY_USAGE_DEFAULT); + return variant_indexed_setters_getters[p_type].index_usage; +} + Variant::ValidatedIndexedSetter Variant::get_member_validated_indexed_setter(Variant::Type p_type) { ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, nullptr); return variant_indexed_setters_getters[p_type].validated_setter; |