summaryrefslogtreecommitdiff
path: root/tools/editor
diff options
context:
space:
mode:
authorJuan Linietsky <reduzio@gmail.com>2015-12-13 20:39:01 -0300
committerJuan Linietsky <reduzio@gmail.com>2015-12-13 20:39:01 -0300
commit7f96f0603e16a970c7b0ea1fba936e56baf80d4a (patch)
treef470757f0dc5669ed7fbd6c720339dde0d7ce04d /tools/editor
parent72ff61963b207cc41664f7aeb39448d0a2f8369f (diff)
-scenes are properly reloaded when a dependency changes, fixes #2896
(it's clevery done so local changes to scenes are kept even if unsaved)
Diffstat (limited to 'tools/editor')
-rw-r--r--tools/editor/editor_data.cpp90
-rw-r--r--tools/editor/editor_data.h3
-rw-r--r--tools/editor/editor_import_export.cpp1
-rw-r--r--tools/editor/editor_node.cpp29
-rw-r--r--tools/editor/editor_node.h1
5 files changed, 123 insertions, 1 deletions
diff --git a/tools/editor/editor_data.cpp b/tools/editor/editor_data.cpp
index a6aedf2706..e9f9e09acd 100644
--- a/tools/editor/editor_data.cpp
+++ b/tools/editor/editor_data.cpp
@@ -31,6 +31,9 @@
#include "editor_settings.h"
#include "os/dir_access.h"
#include "io/resource_loader.h"
+#include "scene/resources/packed_scene.h"
+#include "os/file_access.h"
+#include "editor_node.h"
void EditorHistory::_cleanup_history() {
@@ -493,6 +496,93 @@ void EditorData::remove_scene(int p_idx){
edited_scene.remove(p_idx);
}
+
+bool EditorData::_find_updated_instances(Node* p_root,Node *p_node,Set<String> &checked_paths) {
+
+ if (p_root!=p_node && p_node->get_owner()!=p_root && !p_root->is_editable_instance(p_node->get_owner()))
+ return false;
+
+ Ref<SceneState> ss;
+
+ if (p_node==p_root) {
+ ss=p_node->get_scene_inherited_state();
+ } else if (p_node->get_filename()!=String()){
+ ss=p_node->get_scene_instance_state();
+ }
+
+ if (ss.is_valid()) {
+ String path = ss->get_path();
+
+ if (!checked_paths.has(path)) {
+
+ uint64_t modified_time = FileAccess::get_modified_time(path);
+ if (modified_time!=ss->get_last_modified_time()) {
+ return true; //external scene changed
+ }
+
+ checked_paths.insert(path);
+ }
+
+ }
+
+ for(int i=0;i<p_node->get_child_count();i++) {
+
+ bool found = _find_updated_instances(p_root,p_node->get_child(i),checked_paths);
+ if (found)
+ return true;
+ }
+
+ return false;
+}
+
+
+bool EditorData::check_and_update_scene(int p_idx) {
+
+ ERR_FAIL_INDEX_V(p_idx,edited_scene.size(),false);
+ if (!edited_scene[p_idx].root)
+ return false;
+
+ Set<String> checked_scenes;
+
+
+ bool must_reload = _find_updated_instances(edited_scene[p_idx].root,edited_scene[p_idx].root,checked_scenes);
+
+ if (must_reload) {
+ Ref<PackedScene> pscene;
+ pscene.instance();
+
+ EditorProgress ep("update_scene","Updating Scene",2);
+ ep.step("Storing local changes..",0);
+ //pack first, so it stores diffs to previous version of saved scene
+ Error err = pscene->pack(edited_scene[p_idx].root);
+ ERR_FAIL_COND_V(err!=OK,false);
+ ep.step("Updating scene..",1);
+ Node *new_scene = pscene->instance(true);
+ ERR_FAIL_COND_V(!new_scene,false);
+
+ //transfer selection
+ List<Node*> new_selection;
+ for (List<Node*>::Element *E=edited_scene[p_idx].selection.front();E;E=E->next()) {
+ NodePath p = edited_scene[p_idx].root->get_path_to(E->get());
+ Node *new_node = new_scene->get_node(p);
+ if (new_node)
+ new_selection.push_back(new_node);
+ }
+
+ new_scene->set_filename( edited_scene[p_idx].root->get_filename() );
+
+ memdelete(edited_scene[p_idx].root);
+ edited_scene[p_idx].root=new_scene;
+ edited_scene[p_idx].selection=new_selection;
+
+ return true;
+
+ }
+
+ return false;
+
+}
+
int EditorData::get_edited_scene() const {
return current_edited_scene;
diff --git a/tools/editor/editor_data.h b/tools/editor/editor_data.h
index a90a071c39..51af7d41bd 100644
--- a/tools/editor/editor_data.h
+++ b/tools/editor/editor_data.h
@@ -144,6 +144,8 @@ private:
Vector<EditedScene> edited_scene;
int current_edited_scene;
+ bool _find_updated_instances(Node* p_root,Node *p_node,Set<String> &checked_paths);
+
public:
EditorPlugin* get_editor(Object *p_object);
@@ -193,6 +195,7 @@ public:
void clear_edited_scenes();
void set_edited_scene_live_edit_root(const NodePath& p_root);
NodePath get_edited_scene_live_edit_root();
+ bool check_and_update_scene(int p_idx);
void set_plugin_window_layout(Ref<ConfigFile> p_layout);
diff --git a/tools/editor/editor_import_export.cpp b/tools/editor/editor_import_export.cpp
index 3cd5cfd629..b6c68d05be 100644
--- a/tools/editor/editor_import_export.cpp
+++ b/tools/editor/editor_import_export.cpp
@@ -43,6 +43,7 @@
#include "tools/editor/plugins/script_editor_plugin.h"
#include "io/zip_io.h"
+
String EditorImportPlugin::validate_source_path(const String& p_path) {
String gp = Globals::get_singleton()->globalize_path(p_path);
diff --git a/tools/editor/editor_node.cpp b/tools/editor/editor_node.cpp
index 3dbca760f0..05df0a3e48 100644
--- a/tools/editor/editor_node.cpp
+++ b/tools/editor/editor_node.cpp
@@ -955,7 +955,23 @@ void EditorNode::_save_scene(String p_file) {
_set_scene_metadata();
- Ref<PackedScene> sdata = memnew( PackedScene );
+
+
+ Ref<PackedScene> sdata;
+
+ if (ResourceCache::has(p_file)) {
+ // something may be referencing this resource and we are good with that.
+ // we must update it, but also let the previous scene state go, as
+ // old version still work for referencing changes in instanced or inherited scenes
+
+ sdata = Ref<PackedScene>( ResourceCache::get(p_file)->cast_to<PackedScene>() );
+ if (sdata.is_valid())
+ sdata->recreate_state();
+ else
+ sdata.instance();
+ } else {
+ sdata.instance();
+ }
Error err = sdata->pack(scene);
@@ -3414,8 +3430,18 @@ void EditorNode::set_current_version(uint64_t p_version) {
bool EditorNode::is_changing_scene() const {
return changing_scene;
}
+
+void EditorNode::_clear_undo_history() {
+
+ get_undo_redo()->clear_history();
+}
+
void EditorNode::set_current_scene(int p_idx) {
+ if (editor_data.check_and_update_scene(p_idx)) {
+ call_deferred("_clear_undo_history");
+ }
+
changing_scene=true;
editor_data.save_edited_scene_state(editor_selection,&editor_history,_get_main_scene_state());
@@ -4113,6 +4139,7 @@ void EditorNode::_bind_methods() {
ObjectTypeDB::bind_method("_toggle_search_bar",&EditorNode::_toggle_search_bar);
ObjectTypeDB::bind_method("_clear_search_box",&EditorNode::_clear_search_box);
+ ObjectTypeDB::bind_method("_clear_undo_history",&EditorNode::_clear_undo_history);
ObjectTypeDB::bind_method(_MD("add_editor_import_plugin", "plugin"), &EditorNode::add_editor_import_plugin);
ObjectTypeDB::bind_method(_MD("remove_editor_import_plugin", "plugin"), &EditorNode::remove_editor_import_plugin);
diff --git a/tools/editor/editor_node.h b/tools/editor/editor_node.h
index bd25f27c59..c4429f943b 100644
--- a/tools/editor/editor_node.h
+++ b/tools/editor/editor_node.h
@@ -540,6 +540,7 @@ class EditorNode : public Node {
void _toggle_search_bar(bool p_pressed);
void _clear_search_box();
+ void _clear_undo_history();
protected:
void _notification(int p_what);