diff --git a/doc/source/classes/class_limbohsm.rst b/doc/source/classes/class_limbohsm.rst index 81700c0..f3b30fc 100644 --- a/doc/source/classes/class_limbohsm.rst +++ b/doc/source/classes/class_limbohsm.rst @@ -48,6 +48,8 @@ Methods +-------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | |void| | :ref:`add_transition`\ (\ from_state\: :ref:`LimboState`, to_state\: :ref:`LimboState`, event\: ``StringName``\ ) | +-------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + | |void| | :ref:`change_active_state`\ (\ state\: :ref:`LimboState`\ ) | + +-------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | :ref:`LimboState` | :ref:`get_active_state`\ (\ ) |const| | +-------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | :ref:`LimboState` | :ref:`get_leaf_state`\ (\ ) |const| | @@ -195,6 +197,20 @@ Establishes a transition from one state to another when ``event`` is dispatched. ---- +.. _class_LimboHSM_method_change_active_state: + +.. rst-class:: classref-method + +|void| **change_active_state**\ (\ state\: :ref:`LimboState`\ ) :ref:`🔗` + +Changes the currently active substate to ``state``. If ``state`` is already active, it will be exited and reentered. + +\ ``state`` must be a child of this **LimboHSM**. + +.. rst-class:: classref-item-separator + +---- + .. _class_LimboHSM_method_get_active_state: .. rst-class:: classref-method diff --git a/doc_classes/LimboHSM.xml b/doc_classes/LimboHSM.xml index 99256d2..d038fe6 100644 --- a/doc_classes/LimboHSM.xml +++ b/doc_classes/LimboHSM.xml @@ -18,6 +18,14 @@ Establishes a transition from one state to another when [param event] is dispatched. Both [param from_state] and [param to_state] must be immediate children of this state. + + + + + Changes the currently active substate to [param state]. If [param state] is already active, it will be exited and reentered. + [param state] must be a child of this [LimboHSM]. + + diff --git a/hsm/limbo_hsm.cpp b/hsm/limbo_hsm.cpp index f7bb754..857f930 100644 --- a/hsm/limbo_hsm.cpp +++ b/hsm/limbo_hsm.cpp @@ -45,9 +45,10 @@ void LimboHSM::set_active(bool p_active) { } } -void LimboHSM::_change_state(LimboState *p_state) { - ERR_FAIL_COND(p_state == nullptr); - ERR_FAIL_COND(p_state->get_parent() != this); +void LimboHSM::change_active_state(LimboState *p_state) { + ERR_FAIL_NULL(p_state); + ERR_FAIL_COND_MSG(!is_active(), "LimboHSM: Unable to change active state when HSM is not active."); + ERR_FAIL_COND_MSG(p_state->get_parent() != this, "LimboHSM: Unable to perform transition to a state that is not a child of this HSM."); if (active_state) { active_state->_exit(); @@ -66,7 +67,7 @@ void LimboHSM::_enter() { ERR_FAIL_COND_MSG(initial_state == nullptr, "LimboHSM: Initial state is not set."); LimboState::_enter(); - _change_state(initial_state); + change_active_state(initial_state); } void LimboHSM::_exit() { @@ -92,7 +93,7 @@ void LimboHSM::update(double p_delta) { _update(p_delta); updating = false; if (next_active) { - _change_state(next_active); + change_active_state(next_active); next_active = nullptr; } } @@ -186,7 +187,7 @@ bool LimboHSM::_dispatch(const StringName &p_event, const Variant &p_cargo) { } if (permitted) { if (!updating) { - _change_state(to_state); + change_active_state(to_state); } else if (!next_active) { // Only set next_active if we are not already in the process of changing states. next_active = to_state; @@ -264,8 +265,8 @@ void LimboHSM::_bind_methods() { ClassDB::bind_method(D_METHOD("add_transition", "from_state", "to_state", "event"), &LimboHSM::add_transition); ClassDB::bind_method(D_METHOD("remove_transition", "from_state", "event"), &LimboHSM::remove_transition); ClassDB::bind_method(D_METHOD("anystate"), &LimboHSM::anystate); - ClassDB::bind_method(D_METHOD("initialize", "agent", "parent_scope"), &LimboHSM::initialize, Variant()); + ClassDB::bind_method(D_METHOD("change_active_state", "state"), &LimboHSM::change_active_state); BIND_ENUM_CONSTANT(IDLE); BIND_ENUM_CONSTANT(PHYSICS); diff --git a/hsm/limbo_hsm.h b/hsm/limbo_hsm.h index 4f4dc2b..b046a1f 100644 --- a/hsm/limbo_hsm.h +++ b/hsm/limbo_hsm.h @@ -54,16 +54,17 @@ protected: virtual void _exit() override; virtual void _update(double p_delta) override; - void _change_state(LimboState *p_state); - public: void set_update_mode(UpdateMode p_mode) { update_mode = p_mode; } UpdateMode get_update_mode() const { return update_mode; } + void set_active(bool p_active); + + void change_active_state(LimboState *p_state); + LimboState *get_active_state() const { return active_state; } LimboState *get_previous_active_state() const { return previous_active; } LimboState *get_leaf_state() const; - void set_active(bool p_active); void set_initial_state(LimboState *p_state); LimboState *get_initial_state() const { return initial_state; }