//! \~\file pistatemachine_transition.h //! \~\ingroup StateMachine //! \~\brief //! \~english Declares transitions used by PIStateMachine //! \~russian Объявляет переходы, используемые в PIStateMachine /* PIP - Platform Independent Primitives State machine transition Ivan Pelipenko peri4ko@yandex.ru This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ #ifndef pistatemachine_transition_H #define pistatemachine_transition_H #include "pistatemachine_base.h" #include "pitimer.h" //! \~\ingroup StateMachine //! \~\brief //! \~english Transition between states in PIStateMachine. //! \~russian Переход между состояниями в PIStateMachine. //! \~\details //! \~english //! A transition can be triggered by an event or by a timeout. Optional guards are //! evaluated against arguments passed to \a PIStateMachine::postEvent(). //! \~russian //! Переход может запускаться событием или таймаутом. Необязательные guard-функции //! проверяются на аргументах, переданных в \a PIStateMachine::postEvent(). class PIP_EXPORT PITransitionBase { friend class PIStateMachine; friend class PIStateBase; public: //! \~english Creates a transition from \a source to \a target for the specified event identifier. //! \~russian Создает переход из \a source в \a target для указанного идентификатора события. PITransitionBase(PIStateBase * source, PIStateBase * target, int event_id); //! \~english Destroys the transition and its stored guard. //! \~russian Уничтожает переход и сохраненную guard-функцию. virtual ~PITransitionBase(); //! \~english Returns the root state machine. //! \~russian Возвращает корневую машину состояний. PIStateMachine * machine() const { return root; } //! \~english Returns the source state. //! \~russian Возвращает исходное состояние. PIStateBase * source() const { return source_state; } //! \~english Returns the target state. //! \~russian Возвращает целевое состояние. PIStateBase * target() const { return target_state; } //! \~english Sets a guard function that must return bool. //! \~russian Задает guard-функцию, которая должна возвращать bool. template PITransitionBase * addGuard(std::function f) { static_assert(std::is_same::value, "guard function should return bool!"); piDeleteSafety(guard); guard = PIStateMachineHelpers::makeFunction(f); return this; } //! \~english Sets a guard from a lambda or other callable object. //! \~russian Задает guard-функцию из lambda или другого вызываемого объекта. template PITransitionBase * addGuard(L f) { return addGuard(toStdFunction(f)); } //! \~english Tests the guard against event arguments passed to the transition. //! \~russian Проверяет guard-функцию на аргументах события, переданных переходу. template bool testGuard(Args... args) { if (!guard) return true; if (guard->formatHash() != PIStateMachineHelpers::Function().formatHash()) { piCout << "invalid arguments format!"; return false; } return reinterpret_cast *>(guard)->func(args...); } //! \~english Sets an action executed when the transition fires. //! \~russian Задает действие, выполняемое при срабатывании перехода. PITransitionBase * addAction(std::function a); //! \~english Executes the transition action if it is set. //! \~russian Выполняет действие перехода, если оно задано. void makeAction(); //! \~english Triggers the transition and updates active states. //! \~russian Запускает переход и обновляет активные состояния. void trigger(); protected: virtual void enabled() {} virtual void disabled() {} int eventID = 0; PIStateBase *source_state = nullptr, *target_state = nullptr; PIStateMachine * root = nullptr; PIStateMachineHelpers::FunctionBase * guard = nullptr; std::function action; }; //! \~\ingroup StateMachine //! \~\brief //! \~english Transition that fires automatically after a timeout. //! \~russian Переход, который автоматически срабатывает по истечении таймаута. class PIP_EXPORT PITransitionTimeout: public PITransitionBase { public: //! \~english Creates a transition that fires after \a timeout while the source state is active. //! \~russian Создает переход, который срабатывает через \a timeout, пока исходное состояние активно. PITransitionTimeout(PIStateBase * source, PIStateBase * target, PISystemTime timeout); //! \~english Stops the internal timer and destroys the transition. //! \~russian Останавливает внутренний таймер и уничтожает переход. ~PITransitionTimeout(); private: void enabled() override; void disabled() override; PITimer timer; }; #endif