diff options
Diffstat (limited to 'core/io')
-rw-r--r-- | core/io/dir_access.cpp | 4 | ||||
-rw-r--r-- | core/io/dir_access.h | 1 | ||||
-rw-r--r-- | core/io/file_access.cpp | 5 | ||||
-rw-r--r-- | core/io/marshalls.cpp | 47 | ||||
-rw-r--r-- | core/io/resource.cpp | 96 | ||||
-rw-r--r-- | core/io/resource.h | 4 | ||||
-rw-r--r-- | core/io/resource_format_binary.cpp | 10 | ||||
-rw-r--r-- | core/io/resource_loader.cpp | 51 | ||||
-rw-r--r-- | core/io/xml_parser.cpp | 46 | ||||
-rw-r--r-- | core/io/xml_parser.h | 9 |
10 files changed, 155 insertions, 118 deletions
diff --git a/core/io/dir_access.cpp b/core/io/dir_access.cpp index 433a7efb21..0a900078b7 100644 --- a/core/io/dir_access.cpp +++ b/core/io/dir_access.cpp @@ -181,6 +181,10 @@ Error DirAccess::make_dir_recursive(String p_dir) { return OK; } +DirAccess::AccessType DirAccess::get_access_type() const { + return _access_type; +} + String DirAccess::fix_path(String p_path) const { switch (_access_type) { case ACCESS_RESOURCES: { diff --git a/core/io/dir_access.h b/core/io/dir_access.h index 0125f011b5..22017efaa3 100644 --- a/core/io/dir_access.h +++ b/core/io/dir_access.h @@ -57,6 +57,7 @@ protected: String _get_root_path() const; String _get_root_string() const; + AccessType get_access_type() const; String fix_path(String p_path) const; template <class T> diff --git a/core/io/file_access.cpp b/core/io/file_access.cpp index 7d8da1b11c..da25f23917 100644 --- a/core/io/file_access.cpp +++ b/core/io/file_access.cpp @@ -388,9 +388,7 @@ String FileAccess::get_as_utf8_string() const { w[len] = 0; String s; - if (s.parse_utf8((const char *)w)) { - return String(); - } + s.parse_utf8((const char *)w); return s; } @@ -516,7 +514,6 @@ String FileAccess::get_pascal_string() { String ret; ret.parse_utf8(cs.ptr()); - return ret; } diff --git a/core/io/marshalls.cpp b/core/io/marshalls.cpp index bb9606c94b..8ee19f274e 100644 --- a/core/io/marshalls.cpp +++ b/core/io/marshalls.cpp @@ -78,7 +78,7 @@ static Error _decode_string(const uint8_t *&buf, int &len, int *r_len, String &r ERR_FAIL_COND_V(strlen < 0 || strlen + pad > len, ERR_FILE_EOF); String str; - ERR_FAIL_COND_V(str.parse_utf8((const char *)buf, strlen), ERR_INVALID_DATA); + ERR_FAIL_COND_V(str.parse_utf8((const char *)buf, strlen) != OK, ERR_INVALID_DATA); r_string = str; // Add padding @@ -532,7 +532,13 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int } break; case Variant::RID: { - r_variant = RID(); + ERR_FAIL_COND_V(len < 8, ERR_INVALID_DATA); + uint64_t id = decode_uint64(buf); + if (r_len) { + (*r_len) += 8; + } + + r_variant = RID::from_uint64(id); } break; case Variant::OBJECT: { if (type & ENCODE_FLAG_OBJECT_AS_ID) { @@ -614,9 +620,20 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int r_variant = Callable(); } break; case Variant::SIGNAL: { - r_variant = Signal(); - } break; + String name; + Error err = _decode_string(buf, len, r_len, name); + if (err) { + return err; + } + ERR_FAIL_COND_V(len < 8, ERR_INVALID_DATA); + ObjectID id = ObjectID(decode_uint64(buf)); + if (r_len) { + (*r_len) += 8; + } + + r_variant = Signal(id, StringName(name)); + } break; case Variant::DICTIONARY: { ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA); int32_t count = decode_uint32(buf); @@ -1352,10 +1369,12 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo } break; case Variant::RID: { - } break; - case Variant::CALLABLE: { - } break; - case Variant::SIGNAL: { + RID rid = p_variant; + + if (buf) { + encode_uint64(rid.get_id(), buf); + } + r_len += 8; } break; case Variant::OBJECT: { if (p_full_objects) { @@ -1419,6 +1438,18 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo } } break; + case Variant::CALLABLE: { + } break; + case Variant::SIGNAL: { + Signal signal = p_variant; + + _encode_string(signal.get_name(), buf, r_len); + + if (buf) { + encode_uint64(signal.get_object_id(), buf); + } + r_len += 8; + } break; case Variant::DICTIONARY: { Dictionary d = p_variant; diff --git a/core/io/resource.cpp b/core/io/resource.cpp index ed7228d0b9..fec5ca5c7b 100644 --- a/core/io/resource.cpp +++ b/core/io/resource.cpp @@ -52,41 +52,36 @@ void Resource::set_path(const String &p_path, bool p_take_over) { return; } + if (p_path.is_empty()) { + p_take_over = false; // Can't take over an empty path + } + + ResourceCache::lock.lock(); + if (!path_cache.is_empty()) { - ResourceCache::lock.write_lock(); ResourceCache::resources.erase(path_cache); - ResourceCache::lock.write_unlock(); } path_cache = ""; - ResourceCache::lock.read_lock(); - bool has_path = ResourceCache::resources.has(p_path); - ResourceCache::lock.read_unlock(); + Ref<Resource> existing = ResourceCache::get_ref(p_path); - if (has_path) { + if (existing.is_valid()) { if (p_take_over) { - ResourceCache::lock.write_lock(); - Resource **res = ResourceCache::resources.getptr(p_path); - if (res) { - (*res)->set_name(""); - } - ResourceCache::lock.write_unlock(); + existing->path_cache = String(); + ResourceCache::resources.erase(p_path); } else { - ResourceCache::lock.read_lock(); - bool exists = ResourceCache::resources.has(p_path); - ResourceCache::lock.read_unlock(); - - ERR_FAIL_COND_MSG(exists, "Another resource is loaded from path '" + p_path + "' (possible cyclic resource inclusion)."); + ResourceCache::lock.unlock(); + ERR_FAIL_MSG("Another resource is loaded from path '" + p_path + "' (possible cyclic resource inclusion)."); } } + path_cache = p_path; if (!path_cache.is_empty()) { - ResourceCache::lock.write_lock(); ResourceCache::resources[path_cache] = this; - ResourceCache::lock.write_unlock(); } + ResourceCache::lock.unlock(); _resource_path_changed(); } @@ -380,7 +375,7 @@ void Resource::set_as_translation_remapped(bool p_remapped) { return; } - ResourceCache::lock.write_lock(); + ResourceCache::lock.lock(); if (p_remapped) { ResourceLoader::remapped_list.add(&remapped_list); @@ -388,7 +383,7 @@ void Resource::set_as_translation_remapped(bool p_remapped) { ResourceLoader::remapped_list.remove(&remapped_list); } - ResourceCache::lock.write_unlock(); + ResourceCache::lock.unlock(); } bool Resource::is_translation_remapped() const { @@ -455,9 +450,9 @@ Resource::Resource() : Resource::~Resource() { if (!path_cache.is_empty()) { - ResourceCache::lock.write_lock(); + ResourceCache::lock.lock(); ResourceCache::resources.erase(path_cache); - ResourceCache::lock.write_unlock(); + ResourceCache::lock.unlock(); } if (owners.size()) { WARN_PRINT("Resource is still owned."); @@ -469,7 +464,7 @@ HashMap<String, Resource *> ResourceCache::resources; HashMap<String, HashMap<String, String>> ResourceCache::resource_path_cache; #endif -RWLock ResourceCache::lock; +Mutex ResourceCache::lock; #ifdef TOOLS_ENABLED RWLock ResourceCache::path_cache_lock; #endif @@ -491,46 +486,67 @@ void ResourceCache::reload_externals() { } bool ResourceCache::has(const String &p_path) { - lock.read_lock(); - bool b = resources.has(p_path); - lock.read_unlock(); + lock.lock(); + + Resource **res = resources.getptr(p_path); - return b; + if (res && (*res)->reference_get_count() == 0) { + // This resource is in the process of being deleted, ignore its existence. + (*res)->path_cache = String(); + resources.erase(p_path); + res = nullptr; + } + + lock.unlock(); + + if (!res) { + return false; + } + + return true; } -Resource *ResourceCache::get(const String &p_path) { - lock.read_lock(); +Ref<Resource> ResourceCache::get_ref(const String &p_path) { + Ref<Resource> ref; + lock.lock(); Resource **res = resources.getptr(p_path); - lock.read_unlock(); + if (res) { + ref = Ref<Resource>(*res); + } - if (!res) { - return nullptr; + if (res && !ref.is_valid()) { + // This resource is in the process of being deleted, ignore its existence + (*res)->path_cache = String(); + resources.erase(p_path); + res = nullptr; } - return *res; + lock.unlock(); + + return ref; } void ResourceCache::get_cached_resources(List<Ref<Resource>> *p_resources) { - lock.read_lock(); + lock.lock(); for (KeyValue<String, Resource *> &E : resources) { p_resources->push_back(Ref<Resource>(E.value)); } - lock.read_unlock(); + lock.unlock(); } int ResourceCache::get_cached_resource_count() { - lock.read_lock(); + lock.lock(); int rc = resources.size(); - lock.read_unlock(); + lock.unlock(); return rc; } void ResourceCache::dump(const char *p_file, bool p_short) { #ifdef DEBUG_ENABLED - lock.read_lock(); + lock.lock(); HashMap<String, int> type_count; @@ -562,7 +578,7 @@ void ResourceCache::dump(const char *p_file, bool p_short) { } } - lock.read_unlock(); + lock.unlock(); #else WARN_PRINT("ResourceCache::dump only with in debug builds."); #endif diff --git a/core/io/resource.h b/core/io/resource.h index a45bc6e1e4..a2cde87990 100644 --- a/core/io/resource.h +++ b/core/io/resource.h @@ -153,7 +153,7 @@ public: class ResourceCache { friend class Resource; friend class ResourceLoader; //need the lock - static RWLock lock; + static Mutex lock; static HashMap<String, Resource *> resources; #ifdef TOOLS_ENABLED static HashMap<String, HashMap<String, String>> resource_path_cache; // Each tscn has a set of resource paths and IDs. @@ -166,7 +166,7 @@ class ResourceCache { public: static void reload_externals(); static bool has(const String &p_path); - static Resource *get(const String &p_path); + static Ref<Resource> get_ref(const String &p_path); static void dump(const char *p_file = nullptr, bool p_short = false); static void get_cached_resources(List<Ref<Resource>> *p_resources); static int get_cached_resource_count(); diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp index 2469e1a4be..b1c50e829c 100644 --- a/core/io/resource_format_binary.cpp +++ b/core/io/resource_format_binary.cpp @@ -693,7 +693,7 @@ Error ResourceLoaderBinary::load() { } if (cache_mode == ResourceFormatLoader::CACHE_MODE_REUSE && ResourceCache::has(path)) { - Ref<Resource> cached = ResourceCache::get(path); + Ref<Resource> cached = ResourceCache::get_ref(path); if (cached.is_valid()) { //already loaded, don't do anything error = OK; @@ -717,10 +717,10 @@ Error ResourceLoaderBinary::load() { if (cache_mode == ResourceFormatLoader::CACHE_MODE_REPLACE && ResourceCache::has(path)) { //use the existing one - Resource *r = ResourceCache::get(path); - if (r->get_class() == t) { - r->reset_state(); - res = Ref<Resource>(r); + Ref<Resource> cached = ResourceCache::get_ref(path); + if (cached->get_class() == t) { + cached->reset_state(); + res = cached; } } diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp index fb21db1a19..2cd455475c 100644 --- a/core/io/resource_loader.cpp +++ b/core/io/resource_loader.cpp @@ -335,23 +335,15 @@ Error ResourceLoader::load_threaded_request(const String &p_path, const String & thread_load_mutex->unlock(); ERR_FAIL_V_MSG(ERR_INVALID_PARAMETER, "Attempted to load a resource already being loaded from this thread, cyclic reference?"); } - //lock first if possible - ResourceCache::lock.read_lock(); - - //get ptr - Resource **rptr = ResourceCache::resources.getptr(local_path); - - if (rptr) { - Ref<Resource> res(*rptr); - //it is possible this resource was just freed in a thread. If so, this referencing will not work and resource is considered not cached - if (res.is_valid()) { - //referencing is fine - load_task.resource = res; - load_task.status = THREAD_LOAD_LOADED; - load_task.progress = 1.0; - } + + Ref<Resource> existing = ResourceCache::get_ref(local_path); + + if (existing.is_valid()) { + //referencing is fine + load_task.resource = existing; + load_task.status = THREAD_LOAD_LOADED; + load_task.progress = 1.0; } - ResourceCache::lock.read_unlock(); } if (!p_source_resource.is_empty()) { @@ -530,27 +522,18 @@ Ref<Resource> ResourceLoader::load(const String &p_path, const String &p_type_hi } //Is it cached? - ResourceCache::lock.read_lock(); - - Resource **rptr = ResourceCache::resources.getptr(local_path); - if (rptr) { - Ref<Resource> res(*rptr); + Ref<Resource> existing = ResourceCache::get_ref(local_path); - //it is possible this resource was just freed in a thread. If so, this referencing will not work and resource is considered not cached - if (res.is_valid()) { - ResourceCache::lock.read_unlock(); - thread_load_mutex->unlock(); - - if (r_error) { - *r_error = OK; - } + if (existing.is_valid()) { + thread_load_mutex->unlock(); - return res; //use cached + if (r_error) { + *r_error = OK; } - } - ResourceCache::lock.read_unlock(); + return existing; //use cached + } //load using task (but this thread) ThreadLoadTask load_task; @@ -867,7 +850,7 @@ String ResourceLoader::path_remap(const String &p_path) { } void ResourceLoader::reload_translation_remaps() { - ResourceCache::lock.read_lock(); + ResourceCache::lock.lock(); List<Resource *> to_reload; SelfList<Resource> *E = remapped_list.first(); @@ -877,7 +860,7 @@ void ResourceLoader::reload_translation_remaps() { E = E->next(); } - ResourceCache::lock.read_unlock(); + ResourceCache::lock.unlock(); //now just make sure to not delete any of these resources while changing locale.. while (to_reload.front()) { diff --git a/core/io/xml_parser.cpp b/core/io/xml_parser.cpp index 7b43193f47..154b55f5e7 100644 --- a/core/io/xml_parser.cpp +++ b/core/io/xml_parser.cpp @@ -72,11 +72,11 @@ void XMLParser::_parse_closing_xml_element() { node_empty = false; attributes.clear(); - ++P; + next_char(); const char *pBeginClose = P; while (*P && *P != '>') { - ++P; + next_char(); } node_name = String::utf8(pBeginClose, (int)(P - pBeginClose)); @@ -85,7 +85,7 @@ void XMLParser::_parse_closing_xml_element() { #endif if (*P) { - ++P; + next_char(); } } @@ -95,12 +95,12 @@ void XMLParser::_ignore_definition() { char *F = P; // move until end marked with '>' reached while (*P && *P != '>') { - ++P; + next_char(); } node_name.parse_utf8(F, P - F); if (*P) { - ++P; + next_char(); } } @@ -114,7 +114,7 @@ bool XMLParser::_parse_cdata() { // skip '<![CDATA[' int count = 0; while (*P && count < 8) { - ++P; + next_char(); ++count; } @@ -134,7 +134,7 @@ bool XMLParser::_parse_cdata() { cDataEnd = P - 2; } - ++P; + next_char(); } if (cDataEnd) { @@ -180,7 +180,7 @@ void XMLParser::_parse_comment() { } else if (*P == '<') { ++count; } - ++P; + next_char(); } if (count) { @@ -206,7 +206,7 @@ void XMLParser::_parse_opening_xml_element() { // find end of element while (*P && *P != '>' && !_is_white_space(*P)) { - ++P; + next_char(); } const char *endName = P; @@ -214,7 +214,7 @@ void XMLParser::_parse_opening_xml_element() { // find attributes while (*P && *P != '>') { if (_is_white_space(*P)) { - ++P; + next_char(); } else { if (*P != '/') { // we've got an attribute @@ -223,7 +223,7 @@ void XMLParser::_parse_opening_xml_element() { const char *attributeNameBegin = P; while (*P && !_is_white_space(*P) && *P != '=') { - ++P; + next_char(); } if (!*P) { @@ -231,12 +231,12 @@ void XMLParser::_parse_opening_xml_element() { } const char *attributeNameEnd = P; - ++P; + next_char(); // read the attribute value // check for quotes and single quotes, thx to murphy while ((*P != '\"') && (*P != '\'') && *P) { - ++P; + next_char(); } if (!*P) { // malformatted xml file @@ -245,16 +245,16 @@ void XMLParser::_parse_opening_xml_element() { const char attributeQuoteChar = *P; - ++P; + next_char(); const char *attributeValueBegin = P; while (*P != attributeQuoteChar && *P) { - ++P; + next_char(); } const char *attributeValueEnd = P; if (*P) { - ++P; + next_char(); } Attribute attr; @@ -268,7 +268,7 @@ void XMLParser::_parse_opening_xml_element() { attributes.push_back(attr); } else { // tag is closed directly - ++P; + next_char(); node_empty = true; break; } @@ -288,7 +288,7 @@ void XMLParser::_parse_opening_xml_element() { #endif if (*P) { - ++P; + next_char(); } } @@ -298,7 +298,7 @@ void XMLParser::_parse_current_node() { // more forward until '<' found while (*P != '<' && *P) { - ++P; + next_char(); } if (P - start > 0) { @@ -312,7 +312,7 @@ void XMLParser::_parse_current_node() { return; } - ++P; + next_char(); // based on current token, parse and report next element switch (*P) { @@ -487,6 +487,7 @@ Error XMLParser::open(const String &p_path) { file->get_buffer((uint8_t *)data, length); data[length] = 0; P = data; + current_line = 0; return OK; } @@ -523,10 +524,7 @@ void XMLParser::close() { } int XMLParser::get_current_line() const { - return 0; -} - -XMLParser::XMLParser() { + return current_line; } XMLParser::~XMLParser() { diff --git a/core/io/xml_parser.h b/core/io/xml_parser.h index da14ee8eae..aea252ddc7 100644 --- a/core/io/xml_parser.h +++ b/core/io/xml_parser.h @@ -68,6 +68,7 @@ private: char *data = nullptr; char *P = nullptr; uint64_t length = 0; + uint64_t current_line = 0; String node_name; bool node_empty = false; NodeType node_type = NODE_NONE; @@ -88,6 +89,13 @@ private: void _parse_opening_xml_element(); void _parse_current_node(); + _FORCE_INLINE_ void next_char() { + if (*P == '\n') { + current_line++; + } + P++; + } + static void _bind_methods(); public: @@ -113,7 +121,6 @@ public: void close(); - XMLParser(); ~XMLParser(); }; |