diff options
author | Juan Linietsky <reduzio@gmail.com> | 2015-12-13 20:39:01 -0300 |
---|---|---|
committer | Juan Linietsky <reduzio@gmail.com> | 2015-12-13 20:39:01 -0300 |
commit | 7f96f0603e16a970c7b0ea1fba936e56baf80d4a (patch) | |
tree | f470757f0dc5669ed7fbd6c720339dde0d7ce04d /tools/editor | |
parent | 72ff61963b207cc41664f7aeb39448d0a2f8369f (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.cpp | 90 | ||||
-rw-r--r-- | tools/editor/editor_data.h | 3 | ||||
-rw-r--r-- | tools/editor/editor_import_export.cpp | 1 | ||||
-rw-r--r-- | tools/editor/editor_node.cpp | 29 | ||||
-rw-r--r-- | tools/editor/editor_node.h | 1 |
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); |