diff --git a/compat/resource_compat_binary.cpp b/compat/resource_compat_binary.cpp index 303d6dafd..06edad6d8 100644 --- a/compat/resource_compat_binary.cpp +++ b/compat/resource_compat_binary.cpp @@ -46,6 +46,7 @@ #include "core/io/resource_format_binary.h" #include "compat/image_parser_v2.h" +#include "utility/common.h" #include "utility/file_access_buffer.h" #include "utility/gdre_settings.h" #include "utility/resource_info.h" @@ -954,7 +955,6 @@ Error ResourceLoaderCompatBinary::load() { } if (is_scene && name == "_bundled") { - Dictionary _bundled = res->get("_bundled"); if (!main) { // ?????? // WARN_PRINT("PackedScene found in non-main resource?!!??!?!?!"); @@ -963,10 +963,10 @@ Error ResourceLoaderCompatBinary::load() { if (!compat.is_valid()) { compat.instantiate(); } - compat->packed_scene_version = (int)_bundled.get("version", -1); + compat->packed_scene_version = (int)value.operator Dictionary().get("version", 1); compat->set_on_resource(res); - } else if (_bundled.has("version")) { - packed_scene_version = (int)_bundled.get("version", -1); + } else { + packed_scene_version = (int)value.operator Dictionary().get("version", 1); } } @@ -1051,10 +1051,6 @@ Error ResourceLoaderCompatBinary::load() { } f.unref(); resource = res; - if (res->get_save_class() == "PackedScene") { - Dictionary _bundled = res->get("_bundled"); - packed_scene_version = _bundled.get("version", -1); - } // skip translation remapping for fake and non-global loads if (is_real_load()) { resource->set_as_translation_remapped(translation_remapped); @@ -2748,14 +2744,7 @@ Error ResourceFormatSaverCompatBinaryInstance::_save_to_file(const Refget_class() == "PackedScene") { - Dictionary bundled = p.value; - int packed_scene_version = bundled.get("version", -1); - Ref ri = ResourceInfo::get_info_from_resource(saved_resources.get(i)); - int original_scene_version = ri.is_valid() ? ri->packed_scene_version : -1; - if (original_scene_version < 0 || original_scene_version != packed_scene_version) { - value = fix_scene_bundle(saved_resources.get(i), original_scene_version); - // we have to fix this - } + value = fix_scene_bundle_format(saved_resources.get(i)); } } f->store_32(uint32_t(p.name_idx)); @@ -3350,23 +3339,58 @@ struct ConnectionData { Vector binds; }; -Dictionary ResourceFormatSaverCompatBinaryInstance::fix_scene_bundle(const Ref &p_scene, int original_version) { +Dictionary ResourceFormatSaverCompatBinaryInstance::fix_scene_bundle_format(const Ref &p_scene) { Dictionary bundled = p_scene->get("_bundled"); - int ver = bundled.get("version", -1); + int ver = bundled.get("version", 1); if (ver > ResourceFormatLoaderCompatBinary::CURRENT_PACKED_SCENE_VERSION) { ERR_FAIL_V_MSG(bundled, "THEY INCREASED THE PACKED SCENE VERSION AGAIN!!!!!! REPORT THIS!!!!!!!!!!!!!!!!!!!!!!!!!!!"); } + Ref ri = ResourceInfo::get_info_from_resource(p_scene); + int original_version = ri.is_valid() ? ri->packed_scene_version : -1; + if (original_version < 0) { + switch (ver_major) { + case 0: + case 1: + original_version = 1; + break; + case 2: + case 3: + original_version = 2; + break; + case 4: + default: + original_version = ResourceFormatLoaderCompatBinary::CURRENT_PACKED_SCENE_VERSION; + break; + } + } + + if (original_version == ver) { + return bundled; + } int conn_count = p_scene->get_state()->get_connection_count(); - bool requires_version_3 = false; for (int i = 0; i < conn_count; i++) { if (p_scene->get_state()->get_connection_unbinds(i) > 0) { - requires_version_3 = true; - break; + // Requires version 3, we can't fix this, return the original bundled dictionary + WARN_PRINT_DEBUG_COND(original_version < 3, vformat("Non-v3 scene bundle '%s' has unbinds. This is not supported.", p_scene->get_path())); + return bundled; } } - if (requires_version_3) { - return bundled; + int new_version = original_version; // default to 1 + if (new_version == 1) { + static Vector non_v1_keys = { "node_paths", "editable_instances", "base_scene" }; + for (auto &key : non_v1_keys) { + if (bundled.has(key) && bundled[key].get_type() != Variant::NIL) { + auto &value = bundled[key]; + if (value.get_type() == Variant::ARRAY && value.operator Array().size() > 0) { + WARN_PRINT_DEBUG_COND(original_version == 1, vformat("Non-v1 scene bundle '%s' has non-empty %s array. This is not supported.", p_scene->get_path(), key)); + new_version = 2; + } else if (value.get_type() == Variant::INT && value.operator int64_t() >= 0) { + WARN_PRINT_DEBUG_COND(original_version == 1, vformat("Non-v1 scene bundle '%s' has base_scene index. This is not supported.", p_scene->get_path())); + new_version = 2; + } + } + } } Dictionary ret = bundled.duplicate(true); PackedInt32Array conns = ret["conns"]; @@ -3389,7 +3413,12 @@ Dictionary ResourceFormatSaverCompatBinaryInstance::fix_scene_bundle(const Ref

0 ? original_version : 2; // default to 2 + ret["version"] = new_version; + if (new_version == 1) { + ret.erase("node_paths"); + ret.erase("editable_instances"); + ret.erase("base_scene"); + } return ret; } diff --git a/compat/resource_compat_binary.h b/compat/resource_compat_binary.h index 060a78200..8b2cd4df9 100644 --- a/compat/resource_compat_binary.h +++ b/compat/resource_compat_binary.h @@ -236,7 +236,7 @@ class ResourceFormatSaverCompatBinaryInstance { void _find_resources(const Variant &p_variant, bool p_main = false); static void save_unicode_string(Ref f, const String &p_string, bool p_bit_on_len = false); int get_string_index(const String &p_string); - Dictionary fix_scene_bundle(const Ref &p_scene, int original_version); + Dictionary fix_scene_bundle_format(const Ref &p_scene); Error set_save_settings(const Ref &p_resource, uint32_t p_flags); static String get_local_path(const String &p_path, const Ref &p_resource); diff --git a/compat/resource_compat_text.cpp b/compat/resource_compat_text.cpp index 4e7c66f33..cbce45b86 100644 --- a/compat/resource_compat_text.cpp +++ b/compat/resource_compat_text.cpp @@ -3137,7 +3137,7 @@ bool is_packed_scene(const Ref &p_resource) { return p_resource.is_valid() && _resource_get_class(p_resource) == "PackedScene"; } -Ref _ensure_resource_is_packed_scene(const Ref &p_resource, int recursion_depth) { +Ref _ensure_resource_is_packed_scene(const Ref &p_resource, int recursion_depth, HashMap, Ref> &r_replaced_packed_scenes) { Ref r_packed_scene = p_resource; if (recursion_depth > 256) { ERR_PRINT("Recursion depth exceeded."); @@ -3153,7 +3153,12 @@ Ref _ensure_resource_is_packed_scene(const Ref &p_resourc for (int i = 0; i < arr.size(); i++) { Ref res = arr[i]; if (res.is_valid() && res->get_save_class() == "PackedScene") { - arr[i] = _ensure_resource_is_packed_scene(res, recursion_depth); + if (r_replaced_packed_scenes.has(res)) { + arr[i] = r_replaced_packed_scenes[res]; + } else { + arr[i] = _ensure_resource_is_packed_scene(res, recursion_depth, r_replaced_packed_scenes); + r_replaced_packed_scenes[res] = arr[i]; + } } } bundle.set("variants", arr); @@ -3183,5 +3188,6 @@ Ref ResourceFormatSaverCompatTextInstance::ensure_packed_scenes(con } else if (p_resource->get_class() == "PackedScene") { return p_resource; } - return _ensure_resource_is_packed_scene(p_resource, 0); + HashMap, Ref> replaced_packed_scenes; + return _ensure_resource_is_packed_scene(p_resource, 0, replaced_packed_scenes); } diff --git a/gui/gdre_window.cpp b/gui/gdre_window.cpp index 92b3c3b81..d1981407a 100644 --- a/gui/gdre_window.cpp +++ b/gui/gdre_window.cpp @@ -181,6 +181,7 @@ void GDREWindow::_bind_methods() { ClassDB::bind_static_method(get_class_static(), D_METHOD("popup_box", "p_parent", "p_box", "p_message", "p_title", "p_confirm_callback", "p_cancel_callback", "p_ok_button_text", "p_cancel_button_text"), &GDREWindow::popup_box, DEFVAL(Callable()), DEFVAL(Callable()), DEFVAL("OK"), DEFVAL("Cancel")); ClassDB::bind_method(D_METHOD("popup_confirm_box", "p_message", "p_title", "p_confirm_callback", "p_cancel_callback", "p_ok_button_text", "p_cancel_button_text"), &GDREWindow::popup_confirm_box, DEFVAL(Callable()), DEFVAL(Callable()), DEFVAL("OK"), DEFVAL("Cancel")); ClassDB::bind_method(D_METHOD("popup_error_box", "p_message", "p_title", "p_callback"), &GDREWindow::popup_error_box, DEFVAL("Error"), DEFVAL(Callable())); + ClassDB::bind_static_method(get_class_static(), D_METHOD("set_window_autoscaling", "p_window", "p_min_size"), &GDREWindow::set_window_autoscaling); } void GDREAcceptDialogBase::_bind_methods() { diff --git a/standalone/gdre_file_tree.gd b/standalone/gdre_file_tree.gd index 558cca301..f68217ef4 100644 --- a/standalone/gdre_file_tree.gd +++ b/standalone/gdre_file_tree.gd @@ -747,6 +747,7 @@ func _ready(): self.hide_root = true _clear() right_click_menu = PopupMenu.new() + GDREWindow.set_window_autoscaling(right_click_menu, Vector2i()) pop_right_menu_items() right_click_menu.visible = false right_click_menu.connect("id_pressed", self._on_right_click_id) diff --git a/utility/common.h b/utility/common.h index 7f37d465d..f4378ccc6 100644 --- a/utility/common.h +++ b/utility/common.h @@ -418,3 +418,16 @@ class GDRECommon : public Object { // Can only pass in string literals #define _GDRE_CHECK_HEADER(p_buffer, p_expected_header) gdre::check_header(p_buffer, p_expected_header, sizeof(p_expected_header) - 1) + +#define WARN_PRINT_COND(cond, msg) \ + if (unlikely(cond)) { \ + WARN_PRINT(msg); \ + } + +#ifdef DEBUG_ENABLED +#define WARN_PRINT_DEBUG(msg) WARN_PRINT(msg) +#define WARN_PRINT_DEBUG_COND(cond, msg) WARN_PRINT_COND(cond, msg) +#else +#define WARN_PRINT_DEBUG(msg) (void)(msg) +#define WARN_PRINT_DEBUG_COND(cond, msg) (void)(msg) +#endif