Add reload and resave dialog when BT resource files change externally
This commit is contained in:
parent
6148a82f5e
commit
81e672b4d2
|
@ -19,6 +19,7 @@
|
||||||
#include "core/os/memory.h"
|
#include "core/os/memory.h"
|
||||||
#include "core/print_string.h"
|
#include "core/print_string.h"
|
||||||
#include "core/project_settings.h"
|
#include "core/project_settings.h"
|
||||||
|
#include "core/resource.h"
|
||||||
#include "core/script_language.h"
|
#include "core/script_language.h"
|
||||||
#include "core/string_name.h"
|
#include "core/string_name.h"
|
||||||
#include "core/typedefs.h"
|
#include "core/typedefs.h"
|
||||||
|
@ -568,10 +569,10 @@ void LimboAIEditor::_load_bt(String p_path) {
|
||||||
editor->edit_resource(bt);
|
editor->edit_resource(bt);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LimboAIEditor::edit_bt(Ref<BehaviorTree> p_behavior_tree) {
|
void LimboAIEditor::edit_bt(Ref<BehaviorTree> p_behavior_tree, bool p_force_refresh) {
|
||||||
ERR_FAIL_COND_MSG(p_behavior_tree.is_null(), "p_behavior_tree is null");
|
ERR_FAIL_COND_MSG(p_behavior_tree.is_null(), "p_behavior_tree is null");
|
||||||
|
|
||||||
if (task_tree->get_bt() == p_behavior_tree) {
|
if (!p_force_refresh && task_tree->get_bt() == p_behavior_tree) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -778,6 +779,67 @@ void LimboAIEditor::_on_task_dragged(Ref<BTTask> p_task, Ref<BTTask> p_to_task,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LimboAIEditor::_on_resources_reload(const Vector<String> &p_resources) {
|
||||||
|
for (int i = 0; i < p_resources.size(); i++) {
|
||||||
|
if (!ResourceCache::has(p_resources[i])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
String res_type = ResourceLoader::get_resource_type(p_resources[i]);
|
||||||
|
if (res_type == "BehaviorTree") {
|
||||||
|
for (int j = 0; j < history.size(); j++) {
|
||||||
|
if (history.get(j)->get_path() == p_resources[i]) {
|
||||||
|
disk_changed_files.insert(p_resources[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (disk_changed_files.size() > 0) {
|
||||||
|
disk_changed_list->clear();
|
||||||
|
disk_changed_list->set_hide_root(true);
|
||||||
|
disk_changed_list->create_item();
|
||||||
|
for (Set<String>::Element *E = disk_changed_files.front(); E; E = E->next()) {
|
||||||
|
// for (int i = 0; i < disk_changed_files.size(); i++) {
|
||||||
|
TreeItem *ti = disk_changed_list->create_item();
|
||||||
|
ti->set_text(0, E->get());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_visible()) {
|
||||||
|
EditorNode::get_singleton()->select_editor_by_name("LimboAI");
|
||||||
|
}
|
||||||
|
disk_changed->call_deferred("popup_centered_ratio", 0.5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LimboAIEditor::_reload_modified() {
|
||||||
|
for (Set<String>::Element *E = disk_changed_files.front(); E; E = E->next()) {
|
||||||
|
for (int j = 0; j < history.size(); j++) {
|
||||||
|
if (history.get(j)->get_path() == E->get()) {
|
||||||
|
dirty.erase(history.get(j));
|
||||||
|
history.get(j)->get_root_task()->clear_internal_resource_paths();
|
||||||
|
history.get(j)->reload_from_file();
|
||||||
|
if (j == idx_history) {
|
||||||
|
edit_bt(history.get(j), true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
disk_changed_files.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LimboAIEditor::_resave_modified(String _str) {
|
||||||
|
for (Set<String>::Element *E = disk_changed_files.front(); E; E = E->next()) {
|
||||||
|
for (int j = 0; j < history.size(); j++) {
|
||||||
|
if (history.get(j)->get_path() == E->get()) {
|
||||||
|
ResourceSaver::save(history.get(j)->get_path(), history.get(j));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
disk_changed->hide();
|
||||||
|
disk_changed_files.clear();
|
||||||
|
}
|
||||||
|
|
||||||
void LimboAIEditor::apply_changes() {
|
void LimboAIEditor::apply_changes() {
|
||||||
for (int i = 0; i < history.size(); i++) {
|
for (int i = 0; i < history.size(); i++) {
|
||||||
Ref<BehaviorTree> bt = history.get(i);
|
Ref<BehaviorTree> bt = history.get(i);
|
||||||
|
@ -853,7 +915,10 @@ void LimboAIEditor::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("_new_bt"), &LimboAIEditor::_new_bt);
|
ClassDB::bind_method(D_METHOD("_new_bt"), &LimboAIEditor::_new_bt);
|
||||||
ClassDB::bind_method(D_METHOD("_save_bt", "p_path"), &LimboAIEditor::_save_bt);
|
ClassDB::bind_method(D_METHOD("_save_bt", "p_path"), &LimboAIEditor::_save_bt);
|
||||||
ClassDB::bind_method(D_METHOD("_load_bt", "p_path"), &LimboAIEditor::_load_bt);
|
ClassDB::bind_method(D_METHOD("_load_bt", "p_path"), &LimboAIEditor::_load_bt);
|
||||||
ClassDB::bind_method(D_METHOD("edit_bt", "p_behavior_tree"), &LimboAIEditor::edit_bt);
|
ClassDB::bind_method(D_METHOD("edit_bt", "p_behavior_tree", "p_force_refresh"), &LimboAIEditor::edit_bt, Variant(false));
|
||||||
|
ClassDB::bind_method(D_METHOD("_on_resources_reload"), &LimboAIEditor::_on_resources_reload);
|
||||||
|
ClassDB::bind_method(D_METHOD("_reload_modified"), &LimboAIEditor::_reload_modified);
|
||||||
|
ClassDB::bind_method(D_METHOD("_resave_modified"), &LimboAIEditor::_resave_modified);
|
||||||
}
|
}
|
||||||
|
|
||||||
LimboAIEditor::LimboAIEditor(EditorNode *p_editor) {
|
LimboAIEditor::LimboAIEditor(EditorNode *p_editor) {
|
||||||
|
@ -1011,6 +1076,28 @@ LimboAIEditor::LimboAIEditor(EditorNode *p_editor) {
|
||||||
menu->connect("id_pressed", this, "_on_action_selected");
|
menu->connect("id_pressed", this, "_on_action_selected");
|
||||||
menu->set_hide_on_window_lose_focus(true);
|
menu->set_hide_on_window_lose_focus(true);
|
||||||
|
|
||||||
|
disk_changed = memnew(ConfirmationDialog);
|
||||||
|
{
|
||||||
|
VBoxContainer *vbc = memnew(VBoxContainer);
|
||||||
|
disk_changed->add_child(vbc);
|
||||||
|
|
||||||
|
Label *dl = memnew(Label);
|
||||||
|
dl->set_text(TTR("The following BehaviorTree resources are newer on disk.\nWhat action should be taken?"));
|
||||||
|
vbc->add_child(dl);
|
||||||
|
|
||||||
|
disk_changed_list = memnew(Tree);
|
||||||
|
vbc->add_child(disk_changed_list);
|
||||||
|
disk_changed_list->set_v_size_flags(Control::SIZE_EXPAND_FILL);
|
||||||
|
|
||||||
|
disk_changed->get_ok()->set_text(TTR("Reload"));
|
||||||
|
disk_changed->connect("confirmed", this, "_reload_modified");
|
||||||
|
|
||||||
|
disk_changed->add_button(TTR("Resave"), !OS::get_singleton()->get_swap_ok_cancel(), "resave");
|
||||||
|
disk_changed->connect("custom_action", this, "_resave_modified");
|
||||||
|
}
|
||||||
|
editor->get_gui_base()->add_child(disk_changed);
|
||||||
|
// disk_changed->hide();
|
||||||
|
|
||||||
GLOBAL_DEF("limbo_ai/behavior_tree/behavior_tree_default_dir", "res://ai/trees");
|
GLOBAL_DEF("limbo_ai/behavior_tree/behavior_tree_default_dir", "res://ai/trees");
|
||||||
ProjectSettings::get_singleton()->set_custom_property_info("limbo_ai/behavior_tree/behavior_tree_default_dir",
|
ProjectSettings::get_singleton()->set_custom_property_info("limbo_ai/behavior_tree/behavior_tree_default_dir",
|
||||||
PropertyInfo(Variant::STRING, "limbo_ai/behavior_tree/behavior_tree_default_dir", PROPERTY_HINT_DIR));
|
PropertyInfo(Variant::STRING, "limbo_ai/behavior_tree/behavior_tree_default_dir", PROPERTY_HINT_DIR));
|
||||||
|
@ -1028,6 +1115,8 @@ LimboAIEditor::LimboAIEditor(EditorNode *p_editor) {
|
||||||
load_dialog->set_current_dir(GLOBAL_GET("limbo_ai/behavior_tree/behavior_tree_default_dir"));
|
load_dialog->set_current_dir(GLOBAL_GET("limbo_ai/behavior_tree/behavior_tree_default_dir"));
|
||||||
new_script_btn->connect("pressed", ScriptEditor::get_singleton(), "open_script_create_dialog",
|
new_script_btn->connect("pressed", ScriptEditor::get_singleton(), "open_script_create_dialog",
|
||||||
varray("BTAction", String(GLOBAL_GET("limbo_ai/behavior_tree/user_task_dir_1")).plus_file("new_task")));
|
varray("BTAction", String(GLOBAL_GET("limbo_ai/behavior_tree/user_task_dir_1")).plus_file("new_task")));
|
||||||
|
|
||||||
|
EditorFileSystem::get_singleton()->connect("resources_reload", this, "_on_resources_reload");
|
||||||
}
|
}
|
||||||
|
|
||||||
LimboAIEditor::~LimboAIEditor() {
|
LimboAIEditor::~LimboAIEditor() {
|
||||||
|
|
|
@ -51,6 +51,8 @@ public:
|
||||||
Ref<BTTask> get_selected() const;
|
Ref<BTTask> get_selected() const;
|
||||||
void deselect();
|
void deselect();
|
||||||
|
|
||||||
|
virtual bool editor_can_reload_from_file() { return false; }
|
||||||
|
|
||||||
TaskTree();
|
TaskTree();
|
||||||
~TaskTree();
|
~TaskTree();
|
||||||
};
|
};
|
||||||
|
@ -128,6 +130,10 @@ private:
|
||||||
Button *history_forward;
|
Button *history_forward;
|
||||||
TaskPanel *task_panel;
|
TaskPanel *task_panel;
|
||||||
|
|
||||||
|
ConfirmationDialog *disk_changed;
|
||||||
|
Tree *disk_changed_list;
|
||||||
|
Set<String> disk_changed_files;
|
||||||
|
|
||||||
void _add_task(const Ref<BTTask> &p_task);
|
void _add_task(const Ref<BTTask> &p_task);
|
||||||
_FORCE_INLINE_ void _add_task_with_prototype(const Ref<BTTask> &p_prototype) { _add_task(p_prototype->clone()); }
|
_FORCE_INLINE_ void _add_task_with_prototype(const Ref<BTTask> &p_prototype) { _add_task(p_prototype->clone()); }
|
||||||
void _update_header();
|
void _update_header();
|
||||||
|
@ -137,6 +143,9 @@ private:
|
||||||
void _load_bt(String p_path);
|
void _load_bt(String p_path);
|
||||||
void _mark_as_dirty(bool p_dirty);
|
void _mark_as_dirty(bool p_dirty);
|
||||||
|
|
||||||
|
void _reload_modified();
|
||||||
|
void _resave_modified(String _str = "");
|
||||||
|
|
||||||
void _on_tree_rmb(const Vector2 &p_menu_pos);
|
void _on_tree_rmb(const Vector2 &p_menu_pos);
|
||||||
void _on_action_selected(int p_id);
|
void _on_action_selected(int p_id);
|
||||||
void _on_tree_task_selected(const Ref<BTTask> &p_task) const;
|
void _on_tree_task_selected(const Ref<BTTask> &p_task) const;
|
||||||
|
@ -147,6 +156,7 @@ private:
|
||||||
void _on_history_back();
|
void _on_history_back();
|
||||||
void _on_history_forward();
|
void _on_history_forward();
|
||||||
void _on_task_dragged(Ref<BTTask> p_task, Ref<BTTask> p_to_task, int p_type);
|
void _on_task_dragged(Ref<BTTask> p_task, Ref<BTTask> p_to_task, int p_type);
|
||||||
|
void _on_resources_reload(const Vector<String> &p_resources);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
|
@ -156,7 +166,7 @@ protected:
|
||||||
public:
|
public:
|
||||||
static Ref<Texture> get_task_icon(String p_script_path_or_class);
|
static Ref<Texture> get_task_icon(String p_script_path_or_class);
|
||||||
|
|
||||||
void edit_bt(Ref<BehaviorTree> p_behavior_tree);
|
void edit_bt(Ref<BehaviorTree> p_behavior_tree, bool p_force_refresh = false);
|
||||||
|
|
||||||
void apply_changes();
|
void apply_changes();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue