Added proper resource preview cache invalidation, fixes #5342

This commit is contained in:
Juan Linietsky 2016-07-03 13:15:15 -03:00
parent a28bf56ef9
commit 6442dfb73b
7 changed files with 74 additions and 0 deletions

View File

@ -34,6 +34,7 @@
#include "editor_node.h" #include "editor_node.h"
#include "io/resource_saver.h" #include "io/resource_saver.h"
#include "editor_settings.h" #include "editor_settings.h"
#include "editor_resource_preview.h"
EditorFileSystem *EditorFileSystem::singleton=NULL; EditorFileSystem *EditorFileSystem::singleton=NULL;
@ -848,6 +849,7 @@ void EditorFileSystem::_scan_fs_changes(EditorFileSystemDirectory *p_dir,const S
continue; continue;
} }
if (_check_meta_sources(p_dir->files[i]->meta)) { if (_check_meta_sources(p_dir->files[i]->meta)) {
ItemAction ia; ItemAction ia;
ia.action=ItemAction::ACTION_FILE_SOURCES_CHANGED; ia.action=ItemAction::ACTION_FILE_SOURCES_CHANGED;
@ -858,6 +860,8 @@ void EditorFileSystem::_scan_fs_changes(EditorFileSystemDirectory *p_dir,const S
} else { } else {
p_dir->files[i]->meta.sources_changed=false; p_dir->files[i]->meta.sources_changed=false;
} }
EditorResourcePreview::get_singleton()->check_for_invalidation(p_dir->get_file_path(i));
} }
for(int i=0;i<p_dir->subdirs.size();i++) { for(int i=0;i<p_dir->subdirs.size();i++) {
@ -1328,6 +1332,7 @@ void EditorFileSystem::update_file(const String& p_file) {
fs->files[cpos]->modified_time=FileAccess::get_modified_time(p_file); fs->files[cpos]->modified_time=FileAccess::get_modified_time(p_file);
fs->files[cpos]->meta=_get_meta(p_file); fs->files[cpos]->meta=_get_meta(p_file);
EditorResourcePreview::get_singleton()->call_deferred("check_for_invalidation",p_file);
call_deferred("emit_signal","filesystem_changed"); //update later call_deferred("emit_signal","filesystem_changed"); //update later
} }
@ -1341,6 +1346,8 @@ void EditorFileSystem::_bind_methods() {
} }
EditorFileSystem::EditorFileSystem() { EditorFileSystem::EditorFileSystem() {

View File

@ -236,6 +236,7 @@ public:
EditorFileSystemDirectory *get_path(const String& p_path); EditorFileSystemDirectory *get_path(const String& p_path);
String get_file_type(const String& p_file) const; String get_file_type(const String& p_file) const;
EditorFileSystemDirectory* find_file(const String& p_file,int* r_index) const; EditorFileSystemDirectory* find_file(const String& p_file,int* r_index) const;
EditorFileSystem(); EditorFileSystem();
~EditorFileSystem(); ~EditorFileSystem();
}; };

View File

@ -2846,6 +2846,7 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
if (mt!=E->get()->get_last_modified_time()) { if (mt!=E->get()->get_last_modified_time()) {
E->get()->reload_from_file(); E->get()->reload_from_file();
} }
} }

View File

@ -66,16 +66,20 @@ void EditorResourcePreview::_preview_ready(const String& p_str,const Ref<Texture
String path = p_str; String path = p_str;
uint32_t hash=0; uint32_t hash=0;
uint64_t modified_time=0;
if (p_str.begins_with("ID:")) { if (p_str.begins_with("ID:")) {
hash=p_str.get_slicec(':',2).to_int(); hash=p_str.get_slicec(':',2).to_int();
path="ID:"+p_str.get_slicec(':',1); path="ID:"+p_str.get_slicec(':',1);
} else {
modified_time = FileAccess::get_modified_time(path);
} }
Item item; Item item;
item.order=order++; item.order=order++;
item.preview=p_texture; item.preview=p_texture;
item.last_hash=hash; item.last_hash=hash;
item.modified_time=modified_time;
cache[path]=item; cache[path]=item;
@ -263,6 +267,8 @@ void EditorResourcePreview::queue_edited_resource_preview(const Ref<Resource>& p
preview_mutex->lock(); preview_mutex->lock();
String path_id = "ID:"+itos(p_res->get_instance_ID()); String path_id = "ID:"+itos(p_res->get_instance_ID());
if (cache.has(path_id) && cache[path_id].last_hash==p_res->hash_edited_version()) { if (cache.has(path_id) && cache[path_id].last_hash==p_res->hash_edited_version()) {
cache[path_id].order=order++; cache[path_id].order=order++;
@ -272,6 +278,8 @@ void EditorResourcePreview::queue_edited_resource_preview(const Ref<Resource>& p
} }
cache.erase(path_id); //erase if exists, since it will be regen
//print_line("send to thread "+p_path); //print_line("send to thread "+p_path);
QueueItem item; QueueItem item;
item.function=p_receiver_func; item.function=p_receiver_func;
@ -322,6 +330,32 @@ EditorResourcePreview* EditorResourcePreview::get_singleton() {
void EditorResourcePreview::_bind_methods() { void EditorResourcePreview::_bind_methods() {
ObjectTypeDB::bind_method("_preview_ready",&EditorResourcePreview::_preview_ready); ObjectTypeDB::bind_method("_preview_ready",&EditorResourcePreview::_preview_ready);
ObjectTypeDB::bind_method(_MD("check_for_invalidation","path"),&EditorResourcePreview::check_for_invalidation);
ADD_SIGNAL(MethodInfo("preview_invalidated",PropertyInfo(Variant::STRING,"path")));
}
bool EditorResourcePreview::check_for_invalidation(const String& p_path) {
preview_mutex->lock();
bool call_invalidated=false;
if (cache.has(p_path)) {
uint64_t modified_time = FileAccess::get_modified_time(p_path);
if (modified_time!=cache[p_path].modified_time) {
cache.erase(p_path);
call_invalidated=true;
}
}
preview_mutex->unlock();
if (call_invalidated) {//do outside mutex
call_deferred("emit_signal","preview_invalidated",p_path);
}
} }
EditorResourcePreview::EditorResourcePreview() { EditorResourcePreview::EditorResourcePreview() {

View File

@ -93,6 +93,7 @@ class EditorResourcePreview : public Node {
Ref<Texture> preview; Ref<Texture> preview;
int order; int order;
uint32_t last_hash; uint32_t last_hash;
uint64_t modified_time;
}; };
int order; int order;
@ -106,6 +107,8 @@ class EditorResourcePreview : public Node {
void _thread(); void _thread();
Vector<Ref<EditorResourcePreviewGenerator> > preview_generators; Vector<Ref<EditorResourcePreviewGenerator> > preview_generators;
protected: protected:
static void _bind_methods(); static void _bind_methods();
@ -118,6 +121,7 @@ public:
void queue_edited_resource_preview(const Ref<Resource>& p_path, Object* p_receiver, const StringName& p_receiver_func, const Variant& p_userdata); void queue_edited_resource_preview(const Ref<Resource>& p_path, Object* p_receiver, const StringName& p_receiver_func, const Variant& p_userdata);
void add_preview_generator(const Ref<EditorResourcePreviewGenerator>& p_generator); void add_preview_generator(const Ref<EditorResourcePreviewGenerator>& p_generator);
bool check_for_invalidation(const String& p_path);
EditorResourcePreview(); EditorResourcePreview();
~EditorResourcePreview(); ~EditorResourcePreview();

View File

@ -189,6 +189,7 @@ void ScenesDock::_notification(int p_what) {
initialized=true; initialized=true;
EditorFileSystem::get_singleton()->connect("filesystem_changed",this,"_fs_changed"); EditorFileSystem::get_singleton()->connect("filesystem_changed",this,"_fs_changed");
EditorResourcePreview::get_singleton()->connect("preview_invalidated",this,"_preview_invalidated");
button_reload->set_icon( get_icon("Reload","EditorIcons")); button_reload->set_icon( get_icon("Reload","EditorIcons"));
button_favorite->set_icon( get_icon("Favorites","EditorIcons")); button_favorite->set_icon( get_icon("Favorites","EditorIcons"));
@ -663,6 +664,27 @@ void ScenesDock::_go_to_dir(const String& p_dir){
} }
void ScenesDock::_preview_invalidated(const String& p_path) {
if (p_path.get_base_dir()==path && search_box->get_text()==String() && file_list_vb->is_visible()) {
for(int i=0;i<files->get_item_count();i++) {
if (files->get_item_metadata(i)==p_path) {
//re-request preview
Array udata;
udata.resize(2);
udata[0]=i;
udata[1]=files->get_item_text(i);
EditorResourcePreview::get_singleton()->queue_resource_preview(p_path,this,"_thumbnail_done",udata);
break;
}
}
}
}
void ScenesDock::_fs_changed() { void ScenesDock::_fs_changed() {
button_hist_prev->set_disabled(history_pos==0); button_hist_prev->set_disabled(history_pos==0);
@ -1620,6 +1642,9 @@ void ScenesDock::_bind_methods() {
ObjectTypeDB::bind_method(_MD("drop_data_fw"), &ScenesDock::drop_data_fw); ObjectTypeDB::bind_method(_MD("drop_data_fw"), &ScenesDock::drop_data_fw);
ObjectTypeDB::bind_method(_MD("_files_list_rmb_select"),&ScenesDock::_files_list_rmb_select); ObjectTypeDB::bind_method(_MD("_files_list_rmb_select"),&ScenesDock::_files_list_rmb_select);
ObjectTypeDB::bind_method(_MD("_preview_invalidated"),&ScenesDock::_preview_invalidated);
ADD_SIGNAL(MethodInfo("instance")); ADD_SIGNAL(MethodInfo("instance"));
ADD_SIGNAL(MethodInfo("open")); ADD_SIGNAL(MethodInfo("open"));

View File

@ -168,6 +168,8 @@ class ScenesDock : public VBoxContainer {
bool can_drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from) const; bool can_drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from) const;
void drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from); void drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from);
void _preview_invalidated(const String& p_path);
protected: protected:
void _notification(int p_what); void _notification(int p_what);
static void _bind_methods(); static void _bind_methods();