Merge pull request #30622 from creikey/fix-path-caching

PackedScene resources are freed before they are saved
This commit is contained in:
Rémi Verschelde 2019-10-21 13:53:45 +02:00 committed by GitHub
commit 28eca3649d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 40 additions and 8 deletions

View File

@ -365,17 +365,38 @@ bool Resource::is_translation_remapped() const {
//helps keep IDs same number when loading/saving scenes. -1 clears ID and it Returns -1 when no id stored //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, int p_id) { void Resource::set_id_for_path(const String &p_path, int p_id) {
if (p_id == -1) { if (p_id == -1) {
id_for_path.erase(p_path); if (ResourceCache::path_cache_lock) {
ResourceCache::path_cache_lock->write_lock();
}
ResourceCache::resource_path_cache[p_path].erase(get_path());
if (ResourceCache::path_cache_lock) {
ResourceCache::path_cache_lock->write_unlock();
}
} else { } else {
id_for_path[p_path] = p_id; if (ResourceCache::path_cache_lock) {
ResourceCache::path_cache_lock->write_lock();
}
ResourceCache::resource_path_cache[p_path][get_path()] = p_id;
if (ResourceCache::path_cache_lock) {
ResourceCache::path_cache_lock->write_unlock();
}
} }
} }
int Resource::get_id_for_path(const String &p_path) const { int Resource::get_id_for_path(const String &p_path) const {
if (ResourceCache::path_cache_lock) {
if (id_for_path.has(p_path)) { ResourceCache::path_cache_lock->read_lock();
return id_for_path[p_path]; }
if (ResourceCache::resource_path_cache[p_path].has(get_path())) {
int result = ResourceCache::resource_path_cache[p_path][get_path()];
if (ResourceCache::path_cache_lock) {
ResourceCache::path_cache_lock->read_unlock();
}
return result;
} else { } else {
if (ResourceCache::path_cache_lock) {
ResourceCache::path_cache_lock->read_unlock();
}
return -1; return -1;
} }
} }
@ -430,12 +451,21 @@ Resource::~Resource() {
} }
HashMap<String, Resource *> ResourceCache::resources; HashMap<String, Resource *> ResourceCache::resources;
#ifdef TOOLS_ENABLED
HashMap<String, HashMap<String, int> > ResourceCache::resource_path_cache;
#endif
RWLock *ResourceCache::lock = NULL; RWLock *ResourceCache::lock = NULL;
#ifdef TOOLS_ENABLED
RWLock *ResourceCache::path_cache_lock = NULL;
#endif
void ResourceCache::setup() { void ResourceCache::setup() {
lock = RWLock::create(); lock = RWLock::create();
#ifdef TOOLS_ENABLED
path_cache_lock = RWLock::create();
#endif
} }
void ResourceCache::clear() { void ResourceCache::clear() {

View File

@ -84,9 +84,7 @@ protected:
void _set_path(const String &p_path); void _set_path(const String &p_path);
void _take_over_path(const String &p_path); void _take_over_path(const String &p_path);
#ifdef TOOLS_ENABLED
Map<String, int> id_for_path;
#endif
public: public:
static Node *(*_get_local_scene_func)(); //used by editor static Node *(*_get_local_scene_func)(); //used by editor
@ -152,6 +150,10 @@ class ResourceCache {
friend class ResourceLoader; //need the lock friend class ResourceLoader; //need the lock
static RWLock *lock; static RWLock *lock;
static HashMap<String, Resource *> resources; static HashMap<String, Resource *> resources;
#ifdef TOOLS_ENABLED
static HashMap<String, HashMap<String, int> > resource_path_cache; // each tscn has a set of resource paths and IDs
static RWLock *path_cache_lock;
#endif // TOOLS_ENABLED
friend void unregister_core_types(); friend void unregister_core_types();
static void clear(); static void clear();
friend void register_core_types(); friend void register_core_types();