153 lines
5.5 KiB
C++
153 lines
5.5 KiB
C++
//! \addtogroup StateMachine
|
||
//! \{
|
||
//! \file pistatemachine_transition.h
|
||
//! \brief
|
||
//! \~english State machine transition
|
||
//! \~russian Переход машины состояний
|
||
//! \details
|
||
//! \~english Contains transition classes for state machine
|
||
//! \~russian Содержит классы переходов для машины состояний
|
||
//! \}
|
||
/*
|
||
PIP - Platform Independent Primitives
|
||
State machine transition
|
||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@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 <http://www.gnu.org/licenses/>.
|
||
*/
|
||
|
||
#ifndef pistatemachine_transition_H
|
||
#define pistatemachine_transition_H
|
||
|
||
#include "pistatemachine_base.h"
|
||
#include "pitimer.h"
|
||
|
||
|
||
//! \~english Base class for state machine transitions
|
||
//! \~russian Базовый класс для переходов машины состояний
|
||
class PIP_EXPORT PITransitionBase {
|
||
friend class PIStateMachine;
|
||
friend class PIStateBase;
|
||
|
||
public:
|
||
//! \~english Creates transition from source to target on event
|
||
//! \~russian Создает переход от source к target по событию
|
||
//! \param source Source state
|
||
//! \param target Target state
|
||
//! \param event_id Event identifier that triggers this transition
|
||
PITransitionBase(PIStateBase * source, PIStateBase * target, int event_id);
|
||
|
||
//! \~english Virtual destructor
|
||
//! \~russian Виртуальный деструктор
|
||
virtual ~PITransitionBase();
|
||
|
||
//! \~english Returns state machine this transition belongs to
|
||
//! \~russian Возвращает машину состояний, которой принадлежит этот переход
|
||
PIStateMachine * machine() const { return root; }
|
||
|
||
//! \~english Returns source state
|
||
//! \~russian Возвращает исходное состояние
|
||
PIStateBase * source() const { return source_state; }
|
||
|
||
//! \~english Returns target state
|
||
//! \~russian Возвращает целевое состояние
|
||
PIStateBase * target() const { return target_state; }
|
||
|
||
//! \~english Adds guard function to transition
|
||
//! \~russian Добавляет сторожевую функцию к переходу
|
||
template<typename R, typename... Args>
|
||
PITransitionBase * addGuard(std::function<R(Args...)> f) {
|
||
static_assert(std::is_same<R, bool>::value, "guard function should return bool!");
|
||
piDeleteSafety(guard);
|
||
guard = PIStateMachineHelpers::makeFunction(f);
|
||
return this;
|
||
}
|
||
|
||
//! \~english Adds guard function to transition (callable)
|
||
//! \~russian Добавляет сторожевую функцию к переходу (callable)
|
||
template<typename L>
|
||
PITransitionBase * addGuard(L f) {
|
||
return addGuard(toStdFunction(f));
|
||
}
|
||
|
||
//! \~english Tests guard function with arguments
|
||
//! \~russian Тестирует сторожевую функцию с аргументами
|
||
template<typename... Args>
|
||
bool testGuard(Args... args) {
|
||
if (!guard) return true;
|
||
if (guard->formatHash() != PIStateMachineHelpers::Function<Args...>().formatHash()) {
|
||
piCout << "invalid arguments format!";
|
||
return false;
|
||
}
|
||
return reinterpret_cast<PIStateMachineHelpers::Function<Args...> *>(guard)->func(args...);
|
||
}
|
||
|
||
//! \~english Adds action to transition
|
||
//! \~russian Добавляет действие к переходу
|
||
PITransitionBase * addAction(std::function<void()> a);
|
||
|
||
//! \~english Executes transition action
|
||
//! \~russian Выполняет действие перехода
|
||
void makeAction();
|
||
|
||
//! \~english Triggers transition
|
||
//! \~russian Запускает переход
|
||
void trigger();
|
||
|
||
protected:
|
||
//! \~english Called when transition becomes enabled
|
||
//! \~russian Вызывается когда переход становится доступным
|
||
virtual void enabled() {}
|
||
|
||
//! \~english Called when transition becomes disabled
|
||
//! \~russian Вызывается когда переход становится недоступным
|
||
virtual void disabled() {}
|
||
|
||
int eventID = 0;
|
||
PIStateBase *source_state = nullptr, *target_state = nullptr;
|
||
PIStateMachine * root = nullptr;
|
||
PIStateMachineHelpers::FunctionBase * guard = nullptr;
|
||
std::function<void()> action;
|
||
};
|
||
|
||
|
||
//! \~english Timeout transition
|
||
//! \~russian Переход по таймауту
|
||
//! \details
|
||
//! \~english Transition that triggers after specified timeout
|
||
//! \~russian Переход, который срабатывает после указанного таймаута
|
||
class PIP_EXPORT PITransitionTimeout: public PITransitionBase {
|
||
public:
|
||
//! \~english Creates timeout transition
|
||
//! \~russian Создает переход по таймауту
|
||
//! \param source Source state
|
||
//! \param target Target state
|
||
//! \param timeout Timeout duration
|
||
PITransitionTimeout(PIStateBase * source, PIStateBase * target, PISystemTime timeout);
|
||
|
||
//! \~english Destructor
|
||
//! \~russian Деструктор
|
||
~PITransitionTimeout();
|
||
|
||
private:
|
||
void enabled() override;
|
||
void disabled() override;
|
||
|
||
PITimer timer;
|
||
};
|
||
|
||
//! \}
|
||
|
||
#endif
|