Editor: Mark behavior tree as dirty when blackboard plan changes

This commit is contained in:
Serhii Snitsaruk 2024-01-26 14:35:33 +01:00
parent f8ce5c1311
commit 761b211740
3 changed files with 44 additions and 0 deletions

View File

@ -11,6 +11,8 @@
#include "behavior_tree.h" #include "behavior_tree.h"
#include "../util/limbo_string_names.h"
#ifdef LIMBOAI_MODULE #ifdef LIMBOAI_MODULE
#include "core/error/error_macros.h" #include "core/error/error_macros.h"
#include "core/object/class_db.h" #include "core/object/class_db.h"
@ -28,10 +30,24 @@ void BehaviorTree::set_description(const String &p_value) {
} }
void BehaviorTree::set_blackboard_plan(const Ref<BlackboardPlan> &p_plan) { void BehaviorTree::set_blackboard_plan(const Ref<BlackboardPlan> &p_plan) {
if (blackboard_plan == p_plan) {
return;
}
if (Engine::get_singleton()->is_editor_hint() && blackboard_plan.is_valid() &&
blackboard_plan->is_connected(LW_NAME(changed), callable_mp(this, &BehaviorTree::_plan_changed))) {
blackboard_plan->disconnect(LW_NAME(changed), callable_mp(this, &BehaviorTree::_plan_changed));
}
blackboard_plan = p_plan; blackboard_plan = p_plan;
if (blackboard_plan.is_null()) { if (blackboard_plan.is_null()) {
blackboard_plan = Ref<BlackboardPlan>(memnew(BlackboardPlan)); blackboard_plan = Ref<BlackboardPlan>(memnew(BlackboardPlan));
} }
if (Engine::get_singleton()->is_editor_hint()) {
blackboard_plan->connect(LW_NAME(changed), callable_mp(this, &BehaviorTree::_plan_changed));
}
emit_changed(); emit_changed();
} }
@ -62,6 +78,10 @@ Ref<BTTask> BehaviorTree::instantiate(Node *p_agent, const Ref<Blackboard> &p_bl
return inst; return inst;
} }
void BehaviorTree::_plan_changed() {
emit_changed();
}
void BehaviorTree::_bind_methods() { void BehaviorTree::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_description", "p_value"), &BehaviorTree::set_description); ClassDB::bind_method(D_METHOD("set_description", "p_value"), &BehaviorTree::set_description);
ClassDB::bind_method(D_METHOD("get_description"), &BehaviorTree::get_description); ClassDB::bind_method(D_METHOD("get_description"), &BehaviorTree::get_description);
@ -80,3 +100,10 @@ void BehaviorTree::_bind_methods() {
BehaviorTree::BehaviorTree() { BehaviorTree::BehaviorTree() {
} }
BehaviorTree::~BehaviorTree() {
if (Engine::get_singleton()->is_editor_hint() && blackboard_plan.is_valid() &&
blackboard_plan->is_connected(LW_NAME(changed), callable_mp(this, &BehaviorTree::_plan_changed))) {
blackboard_plan->disconnect(LW_NAME(changed), callable_mp(this, &BehaviorTree::_plan_changed));
}
}

View File

@ -32,6 +32,8 @@ private:
Ref<BlackboardPlan> blackboard_plan; Ref<BlackboardPlan> blackboard_plan;
Ref<BTTask> root_task; Ref<BTTask> root_task;
void _plan_changed();
protected: protected:
static void _bind_methods(); static void _bind_methods();
@ -54,6 +56,7 @@ public:
Ref<BTTask> instantiate(Node *p_agent, const Ref<Blackboard> &p_blackboard) const; Ref<BTTask> instantiate(Node *p_agent, const Ref<Blackboard> &p_blackboard) const;
BehaviorTree(); BehaviorTree();
~BehaviorTree();
}; };
#endif // BEHAVIOR_TREE_H #endif // BEHAVIOR_TREE_H

View File

@ -228,8 +228,17 @@ void LimboAIEditor::edit_bt(Ref<BehaviorTree> p_behavior_tree, bool p_force_refr
p_behavior_tree->notify_property_list_changed(); p_behavior_tree->notify_property_list_changed();
#endif // LIMBOAI_MODULE #endif // LIMBOAI_MODULE
if (task_tree->get_bt().is_valid() &&
task_tree->get_bt()->is_connected(LW_NAME(changed), callable_mp(this, &LimboAIEditor::_mark_as_dirty).bind(true))) {
task_tree->get_bt()->disconnect(LW_NAME(changed), callable_mp(this, &LimboAIEditor::_mark_as_dirty).bind(true));
}
task_tree->load_bt(p_behavior_tree); task_tree->load_bt(p_behavior_tree);
if (task_tree->get_bt().is_valid()) {
task_tree->get_bt()->connect(LW_NAME(changed), callable_mp(this, &LimboAIEditor::_mark_as_dirty).bind(true));
}
int idx = history.find(p_behavior_tree); int idx = history.find(p_behavior_tree);
if (idx != -1) { if (idx != -1) {
idx_history = idx; idx_history = idx;
@ -1052,6 +1061,11 @@ void LimboAIEditor::_notification(int p_what) {
cf->load(conf_path); cf->load(conf_path);
cf->set_value("bt_editor", "bteditor_hsplit", hsc->get_split_offset()); cf->set_value("bt_editor", "bteditor_hsplit", hsc->get_split_offset());
cf->save(conf_path); cf->save(conf_path);
if (task_tree->get_bt().is_valid() &&
task_tree->get_bt()->is_connected(LW_NAME(changed), callable_mp(this, &LimboAIEditor::_mark_as_dirty).bind(true))) {
task_tree->get_bt()->disconnect(LW_NAME(changed), callable_mp(this, &LimboAIEditor::_mark_as_dirty).bind(true));
}
} break; } break;
case NOTIFICATION_READY: { case NOTIFICATION_READY: {
// **** Signals // **** Signals