From 88df78c4a288864c27dd7ec8bff28f94d90d92eb Mon Sep 17 00:00:00 2001 From: Serhii Snitsaruk Date: Mon, 4 Mar 2024 15:53:39 +0100 Subject: [PATCH] Refactor HSM to use StringName for events --- bt/bt_state.cpp | 10 +++++----- bt/bt_state.h | 19 +++++++++---------- hsm/limbo_hsm.cpp | 10 +++++----- hsm/limbo_hsm.h | 12 +++++++----- hsm/limbo_state.cpp | 16 ++++++++-------- hsm/limbo_state.h | 16 ++++++++-------- util/limbo_string_names.cpp | 4 +++- util/limbo_string_names.h | 4 +++- 8 files changed, 48 insertions(+), 43 deletions(-) diff --git a/bt/bt_state.cpp b/bt/bt_state.cpp index 4fd25e3..0c379e7 100644 --- a/bt/bt_state.cpp +++ b/bt/bt_state.cpp @@ -1,7 +1,7 @@ /** * bt_state.cpp * ============================================================================= - * Copyright 2021-2023 Serhii Snitsaruk + * Copyright 2021-2024 Serhii Snitsaruk * * Use of this source code is governed by an MIT-style * license that can be found in the LICENSE file or at @@ -113,11 +113,11 @@ void BTState::_bind_methods() { ClassDB::bind_method(D_METHOD("get_failure_event"), &BTState::get_failure_event); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "behavior_tree", PROPERTY_HINT_RESOURCE_TYPE, "BehaviorTree"), "set_behavior_tree", "get_behavior_tree"); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "success_event"), "set_success_event", "get_success_event"); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "failure_event"), "set_failure_event", "get_failure_event"); + ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "success_event"), "set_success_event", "get_success_event"); + ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "failure_event"), "set_failure_event", "get_failure_event"); } BTState::BTState() { - success_event = "success"; - failure_event = "failure"; + success_event = LW_NAME(EVENT_SUCCESS); + failure_event = LW_NAME(EVENT_FAILURE); } diff --git a/bt/bt_state.h b/bt/bt_state.h index 62ee8f9..07f79f8 100644 --- a/bt/bt_state.h +++ b/bt/bt_state.h @@ -1,7 +1,7 @@ /** * bt_state.h * ============================================================================= - * Copyright 2021-2023 Serhii Snitsaruk + * Copyright 2021-2024 Serhii Snitsaruk * * Use of this source code is governed by an MIT-style * license that can be found in the LICENSE file or at @@ -23,14 +23,16 @@ class BTState : public LimboState { private: Ref behavior_tree; Ref tree_instance; - String success_event; - String failure_event; + StringName success_event; + StringName failure_event; void _update_blackboard_plan(); protected: static void _bind_methods(); + void _notification(int p_notification); + virtual void _setup() override; virtual void _exit() override; virtual void _update(double p_delta) override; @@ -41,16 +43,13 @@ public: Ref get_tree_instance() const { return tree_instance; } - void set_success_event(String p_success_event) { success_event = p_success_event; } - String get_success_event() const { return success_event; } + void set_success_event(const StringName &p_success_event) { success_event = p_success_event; } + StringName get_success_event() const { return success_event; } - void set_failure_event(String p_failure_event) { failure_event = p_failure_event; } - String get_failure_event() const { return failure_event; } + void set_failure_event(const StringName &p_failure_event) { failure_event = p_failure_event; } + StringName get_failure_event() const { return failure_event; } BTState(); - -protected: - void _notification(int p_notification); }; #endif // BT_STATE_H diff --git a/hsm/limbo_hsm.cpp b/hsm/limbo_hsm.cpp index 54e95f2..2ee188a 100644 --- a/hsm/limbo_hsm.cpp +++ b/hsm/limbo_hsm.cpp @@ -1,7 +1,7 @@ /** * limbo_hsm.cpp * ============================================================================= - * Copyright 2021-2023 Serhii Snitsaruk + * Copyright 2021-2024 Serhii Snitsaruk * * Use of this source code is governed by an MIT-style * license that can be found in the LICENSE file or at @@ -100,11 +100,11 @@ void LimboHSM::update(double p_delta) { _update(p_delta); } -void LimboHSM::add_transition(LimboState *p_from_state, LimboState *p_to_state, const String &p_event) { +void LimboHSM::add_transition(LimboState *p_from_state, LimboState *p_to_state, const StringName &p_event) { ERR_FAIL_COND_MSG(p_from_state != nullptr && p_from_state->get_parent() != this, "LimboHSM: Unable to add a transition from a state that is not an immediate child of mine."); ERR_FAIL_COND_MSG(p_to_state == nullptr, "LimboHSM: Unable to add a transition to a null state."); ERR_FAIL_COND_MSG(p_to_state->get_parent() != this, "LimboHSM: Unable to add a transition to a state that is not an immediate child of mine."); - ERR_FAIL_COND_MSG(p_event.is_empty(), "LimboHSM: Failed to add transition due to empty event string."); + ERR_FAIL_COND_MSG(p_event == StringName(), "LimboHSM: Failed to add transition due to empty event string."); uint64_t key = _get_transition_key(p_from_state, p_event); transitions[key] = Object::cast_to(p_to_state); @@ -127,8 +127,8 @@ void LimboHSM::set_initial_state(LimboState *p_state) { initial_state = Object::cast_to(p_state); } -bool LimboHSM::_dispatch(const String &p_event, const Variant &p_cargo) { - ERR_FAIL_COND_V(p_event.is_empty(), false); +bool LimboHSM::_dispatch(const StringName &p_event, const Variant &p_cargo) { + ERR_FAIL_COND_V(p_event == StringName(), false); bool event_consumed = false; diff --git a/hsm/limbo_hsm.h b/hsm/limbo_hsm.h index f92857c..41d7f96 100644 --- a/hsm/limbo_hsm.h +++ b/hsm/limbo_hsm.h @@ -1,7 +1,7 @@ /** * limbo_hsm.h * ============================================================================= - * Copyright 2021-2023 Serhii Snitsaruk + * Copyright 2021-2024 Serhii Snitsaruk * * Use of this source code is governed by an MIT-style * license that can be found in the LICENSE file or at @@ -30,9 +30,11 @@ private: LimboState *active_state; HashMap transitions; - _FORCE_INLINE_ uint64_t _get_transition_key(LimboState *p_from_state, const String &p_event) { + _FORCE_INLINE_ uint64_t _get_transition_key(LimboState *p_from_state, const StringName &p_event) { uint64_t key = hash_djb2_one_64(Variant::OBJECT); - key = hash_djb2_one_64(Variant(p_from_state).hash(), key); + if (p_from_state != nullptr) { + key = hash_djb2_one_64(hash_one_uint64(hash_make_uint64_t(p_from_state)), key); + } key = hash_djb2_one_64(p_event.hash(), key); return key; } @@ -43,7 +45,7 @@ protected: void _notification(int p_what); virtual void _initialize(Node *p_agent, const Ref &p_blackboard) override; - virtual bool _dispatch(const String &p_event, const Variant &p_cargo = Variant()) override; + virtual bool _dispatch(const StringName &p_event, const Variant &p_cargo = Variant()) override; virtual void _enter() override; virtual void _exit() override; @@ -65,7 +67,7 @@ public: virtual void initialize(Node *p_agent, const Ref &p_parent_scope = nullptr); void update(double p_delta); - void add_transition(LimboState *p_from_state, LimboState *p_to_state, const String &p_event); + void add_transition(LimboState *p_from_state, LimboState *p_to_state, const StringName &p_event); LimboState *anystate() const { return nullptr; } LimboHSM(); diff --git a/hsm/limbo_state.cpp b/hsm/limbo_state.cpp index 6e00396..085e998 100644 --- a/hsm/limbo_state.cpp +++ b/hsm/limbo_state.cpp @@ -1,7 +1,7 @@ /** * limbo_state.cpp * ============================================================================= - * Copyright 2021-2023 Serhii Snitsaruk + * Copyright 2021-2024 Serhii Snitsaruk * * Use of this source code is governed by an MIT-style * license that can be found in the LICENSE file or at @@ -34,7 +34,7 @@ LimboState *LimboState::get_root() const { return const_cast(state); } -LimboState *LimboState::named(String p_name) { +LimboState *LimboState::named(const String &p_name) { set_name(p_name); return this; } @@ -80,8 +80,8 @@ void LimboState::_initialize(Node *p_agent, const Ref &p_blackboard) _setup(); } -bool LimboState::_dispatch(const String &p_event, const Variant &p_cargo) { - ERR_FAIL_COND_V(p_event.is_empty(), false); +bool LimboState::_dispatch(const StringName &p_event, const Variant &p_cargo) { + ERR_FAIL_COND_V(p_event == StringName(), false); if (handlers.size() > 0 && handlers.has(p_event)) { Variant ret; @@ -120,13 +120,13 @@ bool LimboState::_dispatch(const String &p_event, const Variant &p_cargo) { return false; } -void LimboState::add_event_handler(const String &p_event, const Callable &p_handler) { - ERR_FAIL_COND(p_event.is_empty()); +void LimboState::add_event_handler(const StringName &p_event, const Callable &p_handler) { + ERR_FAIL_COND(p_event == StringName()); ERR_FAIL_COND(!p_handler.is_valid()); handlers.insert(p_event, p_handler); } -bool LimboState::dispatch(const String &p_event, const Variant &p_cargo) { +bool LimboState::dispatch(const StringName &p_event, const Variant &p_cargo) { return get_root()->_dispatch(p_event, p_cargo); } @@ -196,7 +196,7 @@ void LimboState::_bind_methods() { // TODO: Registering virtual functions is not available in godot-cpp... #endif - ADD_PROPERTY(PropertyInfo(Variant::STRING, "EVENT_FINISHED", PROPERTY_HINT_NONE, "", 0), "", "event_finished"); + ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "EVENT_FINISHED", PROPERTY_HINT_NONE, "", 0), "", "event_finished"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "agent", PROPERTY_HINT_RESOURCE_TYPE, "Node", 0), "set_agent", "get_agent"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "blackboard", PROPERTY_HINT_RESOURCE_TYPE, "Blackboard", 0), "", "get_blackboard"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "blackboard_plan", PROPERTY_HINT_RESOURCE_TYPE, "BlackboardPlan", PROPERTY_USAGE_DEFAULT), "set_blackboard_plan", "get_blackboard_plan"); diff --git a/hsm/limbo_state.h b/hsm/limbo_state.h index 291be8c..47b6d75 100644 --- a/hsm/limbo_state.h +++ b/hsm/limbo_state.h @@ -1,7 +1,7 @@ /** * limbo_state.h * ============================================================================= - * Copyright 2021-2023 Serhii Snitsaruk + * Copyright 2021-2024 Serhii Snitsaruk * * Use of this source code is governed by an MIT-style * license that can be found in the LICENSE file or at @@ -41,7 +41,7 @@ private: Ref blackboard_plan; Node *agent; Ref blackboard; - HashMap handlers; + HashMap handlers; Callable guard_callable; protected: @@ -54,7 +54,7 @@ protected: void _notification(int p_what); virtual void _initialize(Node *p_agent, const Ref &p_blackboard); - virtual bool _dispatch(const String &p_event, const Variant &p_cargo = Variant()); + virtual bool _dispatch(const StringName &p_event, const Variant &p_cargo = Variant()); virtual void _setup(); virtual void _enter(); @@ -69,7 +69,7 @@ protected: #endif // LIMBOAI_MODULE public: - void set_blackboard_plan(const Ref p_plan) { blackboard_plan = p_plan; } + void set_blackboard_plan(const Ref &p_plan) { blackboard_plan = p_plan; } Ref get_blackboard_plan() const { return blackboard_plan; } Ref get_blackboard() const { return blackboard; } @@ -77,15 +77,15 @@ public: Node *get_agent() const { return agent; } void set_agent(Node *p_agent) { agent = p_agent; } - LimboState *named(String p_name); + LimboState *named(const String &p_name); LimboState *call_on_enter(const Callable &p_callable); LimboState *call_on_exit(const Callable &p_callable); LimboState *call_on_update(const Callable &p_callable); - void add_event_handler(const String &p_event, const Callable &p_handler); - bool dispatch(const String &p_event, const Variant &p_cargo = Variant()); + void add_event_handler(const StringName &p_event, const Callable &p_handler); + bool dispatch(const StringName &p_event, const Variant &p_cargo = Variant()); - _FORCE_INLINE_ String event_finished() const { return LW_NAME(EVENT_FINISHED); } + _FORCE_INLINE_ StringName event_finished() const { return LW_NAME(EVENT_FINISHED); } LimboState *get_root() const; bool is_active() const { return active; } diff --git a/util/limbo_string_names.cpp b/util/limbo_string_names.cpp index 6dd6092..f621c23 100644 --- a/util/limbo_string_names.cpp +++ b/util/limbo_string_names.cpp @@ -78,6 +78,9 @@ LimboStringNames::LimboStringNames() { emit_changed = SN("emit_changed"); entered = SN("entered"); error_value = SN("error_value"); + EVENT_FAILURE = SN("failure"); + EVENT_FINISHED = SN("finished"); + EVENT_SUCCESS = SN("success"); exited = SN("exited"); favorite_tasks_changed = SN("favorite_tasks_changed"); Favorites = SN("Favorites"); @@ -160,7 +163,6 @@ LimboStringNames::LimboStringNames() { visibility_changed = SN("visibility_changed"); window_visibility_changed = SN("window_visibility_changed"); - EVENT_FINISHED = "finished"; repeat_forever.parse_utf8("Repeat ∞"); output_var_prefix.parse_utf8("➜"); } diff --git a/util/limbo_string_names.h b/util/limbo_string_names.h index 6111c0a..7e5c7e8 100644 --- a/util/limbo_string_names.h +++ b/util/limbo_string_names.h @@ -92,6 +92,9 @@ public: StringName emit_changed; StringName entered; StringName error_value; + StringName EVENT_FAILURE; + StringName EVENT_FINISHED; + StringName EVENT_SUCCESS; StringName exited; StringName favorite_tasks_changed; StringName Favorites; @@ -175,7 +178,6 @@ public: StringName visibility_changed; StringName window_visibility_changed; - String EVENT_FINISHED; String repeat_forever; String output_var_prefix; };