Duplicate Arrays and Dictionaries when instancing scene in editor
Also, add deep (=false) parameter to Array.duplicate and Dictionary.duplicate Fixes #13971
This commit is contained in:
parent
b842369442
commit
9f6c0c6eae
|
@ -35,8 +35,8 @@
|
|||
#include "variant.h"
|
||||
#include "vector.h"
|
||||
|
||||
struct ArrayPrivate {
|
||||
|
||||
class ArrayPrivate {
|
||||
public:
|
||||
SafeRefCount refcount;
|
||||
Vector<Variant> array;
|
||||
};
|
||||
|
@ -211,13 +211,13 @@ const Variant &Array::get(int p_idx) const {
|
|||
return operator[](p_idx);
|
||||
}
|
||||
|
||||
Array Array::duplicate() const {
|
||||
Array Array::duplicate(bool p_deep) const {
|
||||
|
||||
Array new_arr;
|
||||
int element_count = size();
|
||||
new_arr.resize(element_count);
|
||||
for (int i = 0; i < element_count; i++) {
|
||||
new_arr[i] = get(i);
|
||||
new_arr[i] = p_deep ? get(i).duplicate(p_deep) : get(i);
|
||||
}
|
||||
|
||||
return new_arr;
|
||||
|
|
|
@ -88,7 +88,7 @@ public:
|
|||
Variant pop_back();
|
||||
Variant pop_front();
|
||||
|
||||
Array duplicate() const;
|
||||
Array duplicate(bool p_deep = false) const;
|
||||
|
||||
Array(const Array &p_from);
|
||||
Array();
|
||||
|
|
|
@ -211,7 +211,7 @@ const Variant *Dictionary::next(const Variant *p_key) const {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
Dictionary Dictionary::duplicate() const {
|
||||
Dictionary Dictionary::duplicate(bool p_deep) const {
|
||||
|
||||
Dictionary n;
|
||||
|
||||
|
@ -219,7 +219,7 @@ Dictionary Dictionary::duplicate() const {
|
|||
get_key_list(&keys);
|
||||
|
||||
for (List<Variant>::Element *E = keys.front(); E; E = E->next()) {
|
||||
n[E->get()] = operator[](E->get());
|
||||
n[E->get()] = p_deep ? operator[](E->get()).duplicate(p_deep) : operator[](E->get());
|
||||
}
|
||||
|
||||
return n;
|
||||
|
|
|
@ -75,7 +75,7 @@ public:
|
|||
Array keys() const;
|
||||
Array values() const;
|
||||
|
||||
Dictionary duplicate() const;
|
||||
Dictionary duplicate(bool p_deep = false) const;
|
||||
|
||||
Dictionary(const Dictionary &p_from);
|
||||
Dictionary();
|
||||
|
|
|
@ -226,7 +226,7 @@ Ref<Resource> Resource::duplicate(bool p_subresources) const {
|
|||
|
||||
if (!(E->get().usage & PROPERTY_USAGE_STORAGE))
|
||||
continue;
|
||||
Variant p = get(E->get().name);
|
||||
Variant p = get(E->get().name).duplicate(true);
|
||||
if (p.get_type() == Variant::OBJECT && p_subresources) {
|
||||
|
||||
RES sr = p;
|
||||
|
|
|
@ -338,6 +338,7 @@ public:
|
|||
}
|
||||
|
||||
void zero();
|
||||
Variant duplicate(bool deep = false) const;
|
||||
static void blend(const Variant &a, const Variant &b, float c, Variant &r_dst);
|
||||
static void interpolate(const Variant &a, const Variant &b, float c, Variant &r_dst);
|
||||
|
||||
|
|
|
@ -465,7 +465,7 @@ struct _VariantCall {
|
|||
VCALL_LOCALMEM0R(Dictionary, hash);
|
||||
VCALL_LOCALMEM0R(Dictionary, keys);
|
||||
VCALL_LOCALMEM0R(Dictionary, values);
|
||||
VCALL_LOCALMEM0R(Dictionary, duplicate);
|
||||
VCALL_LOCALMEM1R(Dictionary, duplicate);
|
||||
|
||||
VCALL_LOCALMEM2(Array, set);
|
||||
VCALL_LOCALMEM1R(Array, get);
|
||||
|
@ -494,7 +494,7 @@ struct _VariantCall {
|
|||
VCALL_LOCALMEM0(Array, shuffle);
|
||||
VCALL_LOCALMEM2R(Array, bsearch);
|
||||
VCALL_LOCALMEM4R(Array, bsearch_custom);
|
||||
VCALL_LOCALMEM0R(Array, duplicate);
|
||||
VCALL_LOCALMEM1R(Array, duplicate);
|
||||
VCALL_LOCALMEM0(Array, invert);
|
||||
|
||||
static void _call_PoolByteArray_get_string_from_ascii(Variant &r_ret, Variant &p_self, const Variant **p_args) {
|
||||
|
@ -1613,7 +1613,7 @@ void register_variant_methods() {
|
|||
ADDFUNC0R(DICTIONARY, INT, Dictionary, hash, varray());
|
||||
ADDFUNC0R(DICTIONARY, ARRAY, Dictionary, keys, varray());
|
||||
ADDFUNC0R(DICTIONARY, ARRAY, Dictionary, values, varray());
|
||||
ADDFUNC0R(DICTIONARY, DICTIONARY, Dictionary, duplicate, varray());
|
||||
ADDFUNC1R(DICTIONARY, DICTIONARY, Dictionary, duplicate, BOOL, "deep", varray(false));
|
||||
|
||||
ADDFUNC0R(ARRAY, INT, Array, size, varray());
|
||||
ADDFUNC0R(ARRAY, BOOL, Array, empty, varray());
|
||||
|
@ -1641,7 +1641,7 @@ void register_variant_methods() {
|
|||
ADDFUNC2R(ARRAY, INT, Array, bsearch, NIL, "value", BOOL, "before", varray(true));
|
||||
ADDFUNC4R(ARRAY, INT, Array, bsearch_custom, NIL, "value", OBJECT, "obj", STRING, "func", BOOL, "before", varray(true));
|
||||
ADDFUNC0NC(ARRAY, NIL, Array, invert, varray());
|
||||
ADDFUNC0RNC(ARRAY, ARRAY, Array, duplicate, varray());
|
||||
ADDFUNC1R(ARRAY, ARRAY, Array, duplicate, BOOL, "deep", varray(false));
|
||||
|
||||
ADDFUNC0R(POOL_BYTE_ARRAY, INT, PoolByteArray, size, varray());
|
||||
ADDFUNC2(POOL_BYTE_ARRAY, NIL, PoolByteArray, set, INT, "idx", INT, "byte", varray());
|
||||
|
|
|
@ -3415,6 +3415,19 @@ Variant Variant::iter_get(const Variant &r_iter, bool &r_valid) const {
|
|||
return Variant();
|
||||
}
|
||||
|
||||
Variant Variant::duplicate(bool deep) const {
|
||||
switch (type) {
|
||||
// case OBJECT:
|
||||
// return operator Object *()->duplicate();
|
||||
case DICTIONARY:
|
||||
return operator Dictionary().duplicate(deep);
|
||||
case ARRAY:
|
||||
return operator Array().duplicate(deep);
|
||||
default:
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
|
||||
void Variant::blend(const Variant &a, const Variant &b, float c, Variant &r_dst) {
|
||||
if (a.type != b.type) {
|
||||
if (a.is_num() && b.is_num()) {
|
||||
|
|
|
@ -3939,7 +3939,7 @@ void PropertyEditor::_edit_button(Object *p_item, int p_column, int p_button) {
|
|||
|
||||
if (_might_be_in_instance() && _get_instanced_node_original_property(prop, vorig)) {
|
||||
|
||||
_edit_set(prop, vorig);
|
||||
_edit_set(prop, vorig.duplicate(true)); // Set, making sure to duplicate arrays properly
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -2163,13 +2163,7 @@ Node *Node::_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap) const
|
|||
if (name == script_property_name)
|
||||
continue;
|
||||
|
||||
Variant value = N->get()->get(name);
|
||||
// Duplicate dictionaries and arrays, mainly needed for __meta__
|
||||
if (value.get_type() == Variant::DICTIONARY) {
|
||||
value = Dictionary(value).duplicate();
|
||||
} else if (value.get_type() == Variant::ARRAY) {
|
||||
value = Array(value).duplicate();
|
||||
}
|
||||
Variant value = N->get()->get(name).duplicate(true);
|
||||
|
||||
if (E->get().usage & PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE) {
|
||||
|
||||
|
@ -2313,13 +2307,7 @@ void Node::_duplicate_and_reown(Node *p_new_parent, const Map<Node *, Node *> &p
|
|||
continue;
|
||||
String name = E->get().name;
|
||||
|
||||
Variant value = get(name);
|
||||
// Duplicate dictionaries and arrays, mainly needed for __meta__
|
||||
if (value.get_type() == Variant::DICTIONARY) {
|
||||
value = Dictionary(value).duplicate();
|
||||
} else if (value.get_type() == Variant::ARRAY) {
|
||||
value = Array(value).duplicate();
|
||||
}
|
||||
Variant value = get(name).duplicate(true);
|
||||
|
||||
node->set(name, value);
|
||||
}
|
||||
|
|
|
@ -249,6 +249,8 @@ Node *SceneState::instance(GenEditState p_edit_state) const {
|
|||
//must make a copy, because this res is local to scene
|
||||
}
|
||||
}
|
||||
} else if (p_edit_state == GEN_EDIT_STATE_INSTANCE) {
|
||||
value = value.duplicate(true); // Duplicate arrays and dictionaries for the editor
|
||||
}
|
||||
node->set(snames[nprops[j].name], value, &valid);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue