diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/io/json.cpp | 33 | ||||
-rw-r--r-- | core/io/json.h | 9 | ||||
-rw-r--r-- | core/io/resource_format_binary.cpp | 93 | ||||
-rw-r--r-- | core/io/resource_format_binary.h | 4 | ||||
-rw-r--r-- | core/io/resource_loader.cpp | 20 | ||||
-rw-r--r-- | core/io/resource_loader.h | 3 | ||||
-rw-r--r-- | core/math/bvh.h | 8 | ||||
-rw-r--r-- | core/math/delaunay_3d.h | 12 | ||||
-rw-r--r-- | core/math/geometry_3d.cpp | 28 | ||||
-rw-r--r-- | core/object/script_language.cpp | 31 | ||||
-rw-r--r-- | core/object/script_language.h | 7 | ||||
-rw-r--r-- | core/object/script_language_extension.h | 1 | ||||
-rw-r--r-- | core/object/undo_redo.cpp | 3 | ||||
-rw-r--r-- | core/object/worker_thread_pool.cpp | 12 | ||||
-rw-r--r-- | core/os/os.cpp | 16 | ||||
-rw-r--r-- | core/os/os.h | 2 | ||||
-rw-r--r-- | core/templates/local_vector.h | 64 | ||||
-rw-r--r-- | core/variant/variant_setget.cpp | 8 |
18 files changed, 297 insertions, 57 deletions
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_format_binary.cpp b/core/io/resource_format_binary.cpp index 03beb25b03..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, }; @@ -1009,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 } @@ -1113,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; @@ -1295,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 @@ -1416,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)) { @@ -2033,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 } @@ -2294,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 9dd208e3cd..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; @@ -99,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); @@ -112,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); @@ -164,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 68b9f8b6f7..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); diff --git a/core/io/resource_loader.h b/core/io/resource_loader.h index e427a2f5fc..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); 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/geometry_3d.cpp b/core/math/geometry_3d.cpp index 51523ea296..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; @@ -673,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; } @@ -684,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/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_setget.cpp b/core/variant/variant_setget.cpp index ba37e15f31..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); } } |