Add auto-saving and dirty marking

This commit is contained in:
Serhii Snitsaruk 2022-09-03 14:01:13 +02:00
parent a2313d9a14
commit ffd0d943f1
2 changed files with 42 additions and 0 deletions

View File

@ -388,6 +388,7 @@ void LimboAIEditor::_add_task(const Ref<BTTask> &p_prototype) {
} else { } else {
parent->add_child(p_prototype); parent->add_child(p_prototype);
} }
_mark_as_dirty(true);
task_tree->update_tree(); task_tree->update_tree();
} }
@ -395,7 +396,10 @@ void LimboAIEditor::_update_header() {
String text = task_tree->get_bt()->get_path(); String text = task_tree->get_bt()->get_path();
if (text.empty()) { if (text.empty()) {
text = TTR("New Behavior Tree"); text = TTR("New Behavior Tree");
} else if (dirty.has(task_tree->get_bt())) {
text += "(*)";
} }
header->set_text(text); header->set_text(text);
header->set_icon(editor->get_object_icon(task_tree->get_bt().ptr(), "BehaviorTree")); header->set_icon(editor->get_object_icon(task_tree->get_bt().ptr(), "BehaviorTree"));
} }
@ -417,6 +421,7 @@ void LimboAIEditor::_save_bt(String p_path) {
task_tree->get_bt()->set_path(p_path, true); task_tree->get_bt()->set_path(p_path, true);
ResourceSaver::save(p_path, task_tree->get_bt(), ResourceSaver::FLAG_CHANGE_PATH); ResourceSaver::save(p_path, task_tree->get_bt(), ResourceSaver::FLAG_CHANGE_PATH);
_update_header(); _update_header();
_mark_as_dirty(false);
} }
void LimboAIEditor::_load_bt(String p_path) { void LimboAIEditor::_load_bt(String p_path) {
@ -447,6 +452,17 @@ void LimboAIEditor::_edit_bt(Ref<BehaviorTree> p_behavior_tree) {
_update_header(); _update_header();
} }
void LimboAIEditor::_mark_as_dirty(bool p_dirty) {
Ref<BehaviorTree> bt = task_tree->get_bt();
if (p_dirty && !dirty.has(bt)) {
dirty.insert(bt);
_update_header();
} else if (p_dirty == false && dirty.has(bt)) {
dirty.erase(bt);
_update_header();
}
}
void LimboAIEditor::_on_tree_rmb(const Vector2 &p_menu_pos) { void LimboAIEditor::_on_tree_rmb(const Vector2 &p_menu_pos) {
menu->set_size(Size2(1, 1)); menu->set_size(Size2(1, 1));
menu->set_position(p_menu_pos); menu->set_position(p_menu_pos);
@ -474,6 +490,7 @@ void LimboAIEditor::_on_action_selected(int p_id) {
} }
task_tree->update_tree(); task_tree->update_tree();
editor->edit_node(nullptr); editor->edit_node(nullptr);
_mark_as_dirty(true);
} }
} break; } break;
case ACTION_MOVE_UP: { case ACTION_MOVE_UP: {
@ -485,6 +502,7 @@ void LimboAIEditor::_on_action_selected(int p_id) {
parent->remove_child(sel); parent->remove_child(sel);
parent->add_child_at_index(sel, idx - 1); parent->add_child_at_index(sel, idx - 1);
task_tree->update_tree(); task_tree->update_tree();
_mark_as_dirty(true);
} }
} }
} break; } break;
@ -497,6 +515,7 @@ void LimboAIEditor::_on_action_selected(int p_id) {
parent->remove_child(sel); parent->remove_child(sel);
parent->add_child_at_index(sel, idx + 1); parent->add_child_at_index(sel, idx + 1);
task_tree->update_tree(); task_tree->update_tree();
_mark_as_dirty(true);
} }
} }
} break; } break;
@ -509,6 +528,7 @@ void LimboAIEditor::_on_action_selected(int p_id) {
} }
parent->add_child(sel->clone()); parent->add_child(sel->clone());
task_tree->update_tree(); task_tree->update_tree();
_mark_as_dirty(true);
} }
} break; } break;
case ACTION_MAKE_ROOT: { case ACTION_MAKE_ROOT: {
@ -521,6 +541,7 @@ void LimboAIEditor::_on_action_selected(int p_id) {
task_tree->get_bt()->set_root_task(sel); task_tree->get_bt()->set_root_task(sel);
sel->add_child(old_root); sel->add_child(old_root);
task_tree->update_tree(); task_tree->update_tree();
_mark_as_dirty(true);
} }
} break; } break;
} }
@ -579,6 +600,18 @@ void LimboAIEditor::_on_history_forward() {
_edit_bt(history[idx_history]); _edit_bt(history[idx_history]);
} }
void LimboAIEditor::apply_changes() {
for (int i = 0; i < history.size(); i++) {
Ref<BehaviorTree> bt = history.get(i);
String path = bt->get_path();
if (ResourceLoader::exists(path)) {
ResourceSaver::save(path, bt);
}
dirty.clear();
_update_header();
}
}
void LimboAIEditor::_bind_methods() { void LimboAIEditor::_bind_methods() {
ClassDB::bind_method(D_METHOD("_add_task", "p_task"), &LimboAIEditor::_add_task); ClassDB::bind_method(D_METHOD("_add_task", "p_task"), &LimboAIEditor::_add_task);
ClassDB::bind_method(D_METHOD("_on_tree_rmb"), &LimboAIEditor::_on_tree_rmb); ClassDB::bind_method(D_METHOD("_on_tree_rmb"), &LimboAIEditor::_on_tree_rmb);
@ -751,6 +784,10 @@ const Ref<Texture> LimboAIEditorPlugin::get_icon() const {
return nullptr; return nullptr;
} }
void LimboAIEditorPlugin::apply_changes() {
limbo_ai_editor->apply_changes();
}
void LimboAIEditorPlugin::_notification(int p_notification) { void LimboAIEditorPlugin::_notification(int p_notification) {
// print_line(vformat("NOTIFICATION: %d", p_notification)); // print_line(vformat("NOTIFICATION: %d", p_notification));
} }

View File

@ -104,6 +104,7 @@ private:
EditorNode *editor; EditorNode *editor;
Vector<Ref<BehaviorTree>> history; Vector<Ref<BehaviorTree>> history;
int idx_history; int idx_history;
Set<Ref<BehaviorTree>> dirty;
Button *header; Button *header;
TaskTree *task_tree; TaskTree *task_tree;
@ -120,6 +121,7 @@ private:
void _save_bt(String p_path); void _save_bt(String p_path);
void _load_bt(String p_path); void _load_bt(String p_path);
void _edit_bt(Ref<BehaviorTree> p_behavior_tree); void _edit_bt(Ref<BehaviorTree> p_behavior_tree);
void _mark_as_dirty(bool p_dirty);
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);
@ -135,6 +137,8 @@ protected:
static void _bind_methods(); static void _bind_methods();
public: public:
void apply_changes();
LimboAIEditor(EditorNode *p_editor); LimboAIEditor(EditorNode *p_editor);
~LimboAIEditor(); ~LimboAIEditor();
}; };
@ -154,6 +158,7 @@ public:
virtual const Ref<Texture> get_icon() const; virtual const Ref<Texture> get_icon() const;
bool has_main_screen() const { return true; } bool has_main_screen() const { return true; }
virtual void make_visible(bool p_visible); virtual void make_visible(bool p_visible);
virtual void apply_changes();
LimboAIEditorPlugin(EditorNode *p_editor); LimboAIEditorPlugin(EditorNode *p_editor);
~LimboAIEditorPlugin(); ~LimboAIEditorPlugin();