void EditorResourcePreview::_thread() {

	while (!exit) {

		preview_sem->wait();
		preview_mutex->lock();

		if (queue.size()) {

			QueueItem item = queue.front()->get();
			queue.pop_front();

			if (cache.has(item.path)) {
				//already has it because someone loaded it, just let it know it's ready
				String path = item.path;
				if (item.resource.is_valid()) {
					path += ":" + itos(cache[item.path].last_hash); //keep last hash (see description of what this is in condition below)
				}

				_preview_ready(path, cache[item.path].preview, cache[item.path].small_preview, item.id, item.function, item.userdata);

				preview_mutex->unlock();
			} else {

				preview_mutex->unlock();

				Ref<ImageTexture> texture;
				Ref<ImageTexture> small_texture;

				int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size");
				thumbnail_size *= EDSCALE;

				if (item.resource.is_valid()) {

					_generate_preview(texture, small_texture, item, String());

					//adding hash to the end of path (should be ID:<objid>:<hash>) because of 5 argument limit to call_deferred
					_preview_ready(item.path + ":" + itos(item.resource->hash_edited_version()), texture, small_texture, item.id, item.function, item.userdata);

				} else {

					String temp_path = EditorSettings::get_singleton()->get_cache_dir();
					String cache_base = ProjectSettings::get_singleton()->globalize_path(item.path).md5_text();
					cache_base = temp_path.plus_file("resthumb-" + cache_base);

					//does not have it, try to load a cached thumbnail

					String file = cache_base + ".txt";
					FileAccess *f = FileAccess::open(file, FileAccess::READ);
					if (!f) {

						// No cache found, generate
						_generate_preview(texture, small_texture, item, cache_base);
					} else {

						uint64_t modtime = FileAccess::get_modified_time(item.path);
						int tsize = f->get_line().to_int64();
						bool has_small_texture = f->get_line().to_int();
						uint64_t last_modtime = f->get_line().to_int64();

						bool cache_valid = true;

						if (tsize != thumbnail_size) {

							cache_valid = false;
							memdelete(f);
						} else if (last_modtime != modtime) {

							String last_md5 = f->get_line();
							String md5 = FileAccess::get_md5(item.path);
							memdelete(f);

							if (last_md5 != md5) {

								cache_valid = false;

							} else {
								//update modified time

								f = FileAccess::open(file, FileAccess::WRITE);
								f->store_line(itos(modtime));
								f->store_line(itos(has_small_texture));
								f->store_line(md5);
								memdelete(f);
							}
						} else {
							memdelete(f);
						}

						if (cache_valid) {

							Ref<Image> img;
							img.instance();
							Ref<Image> small_img;
							small_img.instance();

							if (img->load(cache_base + ".png") != OK) {
								cache_valid = false;
							} else {

								texture.instance();
								texture->create_from_image(img, Texture::FLAG_FILTER);

								if (has_small_texture) {
									if (small_img->load(cache_base + "_small.png") != OK) {
										cache_valid = false;
									} else {
										small_texture.instance();
										small_texture->create_from_image(small_img, Texture::FLAG_FILTER);
									}
								}
							}
						}

						if (!cache_valid) {

							_generate_preview(texture, small_texture, item, cache_base);
						}
					}
					_preview_ready(item.path, texture, small_texture, item.id, item.function, item.userdata);
				}
			}

		} else {
			preview_mutex->unlock();
		}
	}
}
Example #2
0
void EditorResourcePreview::_thread() {

	//print_line("begin thread");
	while(!exit) {

		//print_line("wait for semaphore");
		preview_sem->wait();
		preview_mutex->lock();

		//print_line("blue team go");

		if (queue.size()) {



			QueueItem item = queue.front()->get();
			queue.pop_front();
			preview_mutex->unlock();

			Ref<Texture> texture;

			//print_line("pop from queue "+item.path);

			int thumbnail_size = EditorSettings::get_singleton()->get("file_dialog/thumbnail_size");
			thumbnail_size*=EDSCALE;

			if (cache.has(item.path)) {
				//already has it because someone loaded it, just let it know it's ready
				if (item.resource.is_valid()) {
					item.path+=":"+itos(cache[item.path].last_hash); //keep last hash (see description of what this is in condition below)
				}
				call_deferred("_preview_ready",item.path,cache[item.path].preview,item.id,item.function,item.userdata);

			} else if (item.resource.is_valid()){

				texture=_generate_preview(item,String());
				//adding hash to the end of path (should be ID:<objid>:<hash>) because of 5 argument limit to call_deferred
				call_deferred("_preview_ready",item.path+":"+itos(item.resource->hash_edited_version()),texture,item.id,item.function,item.userdata);

			} else {


				String temp_path=EditorSettings::get_singleton()->get_settings_path().plus_file("tmp");
				String cache_base = Globals::get_singleton()->globalize_path(item.path).md5_text();
				cache_base = temp_path.plus_file("resthumb-"+cache_base);

				//does not have it, try to load a cached thumbnail

				String file = cache_base+".txt";
				//print_line("cachetxt at "+file);
				FileAccess *f=FileAccess::open(file,FileAccess::READ);
				if (!f) {

					//print_line("generate because not cached");

					//generate
					texture=_generate_preview(item,cache_base);
				} else {

					uint64_t modtime = FileAccess::get_modified_time(item.path);
					int tsize = f->get_line().to_int64();
					uint64_t last_modtime = f->get_line().to_int64();

					bool cache_valid = true;

					if (tsize!=thumbnail_size) {
						cache_valid=false;
						memdelete(f);
					} else if (last_modtime!=modtime) {

						String last_md5 = f->get_line();
						String md5 = FileAccess::get_md5(item.path);
						memdelete(f);

						if (last_md5!=md5) {

							cache_valid=false;
						} else {
							//update modified time

							f=FileAccess::open(file,FileAccess::WRITE);
							f->store_line(itos(modtime));
							f->store_line(md5);
							memdelete(f);
						}
					} else {
						memdelete(f);
					}

					if (cache_valid) {

						texture = ResourceLoader::load(cache_base+".png","ImageTexture",true);
						if (!texture.is_valid()) {
							//well f**k
							cache_valid=false;
						}
					}

					if (!cache_valid) {

						texture=_generate_preview(item,cache_base);
					}

				}

				//print_line("notify of preview ready");
				call_deferred("_preview_ready",item.path,texture,item.id,item.function,item.userdata);

			}

		} else {
			preview_mutex->unlock();
		}

	}
}