From 5e3a4c13da5971b48ff8f0434165ea9da2084479 Mon Sep 17 00:00:00 2001 From: yg2f Date: Sat, 10 Jan 2015 15:11:44 +0100 Subject: [PATCH 01/36] fixes cubemap ressource editor bug this fixes the cubemap ressource editor bug described in issue #908. some other littles fixes will be required to allow the Environment ressource to create and load Cubemap Ressources more easily --- scene/resources/texture.cpp | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp index dae055890b7..889042f4513 100644 --- a/scene/resources/texture.cpp +++ b/scene/resources/texture.cpp @@ -935,21 +935,21 @@ float CubeMap::get_lossy_storage_quality() const { bool CubeMap::_set(const StringName& p_name, const Variant& p_value) { - if (p_name=="side/left") + if (p_name=="side/left") { set_side(SIDE_LEFT,p_value); - if (p_name=="side/right") + } else if (p_name=="side/right") { set_side(SIDE_RIGHT,p_value); - if (p_name=="side/bottom") + } else if (p_name=="side/bottom") { set_side(SIDE_BOTTOM,p_value); - if (p_name=="side/top") + } else if (p_name=="side/top") { set_side(SIDE_TOP,p_value); - if (p_name=="side/front") + } else if (p_name=="side/front") { set_side(SIDE_FRONT,p_value); - if (p_name=="side/back") + } else if (p_name=="side/back") { set_side(SIDE_BACK,p_value); - else if (p_name=="flags") + } else if (p_name=="flags") { set_flags(p_value); - else if (p_name=="storage") { + } else if (p_name=="storage") { storage=Storage(p_value.operator int()); } else if (p_name=="lossy_quality") { lossy_storage_quality=p_value; @@ -962,25 +962,25 @@ bool CubeMap::_set(const StringName& p_name, const Variant& p_value) { bool CubeMap::_get(const StringName& p_name,Variant &r_ret) const { - if (p_name=="side/left") + if (p_name=="side/left") { r_ret=get_side(SIDE_LEFT); - if (p_name=="side/right") + } else if (p_name=="side/right") { r_ret=get_side(SIDE_RIGHT); - if (p_name=="side/bottom") + } else if (p_name=="side/bottom") { r_ret=get_side(SIDE_BOTTOM); - if (p_name=="side/top") + } else if (p_name=="side/top") { r_ret=get_side(SIDE_TOP); - if (p_name=="side/front") + } else if (p_name=="side/front") { r_ret=get_side(SIDE_FRONT); - if (p_name=="side/back") + } else if (p_name=="side/back") { r_ret=get_side(SIDE_BACK); - else if (p_name=="flags") + } else if (p_name=="flags") { r_ret= flags; - else if (p_name=="storage") + } else if (p_name=="storage") { r_ret= storage; - else if (p_name=="lossy_quality") + } else if (p_name=="lossy_quality") { r_ret= lossy_storage_quality; - else + } else return false; return true; From 6c4e1650fb8b7e06c8657ca1a5de167184fda6c0 Mon Sep 17 00:00:00 2001 From: Dana Olson Date: Sat, 10 Jan 2015 12:55:12 -0500 Subject: [PATCH 02/36] add option to automatically reload changed scripts --- tools/editor/plugins/script_editor_plugin.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/editor/plugins/script_editor_plugin.cpp b/tools/editor/plugins/script_editor_plugin.cpp index 55957887dcd..20aeb05a507 100644 --- a/tools/editor/plugins/script_editor_plugin.cpp +++ b/tools/editor/plugins/script_editor_plugin.cpp @@ -630,7 +630,10 @@ bool ScriptEditor::_test_script_times_on_disk() { if (!all_ok) - disk_changed->call_deferred("popup_centered_ratio",0.5); + if (bool(EDITOR_DEF("text_editor/autoreload_changed_scripts",false))) + script_editor->_reload_scripts(); + else + disk_changed->call_deferred("popup_centered_ratio",0.5); return all_ok; } From d6d85a23c9061149c7996a3b434e6f9b25a81e49 Mon Sep 17 00:00:00 2001 From: "Bil Bas (Spooner)" Date: Sat, 10 Jan 2015 20:42:28 +0000 Subject: [PATCH 03/36] Ignored more generated files. --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 45bf5313117..87f9986e597 100644 --- a/.gitignore +++ b/.gitignore @@ -12,12 +12,14 @@ drivers/gles2/shaders/*.h modules/register_module_types.cpp core/version.h core/method_bind.inc +core/method_bind_ext.inc core/script_encryption_key.cpp core/global_defaults.cpp tools/editor/register_exporters.cpp tools/editor/doc_data_compressed.h tools/editor/editor_icons.cpp -fpic +log.txt # Android specific platform/android/java/local.properties From 7a41f8c604143eec16c232cffda122b095c5108f Mon Sep 17 00:00:00 2001 From: "Bil Bas (Spooner)" Date: Sat, 10 Jan 2015 20:44:20 +0000 Subject: [PATCH 04/36] Added basic sprintf functionality (e.g. "fish %d %s" % [12, Vector2(1, 2)]) --- bin/tests/test_string.cpp | 79 ++++++++++++++++++++++++++++++- core/ustring.cpp | 98 +++++++++++++++++++++++++++++++++++++++ core/ustring.h | 4 +- core/variant_op.cpp | 14 ++++++ 4 files changed, 193 insertions(+), 2 deletions(-) diff --git a/bin/tests/test_string.cpp b/bin/tests/test_string.cpp index 66238b066de..c932aeb3b47 100644 --- a/bin/tests/test_string.cpp +++ b/bin/tests/test_string.cpp @@ -487,7 +487,7 @@ struct test_27_data { bool test_27() { - OS::get_singleton()->print("\n\nTest 26: begins_with\n"); + OS::get_singleton()->print("\n\nTest 27: begins_with\n"); test_27_data tc[] = { {"res://foobar", "res://", true}, {"res", "res://", false}, @@ -504,11 +504,87 @@ bool test_27() { } if (!state) { OS::get_singleton()->print("\n\t Failure on:\n\t\tstring: ", tc[i].data, "\n\t\tbegin: ", tc[i].begin, "\n\t\texpected: ", tc[i].expected ? "true" : "false", "\n"); + break; } }; return state; }; + +bool test_28() { + + OS::get_singleton()->print("\n\nTest 28: sprintf\n"); + + bool success, state = true; + char output_format[] = "\tTest:\t%ls => %ls (%s)\n"; + String format, output; + Array args; + + // %% + format = "fish %% frog"; + args.clear(); + output = format.sprintf(args); + success = (format.sprintf(args) == String("fish % frog")); + OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL"); + if (!success) state = false; + + // Int + format = "fish %d frog"; + args.clear(); + args.push_back(5); + output = format.sprintf(args); + success = (format.sprintf(args) == String("fish 5 frog")); + OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL"); + if (!success) state = false; + + // Hex (lower) + format = "fish %x frog"; + args.clear(); + args.push_back(45); + output = format.sprintf(args); + success = (format.sprintf(args) == String("fish 2d frog")); + OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL"); + if (!success) state = false; + + // Hex (upper) + format = "fish %X frog"; + args.clear(); + args.push_back(45); + output = format.sprintf(args); + success = (format.sprintf(args) == String("fish 2D frog")); + OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL"); + if (!success) state = false; + + // Octal + format = "fish %o frog"; + args.clear(); + args.push_back(99); + output = format.sprintf(args); + success = (format.sprintf(args) == String("fish 143 frog")); + OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL"); + if (!success) state = false; + + // Real + format = "fish %f frog"; + args.clear(); + args.push_back(99.99); + output = format.sprintf(args); + success = (format.sprintf(args) == String("fish 99.990000 frog")); + OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL"); + if (!success) state = false; + + // String + format = "fish %s frog"; + args.clear(); + args.push_back("cheese"); + output = format.sprintf(args); + success = (format.sprintf(args) == String("fish cheese frog")); + OS::get_singleton()->print(output_format , format.c_str(), output.c_str(), success ? "OK" : "FAIL"); + if (!success) state = false; + + return state; +} + typedef bool (*TestFunc)(void); TestFunc test_funcs[] = { @@ -540,6 +616,7 @@ TestFunc test_funcs[] = { test_25, test_26, test_27, + test_28, 0 }; diff --git a/core/ustring.cpp b/core/ustring.cpp index 581cc29440b..a7359f112fe 100644 --- a/core/ustring.cpp +++ b/core/ustring.cpp @@ -34,6 +34,8 @@ #include "io/md5.h" #include "ucaps.h" #include "color.h" +#include "variant.h" +#include #define MAX_DIGITS 6 #define UPPERCASE(m_c) (((m_c)>='a' && (m_c)<='z')?((m_c)-('a'-'A')):(m_c)) #define LOWERCASE(m_c) (((m_c)>='A' && (m_c)<='Z')?((m_c)+('a'-'A')):(m_c)) @@ -3518,4 +3520,100 @@ String rtoss(double p_val) { return String::num_scientific(p_val); } +// sprintf is implemented in GDScript via: +// "fish %s pie" % "frog" +// "fish %s %d pie" % ["frog", 12] +const int FORMAT_BUFFER_SIZE = 1024; +const int OUTPUT_BUFFER_SIZE = 1024 * 100; +String String::sprintf(const Array& values) const { + String formatted; + CharType* self = (CharType*)c_str(); + bool in_format = false; + int value_index = 0; + char format_format[FORMAT_BUFFER_SIZE] = "%d"; + + for (; *self; self++) { + const CharType c = *self; + + if (in_format) { // We have % - lets see what else we get. + switch (c) { + case '%': // Manage %% as % + formatted += chr(c); + in_format = false; + break; + + case 'd': // Integer (signed) + case 'o': // Octal + case 'x': // Hexadecimal (lowercase) + case 'X': // Hexadecimal (uppercase) + if (values[value_index].is_num()) { + char buffer[OUTPUT_BUFFER_SIZE]; + int value = values[value_index]; + format_format[1] = c; + format_format[2] = 0; + ::sprintf(buffer, format_format, value); + + formatted += String(buffer); + ++value_index; + in_format = false; + } else { + // TODO: Error? + } + + break; + + case 'f': // Float + if (values[value_index].is_num()) { + char buffer[OUTPUT_BUFFER_SIZE]; + double value = values[value_index]; + ::sprintf(buffer, "%f", value); + + formatted += String(buffer); + ++value_index; + in_format = false; + } else { + // TODO: Error? + } + + break; + + case 's': // String + String value = values[value_index]; + formatted += value; + ++value_index; + in_format = false; + break; + + // case '-': // Left justify + // break; + + // case '+': // Show + if positive. + // break; + + // case '0': case '1': case '2': case '3': case '4': + // case '5': case '6': case '7': case '8': case '9': + // break; + + // case '.': // Float separtor. + // break; + + // case '*': // Dyanmic width, based on value. + // break; + + //default: + // TODO: error? + } + } else { // Not in format string. + switch (c) { + case '%': + in_format = true; + break; + default: + formatted += chr(c); + } + } + } + + return formatted; +} diff --git a/core/ustring.h b/core/ustring.h index e1d67617423..ccbbf5e5d2f 100644 --- a/core/ustring.h +++ b/core/ustring.h @@ -31,6 +31,7 @@ #include "typedefs.h" #include "vector.h" +#include "array.h" /** @author red @@ -127,6 +128,7 @@ public: String insert(int p_at_pos,String p_string) const; String pad_decimals(int p_digits) const; String pad_zeros(int p_digits) const; + String sprintf(const Array& values) const; static String num(double p_num,int p_decimals=-1); static String num_scientific(double p_num); static String num_real(double p_num); @@ -203,7 +205,7 @@ public: String xml_unescape() const; String c_escape() const; String c_unescape() const; - + String percent_encode() const; String percent_decode() const; diff --git a/core/variant_op.cpp b/core/variant_op.cpp index ec43b1275cb..533a9d69527 100644 --- a/core/variant_op.cpp +++ b/core/variant_op.cpp @@ -736,6 +736,20 @@ void Variant::evaluate(const Operator& p_op, const Variant& p_a, const Variant& } #endif _RETURN( p_a._data._int % p_b._data._int ); + + } else if (p_a.type==STRING) { + const String *str=reinterpret_cast(p_a._data._mem); + + if (p_b.type==ARRAY) { + // e.g. "frog %s %d" % ["fish", 12] + const Array *arr=reinterpret_cast(p_b._data._mem); + _RETURN(str->sprintf(*arr)); + } else { + // e.g. "frog %d" % 12 + Array arr; + arr.push_back(p_b); + _RETURN(str->sprintf(arr)); + } } r_valid=false; From bb6daaa02ede319dae34733221bdae8b4f999a99 Mon Sep 17 00:00:00 2001 From: marynate Date: Sun, 11 Jan 2015 11:04:57 +0800 Subject: [PATCH 05/36] Fix compile compile error on windows platform --- platform/windows/os_windows.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index a3a26ddb25f..45d13da8287 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -134,7 +134,7 @@ int OS_Windows::get_video_driver_count() const { } const char * OS_Windows::get_video_driver_name(int p_driver) const { - return p_driver=="GLES2"; + return "GLES2"; } OS::VideoMode OS_Windows::get_default_video_mode() const { From 2fd9292b12b6a5d8455ab3d7305ee55ebae64c9b Mon Sep 17 00:00:00 2001 From: Nathan Warden Date: Fri, 16 Jan 2015 23:17:12 -0500 Subject: [PATCH 06/36] Changed the "Start the scene (F5)." tooltip to say "Play the project (F5)." --- tools/editor/editor_node.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/editor/editor_node.cpp b/tools/editor/editor_node.cpp index f859d195040..692eeb77b84 100644 --- a/tools/editor/editor_node.cpp +++ b/tools/editor/editor_node.cpp @@ -3552,7 +3552,7 @@ EditorNode::EditorNode() { play_button->set_icon(gui_base->get_icon("MainPlay","EditorIcons")); play_button->set_focus_mode(Control::FOCUS_NONE); play_button->connect("pressed", this,"_menu_option",make_binds(RUN_PLAY)); - play_button->set_tooltip("Start the scene (F5)."); + play_button->set_tooltip("Play the project (F5)."); From 5a4ef1c2cc400ff7fe67714435cadb070dc9cdd5 Mon Sep 17 00:00:00 2001 From: Dana Olson Date: Sat, 17 Jan 2015 14:05:26 -0500 Subject: [PATCH 07/36] fixes --- tools/editor/plugins/script_editor_plugin.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/editor/plugins/script_editor_plugin.cpp b/tools/editor/plugins/script_editor_plugin.cpp index 20aeb05a507..3070079fa1f 100644 --- a/tools/editor/plugins/script_editor_plugin.cpp +++ b/tools/editor/plugins/script_editor_plugin.cpp @@ -630,7 +630,7 @@ bool ScriptEditor::_test_script_times_on_disk() { if (!all_ok) - if (bool(EDITOR_DEF("text_editor/autoreload_changed_scripts",false))) + if (bool(EDITOR_DEF("text_editor/auto_reload_changed_scripts",false))) script_editor->_reload_scripts(); else disk_changed->call_deferred("popup_centered_ratio",0.5); @@ -1805,6 +1805,7 @@ ScriptEditorPlugin::ScriptEditorPlugin(EditorNode *p_node) { script_editor->hide(); + EDITOR_DEF("text_editor/auto_reload_changed_scripts",false); EDITOR_DEF("external_editor/use_external_editor",false); EDITOR_DEF("external_editor/exec_path",""); EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING,"external_editor/exec_path",PROPERTY_HINT_GLOBAL_FILE)); From eac0de398fe48422f7e88509ff04a66667a95284 Mon Sep 17 00:00:00 2001 From: Dana Olson Date: Sat, 17 Jan 2015 14:19:57 -0500 Subject: [PATCH 08/36] ignore and remove .fscache files. closes #1249 --- .gitignore | 1 + demos/2d/hexamap/.fscache | 33 ---------------------- demos/2d/polygon_path_finder_demo/.fscache | 4 --- 3 files changed, 1 insertion(+), 37 deletions(-) delete mode 100644 demos/2d/hexamap/.fscache delete mode 100644 demos/2d/polygon_path_finder_demo/.fscache diff --git a/.gitignore b/.gitignore index 4aee83c13f3..f3a1b9693cd 100644 --- a/.gitignore +++ b/.gitignore @@ -19,6 +19,7 @@ tools/editor/register_exporters.cpp tools/editor/doc_data_compressed.h tools/editor/editor_icons.cpp -fpic +.fscache # Android specific platform/android/java/local.properties diff --git a/demos/2d/hexamap/.fscache b/demos/2d/hexamap/.fscache deleted file mode 100644 index 60aa69b645f..00000000000 --- a/demos/2d/hexamap/.fscache +++ /dev/null @@ -1,33 +0,0 @@ -::res://::1412302385 -WWT-01.png::ImageTexture::1412126473:: -WWT-02.png::ImageTexture::1412126474:: -WWT-03.png::ImageTexture::1412126474:: -WWT-04.png::ImageTexture::1412126474:: -WWT-05.png::ImageTexture::1412126474:: -WWT-06.png::ImageTexture::1412126474:: -WWT-07.png::ImageTexture::1412126474:: -WWT-08.png::ImageTexture::1412126474:: -WWT-09.png::ImageTexture::1412126474:: -WWT-10.png::ImageTexture::1412126474:: -WWT-11.png::ImageTexture::1412126475:: -WWT-12.png::ImageTexture::1412126475:: -WWT-13.png::ImageTexture::1412126475:: -WWT-14.png::ImageTexture::1412126475:: -WWT-15.png::ImageTexture::1412126475:: -WWT-16.png::ImageTexture::1412126475:: -WWT-17.png::ImageTexture::1412126475:: -WWT-18.png::ImageTexture::1412126475:: -WWT-19.png::ImageTexture::1412126476:: -WWT-20.png::ImageTexture::1412126476:: -WWT-21.png::ImageTexture::1412126476:: -WWT-22.png::ImageTexture::1412126476:: -WWT-23.png::ImageTexture::1412126476:: -WWT-24.png::ImageTexture::1412126476:: -WWT-25.png::ImageTexture::1412126476:: -WWT-26.png::ImageTexture::1412126476:: -map.scn::PackedScene::1412127344:: -tiles.scn::PackedScene::1412126994:: -tileset.res::TileSet::1412127001:: -troll.gd::GDScript::1412302377:: -troll.png::ImageTexture::1412302385:: -troll.scn::PackedScene::1412302380:: diff --git a/demos/2d/polygon_path_finder_demo/.fscache b/demos/2d/polygon_path_finder_demo/.fscache deleted file mode 100644 index f699ca5849f..00000000000 --- a/demos/2d/polygon_path_finder_demo/.fscache +++ /dev/null @@ -1,4 +0,0 @@ -::res://::1421147952 -icon.png::ImageTexture::1420046079:: -new_scene_poly_with_holes.scn::PackedScene::1421147952:: -polygonpathfinder.gd::GDScript::1421146502:: From fa62125e05b30f6a7df482af924aa8e552760f07 Mon Sep 17 00:00:00 2001 From: Manuel Lagang Date: Sat, 17 Jan 2015 22:40:01 -0800 Subject: [PATCH 09/36] Modifiers are unset on events for the modifier key itself This patch removes modifiers when processing key events for the particular modifier key. For example, previously a Shift keypress would register as a Shift + Shift modifier event. This would cause issues when a modifier key as the action key in the input map, because unpresses of the modifier key don't match as matching inputs for that action. E.g. if Shift is used as an action, the stored action event is Shift + Shift modifier (as indicated in the editor as "Shift + Shift". The unpress event does not have the Shift modifier set, so the event of unpressing Shift + no modifier doesn't match the action which has the modifier set. This patch removes the shift modifier on just pressing the Shift key down, so the action event is registered as just Shift with no modifier (as indicated in the editor as "Shift"), which matches the unpress event. --- platform/windows/os_windows.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index ce791336649..bb911a99a40 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -589,10 +589,11 @@ LRESULT OS_Windows::WndProc(HWND hWnd,UINT uMsg, WPARAM wParam, LPARAM lParam) { ERR_BREAK(key_event_pos >= KEY_EVENT_BUFFER_SIZE); + // Make sure we don't include modifiers for the modifier key itself. KeyEvent ke; - ke.mod_state.shift=shift_mem; - ke.mod_state.alt=alt_mem; - ke.mod_state.control=control_mem; + ke.mod_state.shift= (wParam != VK_SHIFT) ? shift_mem : false; + ke.mod_state.alt= (! (wParam == VK_MENU && (uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN))) ? alt_mem : false; + ke.mod_state.control= (wParam != VK_CONTROL) ? control_mem : false; ke.mod_state.meta=meta_mem; ke.uMsg=uMsg; From a4f40ec3be67e6bd0498e18bc9c9f66274d29a48 Mon Sep 17 00:00:00 2001 From: Manuel Lagang Date: Sat, 17 Jan 2015 23:06:20 -0800 Subject: [PATCH 10/36] Fix whitespace on previous commit Choose tabs or spaces, not both! --- platform/windows/os_windows.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index bb911a99a40..57b6a8f8165 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -589,7 +589,7 @@ LRESULT OS_Windows::WndProc(HWND hWnd,UINT uMsg, WPARAM wParam, LPARAM lParam) { ERR_BREAK(key_event_pos >= KEY_EVENT_BUFFER_SIZE); - // Make sure we don't include modifiers for the modifier key itself. + // Make sure we don't include modifiers for the modifier key itself. KeyEvent ke; ke.mod_state.shift= (wParam != VK_SHIFT) ? shift_mem : false; ke.mod_state.alt= (! (wParam == VK_MENU && (uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN))) ? alt_mem : false; From 92cc7b840eff99e90b64caad6883aefbe4c3dd1e Mon Sep 17 00:00:00 2001 From: Nathan Warden Date: Mon, 19 Jan 2015 15:47:50 -0500 Subject: [PATCH 11/36] Fixed a bug where a user could add a cyclical dependency, causing a crash. --- tools/editor/scene_tree_dock.cpp | 29 ++++++++++++++++++++++++++++- tools/editor/scene_tree_dock.h | 1 + 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/tools/editor/scene_tree_dock.cpp b/tools/editor/scene_tree_dock.cpp index cff39135794..d8d713ee405 100644 --- a/tools/editor/scene_tree_dock.cpp +++ b/tools/editor/scene_tree_dock.cpp @@ -79,7 +79,15 @@ Node* SceneTreeDock::instance(const String& p_file) { //accept->get_cancel()->hide(); accept->get_ok()->set_text("Ugh"); accept->set_text(String("Error loading scene from ")+p_file); - accept->popup_centered(Size2(300,70));; + accept->popup_centered(Size2(300,70)); + return NULL; + } + + if (_cyclical_dependency_exists(edited_scene->get_filename(), instanced_scene)) { + + accept->get_ok()->set_text("Ok"); + accept->set_text(String("Cannot instance the scene '")+p_file+String("' because the current scene exists within one of its' nodes.")); + accept->popup_centered(Size2(300,90)); return NULL; } @@ -100,6 +108,25 @@ Node* SceneTreeDock::instance(const String& p_file) { } +bool SceneTreeDock::_cyclical_dependency_exists(const String& p_target_scene_path, Node* p_desired_node) { + int childCount = p_desired_node->get_child_count(); + + if (p_desired_node->get_filename()==p_target_scene_path) { + return true; + } + + for (int i=0;iget_child(i); + + if(_cyclical_dependency_exists(p_target_scene_path,child)) { + return true; + } + } + + return false; +} + + static String _get_name_num_separator() { switch(EditorSettings::get_singleton()->get("scenetree_editor/duplicate_node_name_num_separator").operator int()) { case 0: return ""; diff --git a/tools/editor/scene_tree_dock.h b/tools/editor/scene_tree_dock.h index ac5391f3b9d..92ebfc5bee7 100644 --- a/tools/editor/scene_tree_dock.h +++ b/tools/editor/scene_tree_dock.h @@ -102,6 +102,7 @@ class SceneTreeDock : public VBoxContainer { void _load_request(const String& p_path); void _script_open_request(const Ref