diff options
Diffstat (limited to 'scene/resources/packed_scene.cpp')
-rw-r--r-- | scene/resources/packed_scene.cpp | 114 |
1 files changed, 99 insertions, 15 deletions
diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp index c36480420b..f16d68a521 100644 --- a/scene/resources/packed_scene.cpp +++ b/scene/resources/packed_scene.cpp @@ -732,22 +732,62 @@ Error SceneState::_parse_connections(Node *p_owner,Node *p_node, Map<StringName, // only connections that originate or end into main saved scene are saved // everything else is discarded - Node *n=c.target->cast_to<Node>(); - if (!n) { + + Node *target=c.target->cast_to<Node>(); + + + if (!target) { continue; } - //source node is outside saved scene? - bool src_is_out = p_node!=p_owner && (p_node->get_filename()!=String() || p_node->get_owner()!=p_owner); - //target node is outside saved scene? - bool dst_is_out = n!=p_owner && (n->get_filename()!=String() || n->get_owner()!=p_owner); + //find if this connection already exists + Node *common_parent = target->find_common_parent_with(p_node); + + ERR_CONTINUE(!common_parent); + + if (common_parent!=p_owner && common_parent->get_filename()==String()) { + common_parent=common_parent->get_owner(); + } + + bool exists=false; + + //go through ownership chain to see if this exists + while(common_parent) { + + + + Ref<SceneState> ps; + + if (common_parent==p_owner) + ps=common_parent->get_scene_inherited_state(); + else + ps=common_parent->get_scene_instance_state(); - //if both are out, ignore connection - if (src_is_out && dst_is_out) { + + if (ps.is_valid()) { + + NodePath signal_from = common_parent->get_path_to(p_node); + NodePath signal_to = common_parent->get_path_to(target); + + if (ps->has_connection(signal_from,c.signal,signal_to,c.method)) { + exists=true; + break; + } + + } + + if (common_parent==p_owner) + break; + else + common_parent=common_parent->get_owner(); + } + + if (exists) { //already exists (comes from instance or inheritance), so don't save continue; } + { Node *nl=p_node; @@ -760,7 +800,7 @@ Error SceneState::_parse_connections(Node *p_owner,Node *p_node, Map<StringName, Ref<SceneState> state = nl->get_scene_inherited_state(); if (state.is_valid()) { int from_node = state->find_node_by_path(nl->get_path_to(p_node)); - int to_node = state->find_node_by_path(nl->get_path_to(n)); + int to_node = state->find_node_by_path(nl->get_path_to(target)); if (from_node>=0 && to_node>=0) { //this one has state for this node, save @@ -778,7 +818,7 @@ Error SceneState::_parse_connections(Node *p_owner,Node *p_node, Map<StringName, Ref<SceneState> state = nl->get_scene_instance_state(); if (state.is_valid()) { int from_node = state->find_node_by_path(nl->get_path_to(p_node)); - int to_node = state->find_node_by_path(nl->get_path_to(n)); + int to_node = state->find_node_by_path(nl->get_path_to(target)); if (from_node>=0 && to_node>=0) { //this one has state for this node, save @@ -819,14 +859,14 @@ Error SceneState::_parse_connections(Node *p_owner,Node *p_node, Map<StringName, int target_id; - if (node_map.has(n)) { - target_id=node_map[n]; + if (node_map.has(target)) { + target_id=node_map[target]; } else { - if (nodepath_map.has(n)) { - target_id=FLAG_ID_IS_PATH|nodepath_map[n]; + if (nodepath_map.has(target)) { + target_id=FLAG_ID_IS_PATH|nodepath_map[target]; } else { int sidx=nodepath_map.size(); - nodepath_map[n]=sidx; + nodepath_map[target]=sidx; target_id=FLAG_ID_IS_PATH|sidx; } } @@ -1478,6 +1518,8 @@ StringName SceneState::get_connection_method(int p_idx) const{ return names[connections[p_idx].method]; } + + int SceneState::get_connection_flags(int p_idx) const{ ERR_FAIL_INDEX_V(p_idx,connections.size(),-1); @@ -1494,6 +1536,38 @@ Array SceneState::get_connection_binds(int p_idx) const { return binds; } +bool SceneState::has_connection(const NodePath& p_node_from, const StringName& p_signal, const NodePath& p_node_to, const StringName& p_method) const { + + for(int i=0;i<connections.size();i++) { + const ConnectionData &c = connections[i]; + + NodePath np_from; + + if (c.from&FLAG_ID_IS_PATH) { + np_from=node_paths[c.from&FLAG_MASK]; + } else { + np_from=get_node_path(c.from); + } + + NodePath np_to; + + if (c.to&FLAG_ID_IS_PATH) { + np_to=node_paths[c.to&FLAG_MASK]; + } else { + np_to=get_node_path(c.to); + } + + StringName sn_signal=names[c.signal]; + StringName sn_method=names[c.method]; + + if (np_from==p_node_from && sn_signal==p_signal && np_to==p_node_to && sn_method==p_method) { + return true; + } + } + + return false; +} + Vector<NodePath> SceneState::get_editable_instances() const { return editable_instances; } @@ -1505,6 +1579,16 @@ int SceneState::add_name(const StringName& p_name) { return names.size()-1; } +int SceneState::find_name(const StringName& p_name) const { + + for(int i=0;i<names.size();i++) { + if (names[i]==p_name) + return i; + } + + return -1; +} + int SceneState::add_value(const Variant& p_value) { variants.push_back(p_value); |