From 31f42a0c6a457efca66049342873908d77a9c871 Mon Sep 17 00:00:00 2001 From: Guilherme Sousa Date: Wed, 25 Jan 2023 20:05:28 +0100 Subject: [PATCH] Fix typed array export --- editor/editor_properties_array_dict.cpp | 62 ++++++++++++++++--------- scene/resources/packed_scene.cpp | 60 +++++++++++++++++++++--- 2 files changed, 93 insertions(+), 29 deletions(-) diff --git a/editor/editor_properties_array_dict.cpp b/editor/editor_properties_array_dict.cpp index 28c0b047d8d4..0b7ecc18e6b9 100644 --- a/editor/editor_properties_array_dict.cpp +++ b/editor/editor_properties_array_dict.cpp @@ -36,34 +36,43 @@ #include "editor/editor_scale.h" #include "editor/editor_settings.h" #include "editor/inspector_dock.h" +#include "scene/resources/packed_scene.h" bool EditorPropertyArrayObject::_set(const StringName &p_name, const Variant &p_value) { String name = p_name; - if (name.begins_with("indices")) { - int index = name.get_slicec('/', 1).to_int(); - array.set(index, p_value); - return true; + bool is_indexed_property = name.begins_with("indices"); + bool is_indexed_pointer_property = name.begins_with("metadata/_editor_prop_ptr_indices"); + + if (!is_indexed_property && !is_indexed_pointer_property) { + return false; } - return false; + int index = name.get_slice("/", is_indexed_property ? 1 : 2).to_int(); + + array.set(index, p_value); + return true; } bool EditorPropertyArrayObject::_get(const StringName &p_name, Variant &r_ret) const { String name = p_name; - if (name.begins_with("indices")) { - int index = name.get_slicec('/', 1).to_int(); - bool valid; - r_ret = array.get(index, &valid); - if (r_ret.get_type() == Variant::OBJECT && Object::cast_to(r_ret)) { - r_ret = Object::cast_to(r_ret)->get_object_id(); - } + bool is_indexed_property = name.begins_with("indices"); + bool is_indexed_pointer_property = name.begins_with("metadata/_editor_prop_ptr_indices"); + + if (!is_indexed_property && !is_indexed_pointer_property) { + return false; + } - return valid; + int index = name.get_slice("/", is_indexed_property ? 1 : 2).to_int(); + bool valid; + r_ret = array.get(index, &valid); + + if (r_ret.get_type() == Variant::OBJECT && Object::cast_to(r_ret)) { + r_ret = Object::cast_to(r_ret)->get_object_id(); } - return false; + return valid; } void EditorPropertyArrayObject::set_array(const Variant &p_array) { @@ -159,17 +168,24 @@ EditorPropertyDictionaryObject::EditorPropertyDictionaryObject() { ///////////////////// ARRAY /////////////////////////// void EditorPropertyArray::_property_changed(const String &p_property, Variant p_value, const String &p_name, bool p_changing) { - if (p_property.begins_with("indices")) { - int index = p_property.get_slice("/", 1).to_int(); - Variant array = object->get_array(); - array.set(index, p_value); - emit_changed(get_edited_property(), array, "", true); + bool is_indexed_property = p_property.begins_with("indices"); + bool is_indexed_pointer_property = p_property.begins_with("metadata/_editor_prop_ptr_indices"); - if (array.get_type() == Variant::ARRAY) { - array = array.call("duplicate"); // Duplicate, so undo/redo works better. - } - object->set_array(array); + if (!is_indexed_property && !is_indexed_pointer_property) { + return; } + + int index = p_property.get_slice("/", is_indexed_property ? 1 : 2).to_int(); + Variant array = object->get_array(); + array.set(index, p_value); + emit_changed(get_edited_property(), array, "", true); + + if (array.get_type() == Variant::ARRAY) { + array = array.call("duplicate"); // Duplicate, so undo/redo works better. + } + + object->set_array(array); + update_property(); } void EditorPropertyArray::_change_type(Object *p_button, int p_index) { diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp index e497a628aac0..0f00d7a16b6b 100644 --- a/scene/resources/packed_scene.cpp +++ b/scene/resources/packed_scene.cpp @@ -238,16 +238,37 @@ Node *SceneState::instantiate(GenEditState p_edit_state) const { if (nprops[j].name & FLAG_PATH_PROPERTY_IS_NODE) { uint32_t name_idx = nprops[j].name & (FLAG_PATH_PROPERTY_IS_NODE - 1); + NodeData::Property nprop = nprops[j]; + Variant prop_variant = props[nprop.value]; + StringName prop_name = snames[name_idx]; ERR_FAIL_UNSIGNED_INDEX_V(name_idx, (uint32_t)sname_count, nullptr); - if (Engine::get_singleton()->is_editor_hint()) { - // If editor, just set the metadata and be it - node->set(META_POINTER_PROPERTY_BASE + String(snames[name_idx]), props[nprops[j].value]); + + if (prop_variant.get_type() == Variant::ARRAY) { + if (Engine::get_singleton()->is_editor_hint()) { + // If editor, just set the metadata and be it + node->set(prop_name, prop_variant); + continue; + } + Array array = prop_variant; + for (int k = 0; k < array.size(); k++) { + DeferredNodePathProperties dnp; + dnp.path = array[k]; + dnp.base = node; + dnp.property = StringName(String(prop_name) + "/indices/" + itos(k)); + deferred_node_paths.push_back(dnp); + } + } else { + if (Engine::get_singleton()->is_editor_hint()) { + // If editor, just set the metadata and be it + node->set(META_POINTER_PROPERTY_BASE + String(prop_name), prop_variant); + continue; + } // Do an actual deferred sed of the property path. DeferredNodePathProperties dnp; - dnp.path = props[nprops[j].value]; + dnp.path = prop_variant; dnp.base = node; - dnp.property = snames[name_idx]; + dnp.property = prop_name; deferred_node_paths.push_back(dnp); } continue; @@ -404,7 +425,20 @@ Node *SceneState::instantiate(GenEditState p_edit_state) const { for (const DeferredNodePathProperties &dnp : deferred_node_paths) { Node *other = dnp.base->get_node_or_null(dnp.path); - dnp.base->set(dnp.property, other); + if (String(dnp.property).contains("/indices/")) { + Vector properties = String(dnp.property).split("/"); + Array array = dnp.base->get(properties[0]); + + if (array.size() >= properties[2].to_int()) { + array.push_back(other); + } else { + array.set(properties[2].to_int(), other); + } + + dnp.base->set(properties[0], array); + } else { + dnp.base->set(dnp.property, other); + } } for (KeyValue, Ref> &E : resources_local_to_scene) { @@ -599,6 +633,20 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Has if (ures.is_null()) { value = missing_resource_properties[E.name]; } + } else if (E.type == Variant::ARRAY && E.hint == PROPERTY_HINT_TYPE_STRING) { + int hint_subtype_separator = E.hint_string.find(":"); + if (hint_subtype_separator >= 0) { + String subtype_string = E.hint_string.substr(0, hint_subtype_separator); + int slash_pos = subtype_string.find("/"); + PropertyHint subtype_hint = PropertyHint::PROPERTY_HINT_NONE; + if (slash_pos >= 0) { + subtype_hint = PropertyHint(subtype_string.get_slice("/", 1).to_int()); + subtype_string = subtype_string.substr(0, slash_pos); + } + Variant::Type subtype = Variant::Type(subtype_string.to_int()); + + use_deferred_node_path_bit = subtype == Variant::OBJECT && subtype_hint == PROPERTY_HINT_NODE_TYPE; + } } if (!pinned_props.has(name)) {