Add blackboard data property to HSM

This commit is contained in:
Serhii Snitsaruk 2022-10-31 21:30:32 +01:00
parent 40cb7891c7
commit 86dba63db6
4 changed files with 36 additions and 8 deletions

View File

@ -168,9 +168,17 @@ bool LimboHSM::dispatch(const String &p_event, const Variant &p_cargo) {
return event_consumed;
}
void LimboHSM::initialize(Object *p_agent, const Ref<Blackboard> &p_blackboard) {
void LimboHSM::initialize(Object *p_agent, const Ref<Blackboard> &p_parent_scope) {
ERR_FAIL_COND(p_agent == nullptr);
ERR_FAIL_COND(!p_blackboard.is_valid());
if (!p_parent_scope.is_null()) {
blackboard->set_parent_scope(p_parent_scope);
}
_initialize(p_agent, nullptr);
}
void LimboHSM::_initialize(Object *p_agent, const Ref<Blackboard> &p_blackboard) {
ERR_FAIL_COND(p_agent == nullptr);
ERR_FAIL_COND_MSG(agent != nullptr, "LimboAI: HSM already initialized.");
ERR_FAIL_COND_MSG(get_child_count() == 0, "Cannot initialize LimboHSM: no candidate for initial substate.");
if (initial_state == nullptr) {
@ -178,14 +186,23 @@ void LimboHSM::initialize(Object *p_agent, const Ref<Blackboard> &p_blackboard)
ERR_FAIL_COND_MSG(initial_state == nullptr, "LimboHSM: Child at index 0 is not a LimboState.");
}
LimboState::initialize(p_agent, p_blackboard);
Ref<Blackboard> bb = blackboard;
if (!blackboard->get_data().empty()) {
if (!p_blackboard.is_null()) {
bb->set_parent_scope(p_blackboard);
}
} else if (!p_blackboard.is_null()) {
bb = p_blackboard;
}
LimboState::_initialize(p_agent, bb);
for (int i = 0; i < get_child_count(); i++) {
LimboState *c = Object::cast_to<LimboState>(get_child(i));
if (unlikely(c == nullptr)) {
ERR_PRINT(vformat("LimboHSM: Child at index %d is not a LimboState.", i));
} else {
c->initialize(p_agent, p_blackboard);
c->_initialize(p_agent, bb);
}
}
}
@ -218,6 +235,9 @@ void LimboHSM::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_initial_state", "p_state"), &LimboHSM::set_initial_state);
ClassDB::bind_method(D_METHOD("get_initial_state"), &LimboHSM::get_initial_state);
ClassDB::bind_method(D_METHOD("_set_blackboard_data", "p_blackboard"), &LimboHSM::_set_blackboard_data);
ClassDB::bind_method(D_METHOD("_get_blackboard_data"), &LimboHSM::_get_blackboard_data);
ClassDB::bind_method(D_METHOD("get_active_state"), &LimboHSM::get_active_state);
ClassDB::bind_method(D_METHOD("get_leaf_state"), &LimboHSM::get_leaf_state);
ClassDB::bind_method(D_METHOD("set_active", "p_active"), &LimboHSM::set_active);
@ -225,6 +245,8 @@ void LimboHSM::_bind_methods() {
ClassDB::bind_method(D_METHOD("add_transition", "p_from_state", "p_to_state", "p_event"), &LimboHSM::add_transition);
ClassDB::bind_method(D_METHOD("anystate"), &LimboHSM::anystate);
ClassDB::bind_method(D_METHOD("initialize", "p_agent", "p_parent_scope"), &LimboHSM::initialize, Variant());
BIND_ENUM_CONSTANT(IDLE);
BIND_ENUM_CONSTANT(PHYSICS);
BIND_ENUM_CONSTANT(MANUAL);
@ -232,6 +254,7 @@ void LimboHSM::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "update_mode", PROPERTY_HINT_ENUM, "Idle, Physics, Manual"), "set_update_mode", "get_update_mode");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "ANYSTATE", PROPERTY_HINT_NONE, "", 0), "", "anystate");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "initial_state", PROPERTY_HINT_RESOURCE_TYPE, "LimboState", 0), "set_initial_state", "get_initial_state");
ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "_blackboard_data"), "_set_blackboard_data", "_get_blackboard_data");
ADD_SIGNAL(MethodInfo("state_changed", PropertyInfo(Variant::OBJECT, "p_state", PROPERTY_HINT_NONE, "", 0, "LimboState")));
}
@ -240,4 +263,5 @@ LimboHSM::LimboHSM() {
update_mode = UpdateMode::IDLE;
active_state = nullptr;
initial_state = nullptr;
blackboard = Ref<Blackboard>(memnew(Blackboard));
}

View File

@ -34,6 +34,10 @@ protected:
void _notification(int p_what);
void _set_blackboard_data(Dictionary p_value) { blackboard->set_data(p_value.duplicate()); }
Dictionary _get_blackboard_data() const { return blackboard->get_data(); }
virtual void _initialize(Object *p_agent, const Ref<Blackboard> &p_blackboard);
virtual void _enter();
virtual void _exit();
virtual void _update(float p_delta);
@ -51,7 +55,7 @@ public:
void set_initial_state(Node *p_state);
LimboState *get_initial_state() const { return initial_state; }
virtual void initialize(Object *p_agent, const Ref<Blackboard> &p_blackboard);
virtual void initialize(Object *p_agent, const Ref<Blackboard> &p_parent_scope = nullptr);
virtual bool dispatch(const String &p_event, const Variant &p_cargo);
void update(float p_delta) { _update(p_delta); }

View File

@ -61,7 +61,7 @@ void LimboState::_update(float p_delta) {
emit_signal(LimboStringNames::get_singleton()->updated, p_delta);
};
void LimboState::initialize(Object *p_agent, const Ref<Blackboard> &p_blackboard) {
void LimboState::_initialize(Object *p_agent, const Ref<Blackboard> &p_blackboard) {
ERR_FAIL_COND(p_agent == nullptr);
ERR_FAIL_COND(!p_blackboard.is_valid());
agent = p_agent;
@ -144,7 +144,7 @@ void LimboState::_bind_methods() {
ClassDB::bind_method(D_METHOD("_enter"), &LimboState::_enter);
ClassDB::bind_method(D_METHOD("_exit"), &LimboState::_exit);
ClassDB::bind_method(D_METHOD("_update", "p_delta"), &LimboState::_update);
ClassDB::bind_method(D_METHOD("initialize", "p_agent", "p_blackboard"), &LimboState::initialize);
ClassDB::bind_method(D_METHOD("_initialize", "p_agent", "p_blackboard"), &LimboState::_initialize);
ClassDB::bind_method(D_METHOD("dispatch", "p_event", "p_cargo"), &LimboState::dispatch, Variant());
ClassDB::bind_method(D_METHOD("named", "p_name"), &LimboState::named);
ClassDB::bind_method(D_METHOD("add_event_handler", "p_event", "p_method"), &LimboState::add_event_handler);

View File

@ -36,6 +36,7 @@ protected:
void _notification(int p_what);
virtual void _initialize(Object *p_agent, const Ref<Blackboard> &p_blackboard);
virtual void _setup();
virtual void _enter();
virtual void _exit();
@ -51,7 +52,6 @@ public:
Object *get_agent() const { return agent; }
void set_agent(Object *p_agent) { agent = p_agent; }
virtual void initialize(Object *p_agent, const Ref<Blackboard> &p_blackboard);
virtual bool dispatch(const String &p_event, const Variant &p_cargo);
LimboState *named(String p_name);