From 0960f46b0bac8b721cd5863b1b7430f7a2e767e4 Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Thu, 21 Feb 2019 20:49:42 -0300 Subject: [PATCH] Implement a cleaner (and better) way to save imagedata from ImageTexture, fixes #18801 --- core/io/resource_format_binary.cpp | 27 +++++++++++++++++++++-- core/io/resource_format_binary.h | 8 +++++++ core/object.h | 1 + editor/editor_node.cpp | 2 -- scene/resources/resource_format_text.cpp | 28 ++++++++++++++++++++++-- scene/resources/resource_format_text.h | 9 ++++++++ scene/resources/texture.cpp | 23 +++++-------------- scene/resources/texture.h | 6 +---- 8 files changed, 76 insertions(+), 28 deletions(-) diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp index 77e3efb3a0a6..d2c656b8ebd4 100644 --- a/core/io/resource_format_binary.cpp +++ b/core/io/resource_format_binary.cpp @@ -1666,7 +1666,20 @@ void ResourceFormatSaverBinaryInstance::_find_resources(const Variant &p_variant if (E->get().usage & PROPERTY_USAGE_STORAGE) { - _find_resources(res->get(E->get().name)); + Variant value = res->get(E->get().name); + if (E->get().usage & PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT) { + RES sres = value; + if (sres.is_valid()) { + NonPersistentKey npk; + npk.base = res; + npk.property = E->get().name; + non_persistent_map[npk] = sres; + resource_set.insert(sres); + saved_resources.push_back(sres); + } + } else { + _find_resources(value); + } } } @@ -1810,7 +1823,17 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const RES &p if ((F->get().usage & PROPERTY_USAGE_STORAGE)) { Property p; p.name_idx = get_string_index(F->get().name); - p.value = E->get()->get(F->get().name); + + if (F->get().usage & PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT) { + NonPersistentKey npk; + npk.base = E->get(); + npk.property = F->get().name; + if (non_persistent_map.has(npk)) { + p.value = non_persistent_map[npk]; + } + } else { + p.value = E->get()->get(F->get().name); + } Variant default_value = ClassDB::class_get_default_property_value(E->get()->get_class(), F->get().name); diff --git a/core/io/resource_format_binary.h b/core/io/resource_format_binary.h index 8f2c48e74572..c3c477b805f7 100644 --- a/core/io/resource_format_binary.h +++ b/core/io/resource_format_binary.h @@ -123,6 +123,14 @@ class ResourceFormatSaverBinaryInstance { FileAccess *f; String magic; Set resource_set; + + struct NonPersistentKey { //for resource properties generated on the fly + RES base; + StringName property; + bool operator<(const NonPersistentKey &p_key) const { return base == p_key.base ? property < p_key.property : base < p_key.base; } + }; + + Map non_persistent_map; Map string_map; Vector strings; diff --git a/core/object.h b/core/object.h index 9a5217e3deb3..e8a6178052ce 100644 --- a/core/object.h +++ b/core/object.h @@ -119,6 +119,7 @@ enum PropertyUsageFlags { PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE = 1 << 21, // If the object is duplicated also this property will be duplicated PROPERTY_USAGE_HIGH_END_GFX = 1 << 22, PROPERTY_USAGE_NODE_PATH_FROM_SCENE_ROOT = 1 << 23, + PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT = 1 << 24, PROPERTY_USAGE_DEFAULT = PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_NETWORK, PROPERTY_USAGE_DEFAULT_INTL = PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_NETWORK | PROPERTY_USAGE_INTERNATIONALIZED, diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 94c5470c8334..538b3f02bd6c 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -4781,8 +4781,6 @@ EditorNode::EditorNode() { ResourceLoader::clear_translation_remaps(); //no remaps using during editor ResourceLoader::clear_path_remaps(); - ImageTexture::set_keep_images_cached(true); - InputDefault *id = Object::cast_to(Input::get_singleton()); if (id) { diff --git a/scene/resources/resource_format_text.cpp b/scene/resources/resource_format_text.cpp index e838d4a6859c..99a0a3dc82e6 100644 --- a/scene/resources/resource_format_text.cpp +++ b/scene/resources/resource_format_text.cpp @@ -1408,7 +1408,21 @@ void ResourceFormatSaverTextInstance::_find_resources(const Variant &p_variant, if (pi.usage & PROPERTY_USAGE_STORAGE) { Variant v = res->get(I->get().name); - _find_resources(v); + + if (pi.usage & PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT) { + RES sres = v; + if (sres.is_valid()) { + NonPersistentKey npk; + npk.base = res; + npk.property = pi.name; + non_persistent_map[npk] = sres; + resource_set.insert(sres); + saved_resources.push_back(sres); + } + } else { + _find_resources(v); + } + } I = I->next(); @@ -1600,7 +1614,17 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r if (PE->get().usage & PROPERTY_USAGE_STORAGE) { String name = PE->get().name; - Variant value = res->get(name); + Variant value; + if (PE->get().usage & PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT) { + NonPersistentKey npk; + npk.base = res; + npk.property = name; + if (non_persistent_map.has(npk)) { + value = non_persistent_map[npk]; + } + } else { + value = res->get(name); + } Variant default_value = ClassDB::class_get_default_property_value(res->get_class(), name); if (default_value.get_type() != Variant::NIL && bool(Variant::evaluate(Variant::OP_EQUAL, value, default_value))) { diff --git a/scene/resources/resource_format_text.h b/scene/resources/resource_format_text.h index 526f7760d26d..8d78ab33b00d 100644 --- a/scene/resources/resource_format_text.h +++ b/scene/resources/resource_format_text.h @@ -155,6 +155,15 @@ class ResourceFormatSaverTextInstance { bool bundle_resources; bool skip_editor; FileAccess *f; + + struct NonPersistentKey { //for resource properties generated on the fly + RES base; + StringName property; + bool operator<(const NonPersistentKey &p_key) const { return base == p_key.base ? property < p_key.property : base < p_key.base; } + }; + + Map non_persistent_map; + Set resource_set; List saved_resources; Map external_resources; diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp index 85c22f7bf940..e8cc160acf5d 100644 --- a/scene/resources/texture.cpp +++ b/scene/resources/texture.cpp @@ -157,7 +157,7 @@ bool ImageTexture::_get(const StringName &p_name, Variant &r_ret) const { void ImageTexture::_get_property_list(List *p_list) const { p_list->push_back(PropertyInfo(Variant::INT, "flags", PROPERTY_HINT_FLAGS, "Mipmaps,Repeat,Filter,Anisotropic,sRGB,Mirrored Repeat")); - p_list->push_back(PropertyInfo(Variant::OBJECT, "image", PROPERTY_HINT_RESOURCE_TYPE, "Image")); + p_list->push_back(PropertyInfo(Variant::OBJECT, "image", PROPERTY_HINT_RESOURCE_TYPE, "Image", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT)); p_list->push_back(PropertyInfo(Variant::VECTOR2, "size", PROPERTY_HINT_NONE, "")); } @@ -178,12 +178,6 @@ void ImageTexture::_reload_hook(const RID &p_hook) { _change_notify(); } -bool ImageTexture::keep_images_cached = false; - -void ImageTexture::set_keep_images_cached(bool p_enable) { - keep_images_cached = p_enable; -} - void ImageTexture::create(int p_width, int p_height, Image::Format p_format, uint32_t p_flags) { flags = p_flags; @@ -205,9 +199,7 @@ void ImageTexture::create_from_image(const Ref &p_image, uint32_t p_flags VisualServer::get_singleton()->texture_set_data(texture, p_image); _change_notify(); - if (keep_images_cached) { - image_cache = p_image; - } + image_stored = true; } void ImageTexture::set_flags(uint32_t p_flags) { @@ -255,10 +247,7 @@ void ImageTexture::set_data(const Ref &p_image) { _change_notify(); alpha_cache.unref(); - - if (keep_images_cached) { - image_cache = p_image; - } + image_stored = true; } void ImageTexture::_resource_path_changed() { @@ -268,10 +257,10 @@ void ImageTexture::_resource_path_changed() { Ref ImageTexture::get_data() const { - if (image_cache.is_valid()) { - return image_cache; - } else { + if (image_stored) { return VisualServer::get_singleton()->texture_get_data(texture); + } else { + return Ref(); } } diff --git a/scene/resources/texture.h b/scene/resources/texture.h index bfea0f930002..dc3a3e0c74b9 100644 --- a/scene/resources/texture.h +++ b/scene/resources/texture.h @@ -111,7 +111,7 @@ class ImageTexture : public Texture { Size2 size_override; float lossy_storage_quality; mutable Ref alpha_cache; - Ref image_cache; + bool image_stored; protected: virtual void reload_from_file(); @@ -126,11 +126,7 @@ class ImageTexture : public Texture { void _set_data(Dictionary p_data); - static bool keep_images_cached; - public: - static void set_keep_images_cached(bool p_enable); - void create(int p_width, int p_height, Image::Format p_format, uint32_t p_flags = FLAGS_DEFAULT); void create_from_image(const Ref &p_image, uint32_t p_flags = FLAGS_DEFAULT);