summaryrefslogtreecommitdiff
path: root/scene
diff options
context:
space:
mode:
Diffstat (limited to 'scene')
-rw-r--r--scene/gui/base_button.cpp2
-rw-r--r--scene/main/node.cpp32
-rw-r--r--scene/main/node.h1
-rw-r--r--scene/register_scene_types.cpp4
-rw-r--r--scene/resources/packed_scene.cpp114
-rw-r--r--scene/resources/packed_scene.h3
-rw-r--r--scene/resources/scene_format_text.cpp4
7 files changed, 141 insertions, 19 deletions
diff --git a/scene/gui/base_button.cpp b/scene/gui/base_button.cpp
index 699062fee4..41d766c1b7 100644
--- a/scene/gui/base_button.cpp
+++ b/scene/gui/base_button.cpp
@@ -416,7 +416,7 @@ Ref<ShortCut> BaseButton:: get_shortcut() const {
void BaseButton::_unhandled_input(InputEvent p_event) {
- if (!is_disabled() && is_visible() && p_event.is_pressed() && shortcut.is_valid() && shortcut->is_shortcut(p_event)) {
+ if (!is_disabled() && is_visible() && p_event.is_pressed() && !p_event.is_echo() && shortcut.is_valid() && shortcut->is_shortcut(p_event)) {
if (get_viewport()->get_modal_stack_top() && !get_viewport()->get_modal_stack_top()->is_a_parent_of(this))
return; //ignore because of modal window
diff --git a/scene/main/node.cpp b/scene/main/node.cpp
index 55106f5ee7..a53c19d2e7 100644
--- a/scene/main/node.cpp
+++ b/scene/main/node.cpp
@@ -1121,6 +1121,38 @@ Node *Node::get_owner() const {
return data.owner;
}
+
+Node* Node::find_common_parent_with(const Node *p_node) const {
+
+ if (this==p_node)
+ return const_cast<Node*>(p_node);
+
+ Set<const Node*> visited;
+
+ const Node *n=this;
+
+ while(n) {
+
+ visited.insert(n);
+ n=n->data.parent;
+ }
+
+ const Node *common_parent=p_node;
+
+ while(common_parent) {
+
+ if (visited.has(common_parent))
+ break;
+ common_parent=common_parent->data.parent;
+ }
+
+ if (!common_parent)
+ return NULL;
+
+ return const_cast<Node*>(common_parent);
+
+}
+
NodePath Node::get_path_to(const Node *p_node) const {
ERR_FAIL_NULL_V(p_node,NodePath());
diff --git a/scene/main/node.h b/scene/main/node.h
index 10cfc5f9e6..18e403cd61 100644
--- a/scene/main/node.h
+++ b/scene/main/node.h
@@ -215,6 +215,7 @@ public:
NodePath get_path() const;
NodePath get_path_to(const Node *p_node) const;
+ Node* find_common_parent_with(const Node *p_node) const;
void add_to_group(const StringName& p_identifier,bool p_persistent=false);
void remove_from_group(const StringName& p_identifier);
diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp
index c83ab88c73..bc0951e436 100644
--- a/scene/register_scene_types.cpp
+++ b/scene/register_scene_types.cpp
@@ -637,10 +637,10 @@ void register_scene_types() {
resource_saver_text = memnew( ResourceFormatSaverText );
- ResourceSaver::add_resource_format_saver(resource_saver_text);
+ ResourceSaver::add_resource_format_saver(resource_saver_text,true);
resource_loader_text = memnew( ResourceFormatLoaderText );
- ResourceLoader::add_resource_format_loader(resource_loader_text);
+ ResourceLoader::add_resource_format_loader(resource_loader_text,true);
}
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);
diff --git a/scene/resources/packed_scene.h b/scene/resources/packed_scene.h
index 3b6c0898e0..f0e530f88a 100644
--- a/scene/resources/packed_scene.h
+++ b/scene/resources/packed_scene.h
@@ -163,11 +163,14 @@ public:
int get_connection_flags(int p_idx) const;
Array get_connection_binds(int p_idx) const;
+ bool has_connection(const NodePath &p_node_from, const StringName& p_signal, const NodePath &p_node_to, const StringName& p_method) const;
+
Vector<NodePath> get_editable_instances() const;
//build API
int add_name(const StringName& p_name);
+ int find_name(const StringName& p_name) const;
int add_value(const Variant& p_value);
int add_node_path(const NodePath& p_path);
int add_node(int p_parent,int p_owner,int p_type,int p_name, int p_instance);
diff --git a/scene/resources/scene_format_text.cpp b/scene/resources/scene_format_text.cpp
index 95645107d4..7bb9ca90ae 100644
--- a/scene/resources/scene_format_text.cpp
+++ b/scene/resources/scene_format_text.cpp
@@ -404,7 +404,9 @@ Error ResourceInteractiveLoaderText::poll() {
}
if (next_tag.fields.has("parent")) {
- parent=packed_scene->get_state()->add_node_path(next_tag.fields["parent"]);
+ NodePath np = next_tag.fields["parent"];
+ np.prepend_period(); //compatible to how it manages paths internally
+ parent=packed_scene->get_state()->add_node_path(np);
}