Переглянути джерело

Moved folding outside the resource files, now saved outside the project.

Juan Linietsky 6 роки тому
батько
коміт
e647342140

+ 10 - 0
core/io/resource_loader.cpp

@@ -259,6 +259,10 @@ RES ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p
 	}
 #endif
 
+	if (_loaded_callback) {
+		_loaded_callback(res, p_path);
+	}
+
 	return res;
 }
 
@@ -635,6 +639,12 @@ void ResourceLoader::clear_path_remaps() {
 	path_remaps.clear();
 }
 
+void ResourceLoader::set_load_callback(ResourceLoadedCallback p_callback) {
+	_loaded_callback = p_callback;
+}
+
+ResourceLoadedCallback ResourceLoader::_loaded_callback = NULL;
+
 ResourceLoadErrorNotify ResourceLoader::err_notify = NULL;
 void *ResourceLoader::err_notify_ud = NULL;
 

+ 4 - 0
core/io/resource_loader.h

@@ -78,6 +78,7 @@ typedef void (*ResourceLoadErrorNotify)(void *p_ud, const String &p_text);
 typedef void (*DependencyErrorNotify)(void *p_ud, const String &p_loading, const String &p_which, const String &p_type);
 
 typedef Error (*ResourceLoaderImport)(const String &p_path);
+typedef void (*ResourceLoadedCallback)(RES p_resource, const String &p_path);
 
 class ResourceLoader {
 
@@ -106,6 +107,8 @@ class ResourceLoader {
 	//internal load function
 	static RES _load(const String &p_path, const String &p_original_path, const String &p_type_hint, bool p_no_cache, Error *r_error);
 
+	static ResourceLoadedCallback _loaded_callback;
+
 public:
 	static Ref<ResourceInteractiveLoader> load_interactive(const String &p_path, const String &p_type_hint = "", bool p_no_cache = false, Error *r_error = NULL);
 	static RES load(const String &p_path, const String &p_type_hint = "", bool p_no_cache = false, Error *r_error = NULL);
@@ -150,6 +153,7 @@ public:
 	static void load_translation_remaps();
 	static void clear_translation_remaps();
 
+	static void set_load_callback(ResourceLoadedCallback p_callback);
 	static ResourceLoaderImport import;
 };
 

+ 1 - 1
core/io/resource_saver.cpp

@@ -90,7 +90,7 @@ Error ResourceSaver::save(const String &p_path, const RES &p_resource, uint32_t
 				rwcopy->set_path(old_path);
 
 			if (save_callback && p_path.begins_with("res://"))
-				save_callback(p_path);
+				save_callback(p_resource, p_path);
 
 			return OK;
 		} else {

+ 1 - 1
core/io/resource_saver.h

@@ -46,7 +46,7 @@ public:
 	virtual ~ResourceFormatSaver() {}
 };
 
-typedef void (*ResourceSavedCallback)(const String &p_path);
+typedef void (*ResourceSavedCallback)(Ref<Resource> p_resource, const String &p_path);
 
 class ResourceSaver {
 

+ 1 - 25
core/object.cpp

@@ -440,16 +440,6 @@ void Object::set(const StringName &p_name, const Variant &p_value, bool *r_valid
 		if (r_valid)
 			*r_valid = true;
 		return;
-#ifdef TOOLS_ENABLED
-	} else if (p_name == CoreStringNames::get_singleton()->_sections_unfolded) {
-		Array arr = p_value;
-		for (int i = 0; i < arr.size(); i++) {
-			editor_section_folding.insert(arr[i]);
-		}
-		if (r_valid)
-			*r_valid = true;
-		return;
-#endif
 	}
 
 	//something inside the object... :|
@@ -520,16 +510,7 @@ Variant Object::get(const StringName &p_name, bool *r_valid) const {
 		if (r_valid)
 			*r_valid = true;
 		return ret;
-#ifdef TOOLS_ENABLED
-	} else if (p_name == CoreStringNames::get_singleton()->_sections_unfolded) {
-		Array array;
-		for (Set<String>::Element *E = editor_section_folding.front(); E; E = E->next()) {
-			array.push_back(E->get());
-		}
-		if (r_valid)
-			*r_valid = true;
-		return array;
-#endif
+
 	} else {
 		//something inside the object... :|
 		bool success = _getv(p_name, ret);
@@ -657,11 +638,6 @@ void Object::get_property_list(List<PropertyInfo> *p_list, bool p_reversed) cons
 #endif
 		p_list->push_back(PropertyInfo(Variant::OBJECT, "script", PROPERTY_HINT_RESOURCE_TYPE, "Script", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_STORE_IF_NONZERO));
 	}
-#ifdef TOOLS_ENABLED
-	if (editor_section_folding.size()) {
-		p_list->push_back(PropertyInfo(Variant::ARRAY, CoreStringNames::get_singleton()->_sections_unfolded, PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
-	}
-#endif
 	if (!metadata.empty())
 		p_list->push_back(PropertyInfo(Variant::DICTIONARY, "__meta__", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL | PROPERTY_USAGE_STORE_IF_NONZERO));
 	if (script_instance && !p_reversed) {

+ 3 - 0
core/object.h

@@ -723,6 +723,9 @@ public:
 #ifdef TOOLS_ENABLED
 	void editor_set_section_unfold(const String &p_section, bool p_unfolded);
 	bool editor_is_section_unfolded(const String &p_section);
+	const Set<String> &editor_get_section_folding() const { return editor_section_folding; }
+	void editor_clear_section_folding() { editor_section_folding.clear(); }
+
 #endif
 
 	//used by script languages to store binding data

+ 0 - 6
editor/editor_file_system.cpp

@@ -1305,11 +1305,6 @@ void EditorFileSystem::_save_late_updated_files() {
 	}
 }
 
-void EditorFileSystem::_resource_saved(const String &p_path) {
-
-	EditorFileSystem::get_singleton()->update_file(p_path);
-}
-
 Vector<String> EditorFileSystem::_get_dependencies(const String &p_path) {
 
 	List<String> deps;
@@ -1772,7 +1767,6 @@ EditorFileSystem::EditorFileSystem() {
 	abort_scan = false;
 	scanning_changes = false;
 	scanning_changes_done = false;
-	ResourceSaver::set_save_callback(_resource_saved);
 
 	DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES);
 	if (da->change_dir("res://.import") != OK) {

+ 0 - 2
editor/editor_file_system.h

@@ -204,8 +204,6 @@ class EditorFileSystem : public Node {
 
 	bool _update_scan_actions();
 
-	static void _resource_saved(const String &p_path);
-
 	void _update_extensions();
 
 	void _reimport_file(const String &p_file);

+ 168 - 0
editor/editor_folding.cpp

@@ -0,0 +1,168 @@
+#include "editor_folding.h"
+
+#include "editor_settings.h"
+
+PoolVector<String> EditorFolding::_get_unfolds(const Object *p_object) {
+
+	PoolVector<String> sections;
+	sections.resize(p_object->editor_get_section_folding().size());
+	if (sections.size()) {
+		PoolVector<String>::Write w = sections.write();
+		int idx = 0;
+		for (const Set<String>::Element *E = p_object->editor_get_section_folding().front(); E; E = E->next()) {
+			w[idx++] = E->get();
+		}
+	}
+
+	return sections;
+}
+
+void EditorFolding::save_resource_folding(const RES &p_resource, const String &p_path) {
+	Ref<ConfigFile> config;
+	config.instance();
+	PoolVector<String> unfolds = _get_unfolds(p_resource.ptr());
+	config->set_value("folding", "sections_unfolded", unfolds);
+
+	String path = EditorSettings::get_singleton()->get_project_settings_dir();
+	String file = p_path.get_file() + "-folding-" + p_path.md5_text() + ".cfg";
+	file = EditorSettings::get_singleton()->get_project_settings_dir().plus_file(file);
+	config->save(file);
+}
+
+void EditorFolding::_set_unfolds(Object *p_object, const PoolVector<String> &p_unfolds) {
+
+	int uc = p_unfolds.size();
+	PoolVector<String>::Read r = p_unfolds.read();
+	p_object->editor_clear_section_folding();
+	for (int i = 0; i < uc; i++) {
+		p_object->editor_set_section_unfold(r[i], true);
+	}
+}
+
+void EditorFolding::load_resource_folding(RES p_resource, const String &p_path) {
+
+	Ref<ConfigFile> config;
+	config.instance();
+
+	String path = EditorSettings::get_singleton()->get_project_settings_dir();
+	String file = p_path.get_file() + "-folding-" + p_path.md5_text() + ".cfg";
+	file = EditorSettings::get_singleton()->get_project_settings_dir().plus_file(file);
+
+	if (config->load(file) != OK) {
+		return;
+	}
+
+	PoolVector<String> unfolds;
+
+	if (config->has_section_key("folding", "sections_unfolded")) {
+		unfolds = config->get_value("folding", "sections_unfolded");
+	}
+	_set_unfolds(p_resource.ptr(), unfolds);
+}
+
+void EditorFolding::_fill_folds(const Node *p_root, const Node *p_node, Array &p_folds, Array &resource_folds, Set<RES> &resources) {
+	if (p_root != p_node) {
+		if (!p_node->get_owner()) {
+			return; //not owned, bye
+		}
+		if (p_node->get_owner() != p_root && !p_root->is_editable_instance(p_node)) {
+			return;
+		}
+	}
+
+	PoolVector<String> unfolds = _get_unfolds(p_node);
+
+	if (unfolds.size()) {
+		p_folds.push_back(p_root->get_path_to(p_node));
+		p_folds.push_back(unfolds);
+	}
+
+	List<PropertyInfo> plist;
+	p_node->get_property_list(&plist);
+	for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) {
+		if (E->get().type == Variant::OBJECT) {
+			RES res = p_node->get(E->get().name);
+			if (res.is_valid() && !resources.has(res) && res->get_path() != String() && !res->get_path().is_resource_file()) {
+
+				PoolVector<String> res_unfolds = _get_unfolds(res.ptr());
+				resource_folds.push_back(res->get_path());
+				resource_folds.push_back(res_unfolds);
+				resources.insert(res);
+			}
+		}
+	}
+
+	for (int i = 0; i < p_node->get_child_count(); i++) {
+		_fill_folds(p_root, p_node->get_child(i), p_folds, resource_folds, resources);
+	}
+}
+void EditorFolding::save_scene_folding(const Node *p_scene, const String &p_path) {
+
+	Ref<ConfigFile> config;
+	config.instance();
+
+	Array unfolds, res_unfolds;
+	Set<RES> resources;
+	_fill_folds(p_scene, p_scene, unfolds, res_unfolds, resources);
+
+	config->set_value("folding", "node_unfolds", unfolds);
+	config->set_value("folding", "resource_unfolds", res_unfolds);
+
+	String path = EditorSettings::get_singleton()->get_project_settings_dir();
+	String file = p_path.get_file() + "-folding-" + p_path.md5_text() + ".cfg";
+	file = EditorSettings::get_singleton()->get_project_settings_dir().plus_file(file);
+	print_line("save folding for: " + file);
+	config->save(file);
+}
+void EditorFolding::load_scene_folding(Node *p_scene, const String &p_path) {
+
+	Ref<ConfigFile> config;
+	config.instance();
+
+	String path = EditorSettings::get_singleton()->get_project_settings_dir();
+	String file = p_path.get_file() + "-folding-" + p_path.md5_text() + ".cfg";
+	file = EditorSettings::get_singleton()->get_project_settings_dir().plus_file(file);
+
+	if (config->load(file) != OK) {
+		return;
+	}
+
+	Array unfolds;
+	if (config->has_section_key("folding", "node_unfolds")) {
+		unfolds = config->get_value("folding", "node_unfolds");
+	}
+	Array res_unfolds;
+	if (config->has_section_key("folding", "resource_unfolds")) {
+		res_unfolds = config->get_value("folding", "resource_unfolds");
+	}
+
+	ERR_FAIL_COND(unfolds.size() & 1);
+	ERR_FAIL_COND(res_unfolds.size() & 1);
+
+	for (int i = 0; i < unfolds.size(); i += 2) {
+		NodePath path = unfolds[i];
+		PoolVector<String> un = unfolds[i + 1];
+		Node *node = p_scene->get_node(path);
+		if (!node) {
+			continue;
+		}
+		_set_unfolds(node, un);
+	}
+
+	for (int i = 0; i < res_unfolds.size(); i += 2) {
+		String path = res_unfolds[i];
+		RES res;
+		if (ResourceCache::has(path)) {
+			res = RES(ResourceCache::get(path));
+		}
+		if (res.is_null()) {
+			continue;
+		}
+
+		PoolVector<String> unfolds = res_unfolds[i + 1];
+		_set_unfolds(res.ptr(), unfolds);
+	}
+}
+
+EditorFolding::EditorFolding() {
+}

+ 23 - 0
editor/editor_folding.h

@@ -0,0 +1,23 @@
+#ifndef EDITOR_FOLDING_H
+#define EDITOR_FOLDING_H
+
+#include "scene/main/node.h"
+
+class EditorFolding {
+
+	PoolVector<String> _get_unfolds(const Object *p_object);
+	void _set_unfolds(Object *p_object, const PoolVector<String> &p_unfolds);
+
+	void _fill_folds(const Node *p_root, const Node *p_node, Array &p_folds, Array &resource_folds, Set<RES> &resources);
+
+public:
+	void save_resource_folding(const RES &p_resource, const String &p_path);
+	void load_resource_folding(RES p_resource, const String &p_path);
+
+	void save_scene_folding(const Node *p_scene, const String &p_path);
+	void load_scene_folding(Node *p_scene, const String &p_path);
+
+	EditorFolding();
+};
+
+#endif // EDITOR_FOLDING_H

+ 23 - 2
editor/editor_node.cpp

@@ -1061,6 +1061,9 @@ void EditorNode::_save_scene(String p_file, int idx) {
 			set_current_version(editor_data.get_undo_redo().get_version());
 		else
 			editor_data.set_edited_scene_version(0, idx);
+
+		editor_folding.save_scene_folding(scene, p_file);
+
 		_update_title();
 		_update_scene_tabs();
 	} else {
@@ -2907,6 +2910,8 @@ Error EditorNode::load_scene(const String &p_scene, bool p_ignore_broken_deps, b
 	_update_scene_tabs();
 	_add_to_recent_scenes(lpath);
 
+	editor_folding.load_scene_folding(new_scene, lpath);
+
 	prev_scene->set_disabled(previous_scenes.size() == 0);
 	opening_prev = false;
 
@@ -4544,6 +4549,19 @@ void EditorNode::_video_driver_selected(int p_which) {
 	_update_video_driver_color();
 }
 
+void EditorNode::_resource_saved(RES p_resource, const String &p_path) {
+	if (EditorFileSystem::get_singleton()) {
+		EditorFileSystem::get_singleton()->update_file(p_path);
+	}
+
+	singleton->editor_folding.save_resource_folding(p_resource, p_path);
+}
+
+void EditorNode::_resource_loaded(RES p_resource, const String &p_path) {
+
+	singleton->editor_folding.load_resource_folding(p_resource, p_path);
+}
+
 void EditorNode::_bind_methods() {
 
 	ClassDB::bind_method("_menu_option", &EditorNode::_menu_option);
@@ -4733,7 +4751,7 @@ EditorNode::EditorNode() {
 	ResourceLoader::set_timestamp_on_load(true);
 	ResourceSaver::set_timestamp_on_save(true);
 
-    default_value_cache = memnew( EditorDefaultClassValueCache );
+	default_value_cache = memnew(EditorDefaultClassValueCache);
 
 	{ //register importers at the beginning, so dialogs are created with the right extensions
 		Ref<ResourceImporterTexture> import_texture;
@@ -5831,6 +5849,9 @@ EditorNode::EditorNode() {
 	print_handler.userdata = this;
 	add_print_handler(&print_handler);
 
+	ResourceSaver::set_save_callback(_resource_saved);
+	ResourceLoader::set_load_callback(_resource_loaded);
+
 #ifdef OSX_ENABLED
 	ED_SHORTCUT("editor/editor_2d", TTR("Open 2D Editor"), KEY_MASK_ALT | KEY_1);
 	ED_SHORTCUT("editor/editor_3d", TTR("Open 3D Editor"), KEY_MASK_ALT | KEY_2);
@@ -5859,7 +5880,7 @@ EditorNode::~EditorNode() {
 	memdelete(editor_plugins_force_input_forwarding);
 	memdelete(file_server);
 	memdelete(progress_hb);
-    memdelete(default_value_cache);
+	memdelete(default_value_cache);
 	EditorSettings::destroy();
 }
 

+ 6 - 1
editor/editor_node.h

@@ -38,6 +38,7 @@
 #include "editor/editor_about.h"
 #include "editor/editor_data.h"
 #include "editor/editor_export.h"
+#include "editor/editor_folding.h"
 #include "editor/editor_inspector.h"
 #include "editor/editor_log.h"
 #include "editor/editor_name_dialog.h"
@@ -271,7 +272,7 @@ private:
 
 	Ref<Theme> theme;
 
-    EditorDefaultClassValueCache *default_value_cache;
+	EditorDefaultClassValueCache *default_value_cache;
 	PopupMenu *recent_scenes;
 	SceneTreeDock *scene_tree_dock;
 	InspectorDock *inspector_dock;
@@ -386,6 +387,7 @@ private:
 	EditorSelection *editor_selection;
 	ProjectExportDialog *project_export;
 	EditorResourcePreview *resource_preview;
+	EditorFolding editor_folding;
 
 	EditorFileServer *file_server;
 
@@ -601,6 +603,9 @@ private:
 	PrintHandlerList print_handler;
 	static void _print_handler(void *p_this, const String &p_string, bool p_error);
 
+	static void _resource_saved(RES p_resource, const String &p_path);
+	static void _resource_loaded(RES p_resource, const String &p_path);
+
 protected:
 	void _notification(int p_what);
 	static void _bind_methods();

+ 1 - 1
scene/main/node.cpp

@@ -1835,7 +1835,7 @@ void Node::set_editable_instance(Node *p_node, bool p_editable) {
 	}
 }
 
-bool Node::is_editable_instance(Node *p_node) const {
+bool Node::is_editable_instance(const Node *p_node) const {
 
 	if (!p_node)
 		return false; //easier, null is never editable :)

+ 1 - 1
scene/main/node.h

@@ -303,7 +303,7 @@ public:
 	String get_filename() const;
 
 	void set_editable_instance(Node *p_node, bool p_editable);
-	bool is_editable_instance(Node *p_node) const;
+	bool is_editable_instance(const Node *p_node) const;
 	void set_editable_instances(const HashMap<NodePath, int> &p_editable_instances);
 	HashMap<NodePath, int> get_editable_instances() const;