summaryrefslogtreecommitdiff
path: root/scene
diff options
context:
space:
mode:
Diffstat (limited to 'scene')
-rw-r--r--scene/main/scene_tree.cpp17
-rw-r--r--scene/resources/dynamic_font.cpp11
-rw-r--r--scene/resources/visual_shader.cpp30
-rw-r--r--scene/resources/visual_shader.h3
4 files changed, 53 insertions, 8 deletions
diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp
index 7c43d8fb14..238d6c20cc 100644
--- a/scene/main/scene_tree.cpp
+++ b/scene/main/scene_tree.cpp
@@ -459,10 +459,7 @@ void SceneTree::input_event(const Ref<InputEvent> &p_event) {
}
void SceneTree::init() {
-
- //_quit=false;
initialized = true;
-
root->_set_tree(this);
MainLoop::init();
}
@@ -1285,6 +1282,14 @@ void SceneTree::_change_scene(Node *p_to) {
current_scene = NULL;
}
+ // If we're quitting, abort.
+ if (unlikely(_quit)) {
+ if (p_to) { // Prevent memory leak.
+ memdelete(p_to);
+ }
+ return;
+ }
+
if (p_to) {
current_scene = p_to;
root->add_child(p_to);
@@ -1292,15 +1297,14 @@ void SceneTree::_change_scene(Node *p_to) {
}
Error SceneTree::change_scene(const String &p_path) {
-
Ref<PackedScene> new_scene = ResourceLoader::load(p_path);
if (new_scene.is_null())
return ERR_CANT_OPEN;
return change_scene_to(new_scene);
}
-Error SceneTree::change_scene_to(const Ref<PackedScene> &p_scene) {
+Error SceneTree::change_scene_to(const Ref<PackedScene> &p_scene) {
Node *new_scene = NULL;
if (p_scene.is_valid()) {
new_scene = p_scene->instance();
@@ -1310,8 +1314,8 @@ Error SceneTree::change_scene_to(const Ref<PackedScene> &p_scene) {
call_deferred("_change_scene", new_scene);
return OK;
}
-Error SceneTree::reload_current_scene() {
+Error SceneTree::reload_current_scene() {
ERR_FAIL_COND_V(!current_scene, ERR_UNCONFIGURED);
String fname = current_scene->get_filename();
return change_scene(fname);
@@ -1322,6 +1326,7 @@ void SceneTree::add_current_scene(Node *p_current) {
current_scene = p_current;
root->add_child(p_current);
}
+
#ifdef DEBUG_ENABLED
static void _fill_array(Node *p_node, Array &array, int p_level) {
diff --git a/scene/resources/dynamic_font.cpp b/scene/resources/dynamic_font.cpp
index 8b619345d6..a21015f872 100644
--- a/scene/resources/dynamic_font.cpp
+++ b/scene/resources/dynamic_font.cpp
@@ -130,7 +130,10 @@ Error DynamicFontAtSize::_load() {
} else {
FileAccess *f = FileAccess::open(font->font_path, FileAccess::READ);
- ERR_FAIL_COND_V_MSG(!f, ERR_CANT_OPEN, "Cannot open font file '" + font->font_path + "'.");
+ if (!f) {
+ FT_Done_FreeType(library);
+ ERR_FAIL_V_MSG(ERR_CANT_OPEN, "Cannot open font file '" + font->font_path + "'.");
+ }
size_t len = f->get_len();
_fontdata[font->font_path] = Vector<uint8_t>();
@@ -145,7 +148,10 @@ Error DynamicFontAtSize::_load() {
if (font->font_mem == NULL && font->font_path != String()) {
FileAccess *f = FileAccess::open(font->font_path, FileAccess::READ);
- ERR_FAIL_COND_V_MSG(!f, ERR_CANT_OPEN, "Cannot open font file '" + font->font_path + "'.");
+ if (!f) {
+ FT_Done_FreeType(library);
+ ERR_FAIL_V_MSG(ERR_CANT_OPEN, "Cannot open font file '" + font->font_path + "'.");
+ }
memset(&stream, 0, sizeof(FT_StreamRec));
stream.base = NULL;
@@ -176,6 +182,7 @@ Error DynamicFontAtSize::_load() {
error = FT_Open_Face(library, &fargs, 0, &face);
} else {
+ FT_Done_FreeType(library);
ERR_FAIL_V_MSG(ERR_UNCONFIGURED, "DynamicFont uninitialized.");
}
diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp
index 37792eaaea..4d2082e3c1 100644
--- a/scene/resources/visual_shader.cpp
+++ b/scene/resources/visual_shader.cpp
@@ -378,6 +378,9 @@ void VisualShader::remove_node(Type p_type, int p_id) {
List<Connection>::Element *N = E->next();
if (E->get().from_node == p_id || E->get().to_node == p_id) {
g->connections.erase(E);
+ if (E->get().from_node == p_id) {
+ g->nodes[E->get().to_node].prev_connected_nodes.erase(p_id);
+ }
}
E = N;
}
@@ -399,6 +402,25 @@ bool VisualShader::is_node_connection(Type p_type, int p_from_node, int p_from_p
return false;
}
+bool VisualShader::is_nodes_connected_relatively(const Graph *p_graph, int p_node, int p_target) const {
+ bool result = false;
+
+ const VisualShader::Node &node = p_graph->nodes[p_node];
+
+ for (const List<int>::Element *E = node.prev_connected_nodes.front(); E; E = E->next()) {
+
+ if (E->get() == p_target) {
+ return true;
+ }
+
+ result = is_nodes_connected_relatively(p_graph, E->get(), p_target);
+ if (result) {
+ break;
+ }
+ }
+ return result;
+}
+
bool VisualShader::can_connect_nodes(Type p_type, int p_from_node, int p_from_port, int p_to_node, int p_to_port) const {
ERR_FAIL_INDEX_V(p_type, TYPE_MAX, false);
@@ -433,6 +455,9 @@ bool VisualShader::can_connect_nodes(Type p_type, int p_from_node, int p_from_po
}
}
+ if (is_nodes_connected_relatively(g, p_from_node, p_to_node))
+ return false;
+
return true;
}
@@ -449,6 +474,8 @@ void VisualShader::connect_nodes_forced(Type p_type, int p_from_node, int p_from
c.to_node = p_to_node;
c.to_port = p_to_port;
g->connections.push_back(c);
+ g->nodes[p_to_node].prev_connected_nodes.push_back(p_from_node);
+
_queue_update();
}
@@ -479,6 +506,7 @@ Error VisualShader::connect_nodes(Type p_type, int p_from_node, int p_from_port,
c.to_node = p_to_node;
c.to_port = p_to_port;
g->connections.push_back(c);
+ g->nodes[p_to_node].prev_connected_nodes.push_back(p_from_node);
_queue_update();
return OK;
@@ -492,6 +520,7 @@ void VisualShader::disconnect_nodes(Type p_type, int p_from_node, int p_from_por
if (E->get().from_node == p_from_node && E->get().from_port == p_from_port && E->get().to_node == p_to_node && E->get().to_port == p_to_port) {
g->connections.erase(E);
+ g->nodes[p_to_node].prev_connected_nodes.erase(p_from_node);
_queue_update();
return;
}
@@ -1326,6 +1355,7 @@ void VisualShader::_input_type_changed(Type p_type, int p_id) {
List<Connection>::Element *N = E->next();
if (E->get().from_node == p_id) {
g->connections.erase(E);
+ g->nodes[E->get().to_node].prev_connected_nodes.erase(p_id);
}
E = N;
}
diff --git a/scene/resources/visual_shader.h b/scene/resources/visual_shader.h
index 0a3d5f96bd..b2803d1dfb 100644
--- a/scene/resources/visual_shader.h
+++ b/scene/resources/visual_shader.h
@@ -65,6 +65,7 @@ private:
struct Node {
Ref<VisualShaderNode> node;
Vector2 position;
+ List<int> prev_connected_nodes;
};
struct Graph {
@@ -135,6 +136,8 @@ public:
void remove_node(Type p_type, int p_id);
bool is_node_connection(Type p_type, int p_from_node, int p_from_port, int p_to_node, int p_to_port) const;
+
+ bool is_nodes_connected_relatively(const Graph *p_graph, int p_node, int p_target) const;
bool can_connect_nodes(Type p_type, int p_from_node, int p_from_port, int p_to_node, int p_to_port) const;
Error connect_nodes(Type p_type, int p_from_node, int p_from_port, int p_to_node, int p_to_port);
void disconnect_nodes(Type p_type, int p_from_node, int p_from_port, int p_to_node, int p_to_port);