summaryrefslogtreecommitdiff
path: root/scene/resources/packed_scene.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'scene/resources/packed_scene.cpp')
-rw-r--r--scene/resources/packed_scene.cpp80
1 files changed, 69 insertions, 11 deletions
diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp
index b90f396110..ac67e6e5e9 100644
--- a/scene/resources/packed_scene.cpp
+++ b/scene/resources/packed_scene.cpp
@@ -35,6 +35,7 @@
#include "core/core_string_names.h"
#include "core/io/missing_resource.h"
#include "core/io/resource_loader.h"
+#include "core/templates/local_vector.h"
#include "scene/2d/node_2d.h"
#include "scene/3d/node_3d.h"
#include "scene/gui/control.h"
@@ -43,7 +44,7 @@
#include "scene/property_utils.h"
#define PACKED_SCENE_VERSION 2
-
+#define META_POINTER_PROPERTY_BASE "metadata/_editor_prop_ptr_"
bool SceneState::can_instantiate() const {
return nodes.size() > 0;
}
@@ -108,6 +109,8 @@ Node *SceneState::instantiate(GenEditState p_edit_state) const {
HashMap<Ref<Resource>, Ref<Resource>> resources_local_to_scene;
+ LocalVector<DeferredNodePathProperties> deferred_node_paths;
+
for (int i = 0; i < nc; i++) {
const NodeData &n = nd[i];
@@ -230,9 +233,28 @@ Node *SceneState::instantiate(GenEditState p_edit_state) const {
for (int j = 0; j < nprop_count; j++) {
bool valid;
- ERR_FAIL_INDEX_V(nprops[j].name, sname_count, nullptr);
+
ERR_FAIL_INDEX_V(nprops[j].value, prop_count, nullptr);
+ if (nprops[j].name & FLAG_PATH_PROPERTY_IS_NODE) {
+ uint32_t name_idx = nprops[j].name & (FLAG_PATH_PROPERTY_IS_NODE - 1);
+ 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]);
+ } else {
+ // Do an actual deferred sed of the property path.
+ DeferredNodePathProperties dnp;
+ dnp.path = props[nprops[j].value];
+ dnp.base = node;
+ dnp.property = snames[name_idx];
+ deferred_node_paths.push_back(dnp);
+ }
+ continue;
+ }
+
+ ERR_FAIL_INDEX_V(nprops[j].name, sname_count, nullptr);
+
if (snames[nprops[j].name] == CoreStringNames::get_singleton()->_script) {
//work around to avoid old script variables from disappearing, should be the proper fix to:
//https://github.com/godotengine/godot/issues/2958
@@ -369,6 +391,12 @@ Node *SceneState::instantiate(GenEditState p_edit_state) const {
}
}
+ for (uint32_t i = 0; i < deferred_node_paths.size(); i++) {
+ const DeferredNodePathProperties &dnp = deferred_node_paths[i];
+ Node *other = dnp.base->get_node_or_null(dnp.path);
+ dnp.base->set(dnp.property, other);
+ }
+
for (KeyValue<Ref<Resource>, Ref<Resource>> &E : resources_local_to_scene) {
E.value->setup_local_to_scene();
}
@@ -406,10 +434,10 @@ Node *SceneState::instantiate(GenEditState p_edit_state) const {
for (int j = 0; j < binds.size(); j++) {
argptrs[j] = &binds[j];
}
- callable = callable.bind(argptrs, binds.size());
+ callable = callable.bindp(argptrs, binds.size());
}
- cfrom->connect(snames[c.signal], callable, varray(), CONNECT_PERSIST | c.flags);
+ cfrom->connect(snames[c.signal], callable, CONNECT_PERSIST | c.flags);
}
//Node *s = ret_nodes[0];
@@ -532,6 +560,9 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Has
if (E.name == META_PROPERTY_MISSING_RESOURCES) {
continue; // Ignore this property when packing.
}
+ if (E.name.begins_with(META_POINTER_PROPERTY_BASE)) {
+ continue; // do not save.
+ }
// If instance or inheriting, not saving if property requested so.
if (!states_stack.is_empty()) {
@@ -542,8 +573,15 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Has
StringName name = E.name;
Variant value = p_node->get(name);
+ bool use_deferred_node_path_bit = false;
- if (E.type == Variant::OBJECT && missing_resource_properties.has(E.name)) {
+ if (E.type == Variant::OBJECT && E.hint == PROPERTY_HINT_NODE_TYPE) {
+ value = p_node->get(META_POINTER_PROPERTY_BASE + E.name);
+ if (value.get_type() != Variant::NODE_PATH) {
+ continue; //was never set, ignore.
+ }
+ use_deferred_node_path_bit = true;
+ } else if (E.type == Variant::OBJECT && missing_resource_properties.has(E.name)) {
// Was this missing resource overridden? If so do not save the old value.
Ref<Resource> ures = value;
if (ures.is_null()) {
@@ -562,6 +600,9 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Has
NodeData::Property prop;
prop.name = _nm_get_string(name, name_map);
prop.value = _vm_get_variant(value, variant_map);
+ if (use_deferred_node_path_bit) {
+ prop.name |= FLAG_PATH_PROPERTY_IS_NODE;
+ }
nd.properties.push_back(prop);
}
@@ -851,9 +892,7 @@ Error SceneState::_parse_connections(Node *p_owner, Node *p_node, HashMap<String
cd.signal = _nm_get_string(c.signal.get_name(), name_map);
cd.flags = c.flags;
cd.unbinds = unbinds;
- for (int i = 0; i < c.binds.size(); i++) { // TODO: This could be removed now.
- cd.binds.push_back(_vm_get_variant(c.binds[i], variant_map));
- }
+
for (int i = 0; i < binds.size(); i++) {
cd.binds.push_back(_vm_get_variant(binds[i], variant_map));
}
@@ -1018,7 +1057,7 @@ Variant SceneState::get_property_value(int p_node, const StringName &p_property,
const NodeData::Property *p = nodes[p_node].properties.ptr();
for (int i = 0; i < pc; i++) {
- if (p_property == namep[p[i].name]) {
+ if (p_property == namep[p[i].name & FLAG_PROP_NAME_MASK]) {
found = true;
return variants[p[i].value];
}
@@ -1409,7 +1448,19 @@ int SceneState::get_node_property_count(int p_idx) const {
StringName SceneState::get_node_property_name(int p_idx, int p_prop) const {
ERR_FAIL_INDEX_V(p_idx, nodes.size(), StringName());
ERR_FAIL_INDEX_V(p_prop, nodes[p_idx].properties.size(), StringName());
- return names[nodes[p_idx].properties[p_prop].name];
+ return names[nodes[p_idx].properties[p_prop].name & FLAG_PROP_NAME_MASK];
+}
+
+Vector<String> SceneState::get_node_deferred_nodepath_properties(int p_idx) const {
+ Vector<String> ret;
+ ERR_FAIL_INDEX_V(p_idx, nodes.size(), ret);
+ for (int i = 0; i < nodes[p_idx].properties.size(); i++) {
+ uint32_t idx = nodes[p_idx].properties[i].name;
+ if (idx & FLAG_PATH_PROPERTY_IS_NODE) {
+ ret.push_back(names[idx & FLAG_PROP_NAME_MASK]);
+ }
+ }
+ return ret;
}
Variant SceneState::get_node_property_value(int p_idx, int p_prop) const {
@@ -1555,13 +1606,16 @@ int SceneState::add_node(int p_parent, int p_owner, int p_type, int p_name, int
return nodes.size() - 1;
}
-void SceneState::add_node_property(int p_node, int p_name, int p_value) {
+void SceneState::add_node_property(int p_node, int p_name, int p_value, bool p_deferred_node_path) {
ERR_FAIL_INDEX(p_node, nodes.size());
ERR_FAIL_INDEX(p_name, names.size());
ERR_FAIL_INDEX(p_value, variants.size());
NodeData::Property prop;
prop.name = p_name;
+ if (p_deferred_node_path) {
+ prop.name |= FLAG_PATH_PROPERTY_IS_NODE;
+ }
prop.value = p_value;
nodes.write[p_node].properties.push_back(prop);
}
@@ -1599,6 +1653,10 @@ void SceneState::add_editable_instance(const NodePath &p_path) {
editable_instances.push_back(p_path);
}
+String SceneState::get_meta_pointer_property(const String &p_property) {
+ return META_POINTER_PROPERTY_BASE + p_property;
+}
+
Vector<String> SceneState::_get_node_groups(int p_idx) const {
Vector<StringName> groups = get_node_groups(p_idx);
Vector<String> ret;