merged AI doc, some new pages

This commit is contained in:
2026-03-12 14:46:57 +03:00
parent 07ae277f9e
commit ed13838237
206 changed files with 14088 additions and 5152 deletions

View File

@@ -1,13 +1,19 @@
/*! \file pistatemachine.h
* \ingroup StateMachine
* \~\brief
* \~english State machine.
* \~russian Машина состояний.
*/
//! \~\file pistatemachine.h
//! \brief
//! \~english State machine.
//! \~russian Машина состояний.
//! \details
//! \~english Main state machine class that manages states and transitions.
//! \~russian Основной класс машины состояний, управляющий состояниями и переходами.
//! \note
//! \~english Thread-safe implementation with nested post handling.
//! \~russian Потокобезопасная реализация с обработкой вложенных постов.
//! \~\sa
//! PIStateBase, PITransitionBase
/*
PIP - Platform Independent Primitives
State machine
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
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
@@ -30,18 +36,32 @@
#include "pistatemachine_transition.h"
//! \ingroup StateMachine
//! \~\ingroup StateMachine
//! \~\brief
//! \~english
//! \~russian
//! \~english Root object that owns and runs a hierarchical state machine.
//! \~russian Корневой объект, который владеет и запускает иерархическую машину состояний.
class PIP_EXPORT PIStateMachine: public PIStateBase {
public:
//! \~english Creates a state machine with an optional name.
//! \~russian Создает машину состояний с необязательным именем.
PIStateMachine(const PIString & n = {});
//! \~english Starts the machine from its initial active configuration.
//! \~russian Запускает машину из ее начальной активной конфигурации.
bool start();
//! \~english Returns true while the machine is running.
//! \~russian Возвращает true, пока машина запущена.
bool isRunning() const { return is_running; }
//! \~english Sets a callback invoked when the machine finishes.
//! \~russian Задает callback-функцию, вызываемую при завершении машины.
void setOnFinish(std::function<void()> f) { on_finish = f; }
//! \~english Posts an event to active states and triggers the first matching transition.
//! \~russian Посылает событие в активные состояния и запускает первый подходящий переход.
template<typename... Args>
bool postEvent(int event_id, Args... args) {
if (!is_running) return false;
@@ -83,6 +103,7 @@ public:
return false;
}
private:
void onFinish() override;

View File

@@ -1,13 +1,12 @@
/*! \file pistatemachine_base.h
* \ingroup StateMachine
* \~\brief
* \~english Some template helpers for PIStateMachine
* \~russian Несколько шаблонов для PIStateMachine
*/
//! \~\file pistatemachine_base.h
//! \~\ingroup StateMachine
//! \~\brief
//! \~english Declares helper types shared by the state machine API
//! \~russian Объявляет вспомогательные типы, общие для API машины состояний
/*
PIP - Platform Independent Primitives
Some template helpers for PIStateMachine
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
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
@@ -37,6 +36,7 @@ public:
virtual uint formatHash() = 0;
};
template<typename... Args>
class Function: public FunctionBase {
public:
@@ -47,6 +47,7 @@ public:
std::function<bool(Args...)> func;
};
template<typename Ret, typename... Args>
FunctionBase * makeFunction(std::function<Ret(Args...)> func) {
auto * ret = new Function<Args...>();

View File

@@ -1,13 +1,12 @@
/*! \file pistatemachine_state.h
* \ingroup StateMachine
* \~\brief
* \~english State machine node
* \~russian Узел машины состояний
*/
//! \~\file pistatemachine_state.h
//! \~\ingroup StateMachine
//! \~\brief
//! \~english Declares states used by PIStateMachine
//! \~russian Объявляет состояния, используемые в PIStateMachine
/*
PIP - Platform Independent Primitives
State machine node
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
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
@@ -31,52 +30,141 @@
#include "pisystemtime.h"
//! \ingroup StateMachine
//! \~\ingroup StateMachine
//! \~\brief
//! \~english Base class for states in a hierarchical state machine.
//! \~russian Базовый класс состояния в иерархической машине состояний.
//! \~\details
//! \~english
//! A state can own child states and outgoing transitions. Compound states activate
//! either their initial child state or all children when parallel mode is enabled.
//! \~russian
//! Состояние может владеть дочерними состояниями и исходящими переходами.
//! Составные состояния активируют либо начальное дочернее состояние, либо все
//! дочерние состояния при включенном параллельном режиме.
class PIP_EXPORT PIStateBase {
friend class PIStateMachine;
friend class PITransitionBase;
friend class PIStateFinal;
public:
//! \~english Creates a state with an optional diagnostic name.
//! \~russian Создает состояние с необязательным именем для диагностики.
PIStateBase(const PIString & n = {}): name_(n) { ; }
//! \~english Destroys the state together with owned child states and transitions.
//! \~russian Уничтожает состояние вместе с принадлежащими дочерними состояниями и переходами.
virtual ~PIStateBase();
//! \~english Called when the state becomes active.
//! \~russian Вызывается при активации состояния.
virtual void onEnter() {}
//! \~english Called when the state becomes inactive.
//! \~russian Вызывается при деактивации состояния.
virtual void onExit() {}
//! \~english Called when a final child finishes this state.
//! \~russian Вызывается, когда финальное дочернее состояние завершает это состояние.
virtual void onFinish() {}
//! \~english Returns the root state machine.
//! \~russian Возвращает корневую машину состояний.
PIStateMachine * machine() const { return root; }
//! \~english Returns the parent state.
//! \~russian Возвращает родительское состояние.
PIStateBase * parent() const { return parent_state; }
//! \~english Returns the active child of a non-parallel compound state.
//! \~russian Возвращает активное дочернее состояние непараллельного составного состояния.
PIStateBase * activeChild() const { return active_state; }
//! \~english Returns active child states.
//! \~russian Возвращает активные дочерние состояния.
PIVector<PIStateBase *> activeChildren() const;
//! \~english Returns active atomic leaf states below this state.
//! \~russian Возвращает активные атомарные листовые состояния под этим состоянием.
PIVector<PIStateBase *> activeAtomics() const;
//! \~english Adds a child state owned by this state.
//! \~russian Добавляет дочернее состояние, которым владеет это состояние.
void addState(PIStateBase * s);
//! \~english Adds multiple child states owned by this state.
//! \~russian Добавляет несколько дочерних состояний, которыми владеет это состояние.
void addStates(PIVector<PIStateBase *> s);
//! \~english Sets the initial child state for a non-parallel compound state.
//! \~russian Задает начальное дочернее состояние для непараллельного составного состояния.
void setInitialState(PIStateBase * s);
//! \~english Adds an event-driven transition from this state to \a target.
//! \~russian Добавляет переход по событию из этого состояния в \a target.
PITransitionBase * addTransition(PIStateBase * target, int event_id);
//! \~english Adds a timeout transition that fires while this state stays active.
//! \~russian Добавляет переход по таймауту, который срабатывает пока это состояние активно.
PITransitionTimeout * addTimeoutTransition(PIStateBase * target, PISystemTime timeout);
//! \~english Enables or disables parallel activation of child states.
//! \~russian Включает или выключает параллельную активацию дочерних состояний.
void setParallel(bool yes) { is_parallel = yes; }
//! \~english Returns the state name.
//! \~russian Возвращает имя состояния.
const PIString & getName() const { return name_; }
//! \~english Returns true for the root machine object.
//! \~russian Возвращает true для корневого объекта машины состояний.
bool isStateMachine() const { return is_root; }
//! \~english Returns true if the state is currently active.
//! \~russian Возвращает true, если состояние сейчас активно.
bool isActive() const { return is_active; }
//! \~english Returns true if child states are activated in parallel.
//! \~russian Возвращает true, если дочерние состояния активируются параллельно.
bool isParallel() const { return is_parallel; }
//! \~english Returns true if the state is marked as final.
//! \~russian Возвращает true, если состояние помечено как финальное.
bool isFinal() const { return is_final; }
//! \~english Returns true if the state has no children.
//! \~russian Возвращает true, если у состояния нет дочерних состояний.
bool isAtomic() const { return children.isEmpty(); }
//! \~english Returns true if the state owns child states.
//! \~russian Возвращает true, если состояние содержит дочерние состояния.
bool isCompound() const { return children.isNotEmpty(); }
//! \~english Returns direct child states.
//! \~russian Возвращает прямые дочерние состояния.
const PIVector<PIStateBase *> & getChildren() const { return children; }
//! \~english Returns outgoing transitions owned by this state.
//! \~russian Возвращает исходящие переходы, принадлежащие этому состоянию.
const PIVector<PITransitionBase *> & getTransitions() const { return transitions; }
//! \~english Prints the state tree and active branches to piCout.
//! \~russian Печатает дерево состояний и активные ветви в piCout.
void print(PIString prefix = {});
//! \~english Returns this state and all descendant states.
//! \~russian Возвращает это состояние и все дочерние состояния.
PIVector<PIStateBase *> gatherStates();
private:
bool start(bool force = false);
void setActive(bool yes);
@@ -100,39 +188,67 @@ private:
};
//! \~\ingroup StateMachine
//! \~\brief
//! \~english State implementation that forwards enter and exit virtual methods to callbacks.
//! \~russian Реализация состояния, которая перенаправляет виртуальные методы входа и выхода в callback-функции.
class PIP_EXPORT PIStateLambda: public PIStateBase {
public:
//! \~english Creates a state backed by enter and exit callbacks.
//! \~russian Создает состояние с callback-функциями входа и выхода.
PIStateLambda(std::function<void()> on_enter, std::function<void()> on_exit = nullptr, const PIString & n = {}): PIStateBase(n) {
enter = on_enter;
exit = on_exit;
}
//! \~english Executes the enter callback.
//! \~russian Выполняет callback-функцию входа.
void onEnter() override {
if (enter) enter();
}
//! \~english Executes the exit callback.
//! \~russian Выполняет callback-функцию выхода.
void onExit() override {
if (exit) exit();
}
private:
std::function<void()> enter, exit;
};
//! \~\ingroup StateMachine
//! \~\brief
//! \~english Final state that finishes its parent state when entered.
//! \~russian Финальное состояние, которое завершает родительское состояние при входе.
class PIP_EXPORT PIStateFinal: public PIStateBase {
public:
//! \~english Creates a final state with an optional callback executed on entry.
//! \~russian Создает финальное состояние с необязательной callback-функцией, выполняемой при входе.
PIStateFinal(std::function<void()> on_finish = nullptr, const PIString & n = {}): PIStateBase(n) {
is_final = true;
enter = on_finish;
}
//! \~english Executes the finish callback when the final state is entered.
//! \~russian Выполняет callback завершения при входе в финальное состояние.
void onEnter() override {
if (enter) enter();
}
private:
std::function<void()> enter;
};
//! \relatesalso PIStateBase
//! \~english Writes a textual representation of a state to PICout.
//! \~russian Записывает текстовое представление состояния в PICout.
inline PICout operator<<(PICout c, PIStateBase * s) {
if (!s)
c << "state(nullptr)";

View File

@@ -1,13 +1,12 @@
/*! \file pistatemachine_transition.h
* \ingroup StateMachine
* \~\brief
* \~english State machine transition
* \~russian Переход машины состояний
*/
//! \~\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, Andrey Bychkov work.a.b@yandex.ru
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
@@ -30,22 +29,47 @@
#include "pitimer.h"
//! \ingroup StateMachine
//! \~\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<typename R, typename... Args>
PITransitionBase * addGuard(std::function<R(Args...)> f) {
static_assert(std::is_same<R, bool>::value, "guard function should return bool!");
@@ -54,11 +78,15 @@ public:
return this;
}
//! \~english Sets a guard from a lambda or other callable object.
//! \~russian Задает guard-функцию из lambda или другого вызываемого объекта.
template<typename L>
PITransitionBase * addGuard(L f) {
return addGuard(toStdFunction(f));
}
//! \~english Tests the guard against event arguments passed to the transition.
//! \~russian Проверяет guard-функцию на аргументах события, переданных переходу.
template<typename... Args>
bool testGuard(Args... args) {
if (!guard) return true;
@@ -69,11 +97,20 @@ public:
return reinterpret_cast<PIStateMachineHelpers::Function<Args...> *>(guard)->func(args...);
}
//! \~english Sets an action executed when the transition fires.
//! \~russian Задает действие, выполняемое при срабатывании перехода.
PITransitionBase * addAction(std::function<void()> 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() {}
@@ -86,11 +123,21 @@ protected:
};
//! \~\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;

View File

@@ -1,3 +1,13 @@
/*! \file pistatemachinemodule.h
* \ingroup StateMachine
* \~\brief
* \~english Declares module entry includes for the state machine API
* \~russian Объявляет основной include модуля API машины состояний
*
* \~\details
* \~english Includes the public state machine, state, and transition headers.
* \~russian Подключает публичные заголовки машины состояний, состояний и переходов.
*/
/*
PIP - Platform Independent Primitives
Module includes
@@ -34,9 +44,11 @@
//! \~russian \par Общее
//!
//! \~english
//!
//! The module provides hierarchical states, event-driven transitions, timeout
//! transitions and helper state classes for callback-based logic.
//! \~russian
//!
//! Модуль предоставляет иерархические состояния, переходы по событиям,
//! переходы по таймауту и вспомогательные классы состояний для логики на callback-функциях.
//! \~\authors
//! \~english
//! Ivan Pelipenko peri4ko@yandex.ru;
@@ -45,6 +57,645 @@
//! Иван Пелипенко peri4ko@yandex.ru;
//! Андрей Бычков work.a.b@yandex.ru;
//!
//!
//! \~english \section state_machine_overview General Description
//! \~russian \section state_machine_overview Общее описание
//!
//! \~english State machine is a behavioral design pattern that allows an object to change its behavior when its internal state changes.
//! Implementation in PIP is based on the **SCXML** (State Chart XML) standard.
//! \~russian Машина состояний — это поведенческий паттерн проектирования, который позволяет объекту изменять свое поведение при изменении
//! внутреннего состояния. Реализация в PIP основана на стандарте **SCXML** (State Chart XML).
//!
//! \~english \subsection scxml_concepts SCXML Concepts
//! \~russian \subsection scxml_concepts Основные концепции SCXML
//!
//! \~english - **State** — a node in the state tree, can be atomic or compound
//! \~russian - **State (Состояние)** — узел в дереве состояний, может быть атомарным или составным
//! \~english - **Transition** — a connection between states that triggers on an event
//! \~russian - **Transition (Переход)** — связь между состояниями, срабатывает при событии
//! \~english - **Event** — a trigger that causes a transition
//! \~russian - **Event (Событие)** — триггер, вызывающий переход
//! \~english - **Guard** — a condition that must be true for a transition to execute
//! \~russian - **Guard (Сторожевая функция)** — условие, которое должно быть истинным для выполнения перехода
//! \~english - **Action** — an operation executed during a transition
//! \~russian - **Action (Действие)** — операция, выполняемая при переходе
//! \~english - **Parallel** — a state where all substates are activated simultaneously
//! \~russian - **Parallel (Параллельное состояние)** — состояние, в котором все подсостояния активируются одновременно
//!
//! \~english \subsection pim_state_machine_features PIP State Machine Features
//! \~russian \subsection pim_state_machine_features Особенности реализации PIP
//!
//! \~english - **Cannot create state, event, transition on stack** — all objects are created via `new` and managed via pointers
//! \~russian - **Нельзя создавать state, event, transition в стеке** — все объекты создаются через `new` и управляются через указатели
//! \~english - **State machine is the root state** — `PIStateMachine` inherits from `PIStateBase`
//! \~russian - **Машина состояний — это корневой state** — `PIStateMachine` наследуется от `PIStateBase`
//! \~english - **All transitions and states are automatically deleted** — when the parent object is destroyed
//! \~russian - **Все переходы и состояния удаляются автоматически** — при уничтожении родительского объекта
//!
//! \~english \subsection state_types State Types
//! \~russian \subsection state_types Основные типы состояний
//!
//! \~english - **Atomic state** — a state without nested substates
//! \~russian - **Атомарное состояние** — состояние без вложенных подсостояний
//! \~english - **Compound state** — a state containing nested substates
//! \~russian - **Составное состояние** — состояние, содержащее вложенные подсостояния
//! \~english - **Final state** — a terminating state indicating the end of machine execution
//! \~russian - **Финальное состояние** — завершающее состояние, указывающее на окончание работы машины
//! \~english - **Parallel state** — a state where all substates are activated simultaneously
//! \~russian - **Параллельное состояние** — состояние, в котором все подсостояния активируются одновременно
//!
//! \~english \subsection transition_types Transition Types
//! \~russian \subsection transition_types Виды переходов
//!
//! \~english - **Normal transition** — triggers on receiving a specific event
//! \~russian - **Обычный переход** — срабатывает при получении определенного события
//! \~english - **Timeout transition** — triggers automatically after a specified time interval
//! \~russian - **Переход по таймауту** — срабатывает автоматически через заданный промежуток времени
//! \~english - **Guarded transition** — triggers only when a specific condition is met
//! \~russian - **Переход с guard** — срабатывает только при выполнении определенного условия
//!
//! \~english \section state_machine_api State Machine API
//! \~russian \section state_machine_api PIP State Machine API
//!
//! \~english \subsection main_classes Main Classes
//! \~russian \subsection main_classes Основные классы
//!
//! \~english ### PIStateMachine
//!
//! \~english Main state machine class.
//! \~russian Основной класс машины состояний.
//!
//! \~english **Key methods:**
//! \~russian **Ключевые методы:**
//!
//! \~english - `bool start()` — starts state machine execution
//! \~russian - `bool start()` — запускает выполнение машины состояний
//! \~english - `bool isRunning()` — checks if state machine is running
//! \~russian - `bool isRunning()` — проверяет, запущена ли машина
//! \~english - `void setOnFinish(std::function<void()> f)` — sets finish callback
//! \~russian - `void setOnFinish(std::function<void()> f)` — устанавливает коллбэк завершения
//! \~english - `bool postEvent(int event_id, Args... args)` — posts event to state machine
//! \~russian - `bool postEvent(int event_id, Args... args)` — отправляет событие в машину состояний
//!
//! \~english ### PIStateBase
//!
//! \~english Base class for all states.
//! \~russian Базовый класс для всех состояний.
//!
//! \~english **Key methods:**
//! \~russian **Ключевые методы:**
//!
//! \~english - `virtual void onEnter()` — called when state is entered
//! \~russian - `virtual void onEnter()` — вызывается при входе в состояние
//! \~english - `virtual void onExit()` — called when state is exited
//! \~russian - `virtual void onExit()` — вызывается при выходе из состояния
//! \~english - `void addState(PIStateBase *s)` — adds child state
//! \~russian - `void addState(PIStateBase *s)` — добавляет дочернее состояние
//! \~english - `PITransitionBase *addTransition(PIStateBase *target, int event_id)` — adds transition
//! \~russian - `PITransitionBase *addTransition(PIStateBase *target, int event_id)` — добавляет переход
//! \~english - `PITransitionTimeout *addTimeoutTransition(PIStateBase *target, PISystemTime timeout)` — adds timeout transition
//! \~russian - `PITransitionTimeout *addTimeoutTransition(PIStateBase *target, PISystemTime timeout)` — добавляет переход по таймауту
//! \~english - `void setParallel(bool yes)` — sets parallel mode
//! \~russian - `void setParallel(bool yes)` — устанавливает параллельный режим
//!
//! \~english ### PIStateLambda
//!
//! \~english State with lambda callbacks.
//! \~russian Состояние с lambda-коллбэками.
//!
//! \~english ```cpp
//! \~english PIStateLambda(std::function<void()> on_enter, std::function<void()> on_exit = nullptr, const PIString &n = {})
//! \~english ```
//! \~russian ```cpp
//! \~russian PIStateLambda(std::function<void()> on_enter, std::function<void()> on_exit = nullptr, const PIString &n = {})
//! \~russian ```
//!
//! \~english ### PIStateFinal
//!
//! \~english Final state of state machine.
//! \~russian Финальное состояние машины состояний.
//!
//! \~english ```cpp
//! \~english PIStateFinal(std::function<void()> on_finish = nullptr, const PIString &n = {})
//! \~english ```
//! \~russian ```cpp
//! \~russian PIStateFinal(std::function<void()> on_finish = nullptr, const PIString &n = {})
//! \~russian ```
//!
//! \~english ### PITransitionBase
//!
//! \~english Base class for transitions.
//! \~russian Базовый класс для переходов.
//!
//! \~english **Key methods:**
//! \~russian **Ключевые методы:**
//!
//! \~english - `PITransitionBase *addGuard(std::function<R(Args...)> f)` — adds guard function
//! \~russian - `PITransitionBase *addGuard(std::function<R(Args...)> f)` — добавляет сторожевую функцию
//! \~english - `PITransitionBase *addAction(std::function<void()> a)` — adds action
//! \~russian - `PITransitionBase *addAction(std::function<void()> a)` — добавляет действие
//! \~english - `void trigger()` — triggers transition
//! \~russian - `void trigger()` — запускает переход
//!
//! \~english ### PITransitionTimeout
//!
//! \~english Transition that triggers after a specified timeout.
//! \~russian Переход, срабатывающий через заданный промежуток времени.
//!
//! \~english \section usage_examples Usage Examples
//! \~russian \section usage_examples Примеры использования
//!
//! \~english \subsection simple_state_machine Simple State Machine
//! \~russian \subsection simple_state_machine Простая машина состояний
//!
//! \~english ```cpp
//! \~english #include "pistatemachine.h"
//! \~english #include "pisystemtime.h"
//! \~english
//! \~english // Create state machine
//! \~english PIStateMachine *machine = new PIStateMachine("Main");
//! \~english
//! \~english // Create states
//! \~english PIStateLambda *idle = new PIStateLambda(
//! \~english []() { piCout << "Entering Idle state\n"; },
//! \~english []() { piCout << "Exiting Idle state\n"; },
//! \~english "Idle"
//! \~english );
//! \~english PIStateLambda *running = new PIStateLambda(
//! \~english []() { piCout << "Entering Running state\n"; },
//! \~english []() { piCout << "Exiting Running state\n"; },
//! \~english "Running"
//! \~english );
//! \~english PIStateFinal *finish = new PIStateFinal(
//! \~english []() { piCout << "Machine finished\n"; },
//! \~english "Finish"
//! \~english );
//! \~english
//! \~english // Add states
//! \~english machine->addState(idle);
//! \~english machine->addState(running);
//! \~english machine->addState(finish);
//! \~english
//! \~english // Set initial state
//! \~english idle->setInitialState(idle);
//! \~english running->setInitialState(running);
//! \~english machine->setInitialState(idle);
//! \~english
//! \~english // Add transitions
//! \~english idle->addTransition(running, 1);
//! \~english running->addTransition(finish, 2);
//! \~english
//! \~english // Set finish callback
//! \~english machine->setOnFinish([]() { piCout << "Machine execution completed\n"; });
//! \~english
//! \~english // Start machine
//! \~english machine->start();
//! \~english
//! \~english // Post events
//! \~english machine->postEvent(1); // Transition to Running
//! \~english machine->postEvent(2); // Transition to Finish
//! \~english ```
//! \~russian ```cpp
//! \~russian #include "pistatemachine.h"
//! \~russian #include "pisystemtime.h"
//! \~russian
//! \~russian // Создаем машину состояний
//! \~russian PIStateMachine *machine = new PIStateMachine("Main");
//! \~russian
//! \~russian // Создаем состояния
//! \~russian PIStateLambda *idle = new PIStateLambda(
//! \~russian []() { piCout << "Entering Idle state\n"; },
//! \~russian []() { piCout << "Exiting Idle state\n"; },
//! \~russian "Idle"
//! \~russian );
//! \~russian PIStateLambda *running = new PIStateLambda(
//! \~russian []() { piCout << "Entering Running state\n"; },
//! \~russian []() { piCout << "Exiting Running state\n"; },
//! \~russian "Running"
//! \~russian );
//! \~russian PIStateFinal *finish = new PIStateFinal(
//! \~russian []() { piCout << "Machine finished\n"; },
//! \~russian "Finish"
//! \~russian );
//! \~russian
//! \~russian // Добавляем состояния
//! \~russian machine->addState(idle);
//! \~russian machine->addState(running);
//! \~russian machine->addState(finish);
//! \~russian
//! \~russian // Устанавливаем начальное состояние
//! \~russian idle->setInitialState(idle);
//! \~russian running->setInitialState(running);
//! \~russian machine->setInitialState(idle);
//! \~russian
//! \~russian // Добавляем переходы
//! \~russian idle->addTransition(running, 1);
//! \~russian running->addTransition(finish, 2);
//! \~russian
//! \~russian // Устанавливаем коллбэк завершения
//! \~russian machine->setOnFinish([]() { piCout << "Machine execution completed\n"; });
//! \~russian
//! \~russian // Запускаем машину
//! \~russian machine->start();
//! \~russian
//! \~russian // Отправляем события
//! \~russian machine->postEvent(1); // Перейти в Running
//! \~russian machine->postEvent(2); // Перейти в Finish
//! \~russian ```
//!
//! \~english \subsection guarded_transitions Guarded Transitions
//! \~russian \subsection guarded_transitions Машина состояний с guard-функциями
//!
//! \~english ```cpp
//! \~english PIStateMachine *machine = new PIStateMachine("With Guards");
//! \~english
//! \~english PIStateLambda *stateA = new PIStateLambda([]() { piCout << "State A\n"; }, nullptr, "A");
//! \~english PIStateLambda *stateB = new PIStateLambda([]() { piCout << "State B\n"; }, nullptr, "B");
//! \~english PIStateLambda *stateC = new PIStateLambda([]() { piCout << "State C\n"; }, nullptr, "C");
//! \~english
//! \~english machine->addState(stateA);
//! \~english machine->addState(stateB);
//! \~english machine->addState(stateC);
//! \~english
//! \~english stateA->setInitialState(stateA);
//! \~english machine->setInitialState(stateA);
//! \~english
//! \~english // Transition with guard function
//! \~english auto *t1 = stateA->addTransition(stateB, 1);
//! \~english t1->addGuard([](int value) -> bool {
//! \~english return value > 10;
//! \~english });
//! \~english
//! \~english // Transition with another guard function
//! \~english auto *t2 = stateB->addTransition(stateC, 2);
//! \~english t2->addGuard([](const PIString &msg) -> bool {
//! \~english return msg == "allowed";
//! \~english });
//! \~english
//! \~english machine->start();
//! \~english
//! \~english // First call will not execute (value <= 10)
//! \~english machine->postEvent(1, 5);
//! \~english
//! \~english // Second call will execute (value > 10)
//! \~english machine->postEvent(1, 15);
//! \~english
//! \~english // First call will not execute (msg != "allowed")
//! \~english machine->postEvent(2, "test");
//! \~english
//! \~english // Second call will execute (msg == "allowed")
//! \~english machine->postEvent(2, "allowed");
//! \~english ```
//! \~russian ```cpp
//! \~russian PIStateMachine *machine = new PIStateMachine("With Guards");
//! \~russian
//! \~russian PIStateLambda *stateA = new PIStateLambda([]() { piCout << "State A\n"; }, nullptr, "A");
//! \~russian PIStateLambda *stateB = new PIStateLambda([]() { piCout << "State B\n"; }, nullptr, "B");
//! \~russian PIStateLambda *stateC = new PIStateLambda([]() { piCout << "State C\n"; }, nullptr, "C");
//! \~russian
//! \~russian machine->addState(stateA);
//! \~russian machine->addState(stateB);
//! \~russian machine->addState(stateC);
//! \~russian
//! \~russian stateA->setInitialState(stateA);
//! \~russian machine->setInitialState(stateA);
//! \~russian
//! \~russian // Переход с guard-функцией
//! \~russian auto *t1 = stateA->addTransition(stateB, 1);
//! \~russian t1->addGuard([](int value) -> bool {
//! \~russian return value > 10;
//! \~russian });
//! \~russian
//! \~russian // Переход с другой guard-функцией
//! \~russian auto *t2 = stateB->addTransition(stateC, 2);
//! \~russian t2->addGuard([](const PIString &msg) -> bool {
//! \~russian return msg == "allowed";
//! \~russian });
//! \~russian
//! \~russian machine->start();
//! \~russian
//! \~russian // Первый вызов не выполнится (value <= 10)
//! \~russian machine->postEvent(1, 5);
//! \~russian
//! \~russian // Второй вызов выполнится (value > 10)
//! \~russian machine->postEvent(1, 15);
//! \~russian
//! \~russian // Первый вызов не выполнится (msg != "allowed")
//! \~russian machine->postEvent(2, "test");
//! \~russian
//! \~russian // Второй вызов выполнится (msg == "allowed")
//! \~russian machine->postEvent(2, "allowed");
//! \~russian ```
//!
//! \~english \subsection timeout_transitions Timeout Transitions
//! \~russian \subsection timeout_transitions Машина состояний с таймаутами
//!
//! \~english ```cpp
//! \~english PIStateMachine *machine = new PIStateMachine("With Timeout");
//! \~english
//! \~english PIStateLambda *working = new PIStateLambda(
//! \~english []() { piCout << "Working...\n"; },
//! \~english []() { piCout << "Stop working\n"; },
//! \~english "Working"
//! \~english );
//! \~english PIStateLambda *timeoutState = new PIStateLambda([]() { piCout << "Timeout occurred\n"; }, nullptr, "Timeout");
//! \~english PIStateFinal *finish = new PIStateFinal([]() { piCout << "Done\n"; }, "Finish");
//! \~english
//! \~english machine->addState(working);
//! \~english machine->addState(timeoutState);
//! \~english machine->addState(finish);
//! \~english
//! \~english working->setInitialState(working);
//! \~english machine->setInitialState(working);
//! \~english
//! \~english // Add timeout transition (after 5 seconds)
//! \~english working->addTimeoutTransition(timeoutState, PISystemTime::fromSeconds(5));
//! \~english
//! \~english // Add transition from timeoutState to finish
//! \~english timeoutState->addTransition(finish, 1);
//! \~english
//! \~english machine->start();
//! \~english ```
//! \~russian ```cpp
//! \~russian PIStateMachine *machine = new PIStateMachine("With Timeout");
//! \~russian
//! \~russian PIStateLambda *working = new PIStateLambda(
//! \~russian []() { piCout << "Working...\n"; },
//! \~russian []() { piCout << "Stop working\n"; },
//! \~russian "Working"
//! \~russian );
//! \~russian PIStateLambda *timeoutState = new PIStateLambda([]() { piCout << "Timeout occurred\n"; }, nullptr, "Timeout");
//! \~russian PIStateFinal *finish = new PIStateFinal([]() { piCout << "Done\n"; }, "Finish");
//! \~russian
//! \~russian machine->addState(working);
//! \~russian machine->addState(timeoutState);
//! \~russian machine->addState(finish);
//! \~russian
//! \~russian working->setInitialState(working);
//! \~russian machine->setInitialState(working);
//! \~russian
//! \~russian // Добавляем переход по таймауту (через 5 секунд)
//! \~russian working->addTimeoutTransition(timeoutState, PISystemTime::fromSeconds(5));
//! \~russian
//! \~russian // Добавляем переход из timeoutState в finish
//! \~russian timeoutState->addTransition(finish, 1);
//! \~russian
//! \~russian machine->start();
//! \~russian ```
//!
//! \~english \subsection compound_states Compound States
//! \~russian \subsection compound_states Составные состояния
//!
//! \~english ```cpp
//! \~english PIStateMachine *machine = new PIStateMachine("Compound States");
//! \~english
//! \~english // Root state (machine)
//! \~english PIStateLambda *root = new PIStateLambda([]() { piCout << "Root state\n"; }, nullptr, "Root");
//! \~english
//! \~english // Compound state with substates
//! \~english PIStateLambda *parent = new PIStateLambda([]() { piCout << "Parent state\n"; }, nullptr, "Parent");
//! \~english PIStateLambda *child1 = new PIStateLambda([]() { piCout << "Child 1\n"; }, nullptr, "Child1");
//! \~english PIStateLambda *child2 = new PIStateLambda([]() { piCout << "Child 2\n"; }, nullptr, "Child2");
//! \~english
//! \~english parent->setInitialState(child1);
//! \~english parent->addState(child1);
//! \~english parent->addState(child2);
//! \~english root->addState(parent);
//! \~english
//! \~english machine->addState(root);
//! \~english machine->setInitialState(root);
//! \~english
//! \~english // Add transitions
//! \~english root->addTransition(parent, 1);
//! \~english parent->addTransition(root, 2);
//! \~english
//! \~english machine->start();
//! \~english
//! \~english // Transition to parent
//! \~english machine->postEvent(1);
//! \~english
//! \~english // Transition back
//! \~english machine->postEvent(2);
//! \~english ```
//! \~russian ```cpp
//! \~russian PIStateMachine *machine = new PIStateMachine("Compound States");
//! \~russian
//! \~russian // Корневое состояние (машина)
//! \~russian PIStateLambda *root = new PIStateLambda([]() { piCout << "Root state\n"; }, nullptr, "Root");
//! \~russian
//! \~russian // Составное состояние с подсостояниями
//! \~russian PIStateLambda *parent = new PIStateLambda([]() { piCout << "Parent state\n"; }, nullptr, "Parent");
//! \~russian PIStateLambda *child1 = new PIStateLambda([]() { piCout << "Child 1\n"; }, nullptr, "Child1");
//! \~russian PIStateLambda *child2 = new PIStateLambda([]() { piCout << "Child 2\n"; }, nullptr, "Child2");
//! \~russian
//! \~russian parent->setInitialState(child1);
//! \~russian parent->addState(child1);
//! \~russian parent->addState(child2);
//! \~russian root->addState(parent);
//! \~russian
//! \~russian machine->addState(root);
//! \~russian machine->setInitialState(root);
//! \~russian
//! \~russian // Добавляем переходы
//! \~russian root->addTransition(parent, 1);
//! \~russian parent->addTransition(root, 2);
//! \~russian
//! \~russian machine->start();
//! \~russian
//! \~russian // Переход в parent
//! \~russian machine->postEvent(1);
//! \~russian
//! \~russian // Переход обратно
//! \~russian machine->postEvent(2);
//! \~russian ```
//!
//! \~english \subsection parallel_states Parallel States
//! \~russian \subsection parallel_states Параллельные состояния
//!
//! \~english ```cpp
//! \~english PIStateMachine *machine = new PIStateMachine("Parallel States");
//! \~english
//! \~english PIStateLambda *root = new PIStateLambda([]() { piCout << "Root\n"; }, nullptr, "Root");
//! \~english PIStateLambda *parallel = new PIStateLambda([]() { piCout << "Parallel\n"; }, nullptr, "Parallel");
//! \~english PIStateLambda *sub1 = new PIStateLambda([]() { piCout << "Substate 1\n"; }, nullptr, "Sub1");
//! \~english PIStateLambda *sub2 = new PIStateLambda([]() { piCout << "Substate 2\n"; }, nullptr, "Sub2");
//! \~english
//! \~english // Enable parallel mode
//! \~english parallel->setParallel(true);
//! \~english parallel->addState(sub1);
//! \~english parallel->addState(sub2);
//! \~english parallel->setInitialState(sub1);
//! \~english root->addState(parallel);
//! \~english
//! \~english machine->addState(root);
//! \~english machine->setInitialState(root);
//! \~english
//! \~english machine->start();
//! \~english
//! \~english // When entering parallel, both substates are activated simultaneously
//! \~english ```
//! \~russian ```cpp
//! \~russian PIStateMachine *machine = new PIStateMachine("Parallel States");
//! \~russian
//! \~russian PIStateLambda *root = new PIStateLambda([]() { piCout << "Root\n"; }, nullptr, "Root");
//! \~russian PIStateLambda *parallel = new PIStateLambda([]() { piCout << "Parallel\n"; }, nullptr, "Parallel");
//! \~russian PIStateLambda *sub1 = new PIStateLambda([]() { piCout << "Substate 1\n"; }, nullptr, "Sub1");
//! \~russian PIStateLambda *sub2 = new PIStateLambda([]() { piCout << "Substate 2\n"; }, nullptr, "Sub2");
//! \~russian
//! \~russian // Включаем параллельный режим
//! \~russian parallel->setParallel(true);
//! \~russian parallel->addState(sub1);
//! \~russian parallel->addState(sub2);
//! \~russian parallel->setInitialState(sub1);
//! \~russian root->addState(parallel);
//! \~russian
//! \~russian machine->addState(root);
//! \~russian machine->setInitialState(root);
//! \~russian
//! \~russian machine->start();
//! \~russian
//! \~russian // При входе в parallel оба подсостояния активируются одновременно
//! \~russian ```
//!
//! \~english \subsection transitions_with_actions Transitions with Actions
//! \~russian \subsection transitions_with_actions Машина состояний с действиями
//!
//! \~english ```cpp
//! \~english PIStateMachine *machine = new PIStateMachine("With Actions");
//! \~english
//! \~english PIStateLambda *stateA = new PIStateLambda([]() { piCout << "State A\n"; }, nullptr, "A");
//! \~english PIStateLambda *stateB = new PIStateLambda([]() { piCout << "State B\n"; }, nullptr, "B");
//! \~english
//! \~english machine->addState(stateA);
//! \~english machine->addState(stateB);
//! \~english
//! \~english machine->setInitialState(stateA);
//! \~english
//! \~english // Add transition with action
//! \~english auto *t = stateA->addTransition(stateB, 1);
//! \~english t->addAction([]() { piCout << "Action during transition\n"; });
//! \~english
//! \~english machine->start();
//! \~english machine->postEvent(1);
//! \~english ```
//! \~russian ```cpp
//! \~russian PIStateMachine *machine = new PIStateMachine("With Actions");
//! \~russian
//! \~russian PIStateLambda *stateA = new PIStateLambda([]() { piCout << "State A\n"; }, nullptr, "A");
//! \~russian PIStateLambda *stateB = new PIStateLambda([]() { piCout << "State B\n"; }, nullptr, "B");
//! \~russian
//! \~russian machine->addState(stateA);
//! \~russian machine->addState(stateB);
//! \~russian
//! \~russian machine->setInitialState(stateA);
//! \~russian
//! \~russian // Добавляем переход с действием
//! \~russian auto *t = stateA->addTransition(stateB, 1);
//! \~russian t->addAction([]() { piCout << "Action during transition\n"; });
//! \~russian
//! \~russian machine->start();
//! \~russian machine->postEvent(1);
//! \~russian ```
//!
//! \~english \section threading Thread Safety
//! \~russian \section threading Потокобезопасность
//!
//! \~english State machine is thread-safe. The `postEvent` method uses a queue to handle nested calls, allowing safe event posting from
//! different threads.
//! \~russian Машина состояний PIP потокобезопасна. Метод `postEvent` использует очередь для обработки вложенных вызовов, что позволяет
//! безопасно отправлять события из разных потоков.
//!
//! \~english \section usage_rules Usage Rules
//! \~russian \section usage_rules Правила использования
//!
//! \~english \subsection cannot_stack Cannot Create on Stack
//! \~russian \subsection cannot_stack Нельзя создавать в стеке
//!
//! \~english ```cpp
//! \~english // ❌ WRONG
//! \~english PIStateLambda state([]() {}, nullptr, "State");
//! \~english
//! \~english // ✅ CORRECT
//! \~english PIStateLambda *state = new PIStateLambda([]() {}, nullptr, "State");
//! \~english ```
//! \~russian ```cpp
//! \~russian // ❌ НЕЛЬЗЯ
//! \~russian PIStateLambda state([]() {}, nullptr, "State");
//! \~russian
//! \~russian // ✅ ПРАВИЛЬНО
//! \~russian PIStateLambda *state = new PIStateLambda([]() {}, nullptr, "State");
//! \~russian ```
//!
//! \~english \subsection proper_hierarchy Proper Object Hierarchy
//! \~russian \subsection proper_hierarchy Правильная иерархия объектов
//!
//! \~english ```cpp
//! \~english PIStateMachine *machine = new PIStateMachine("Main");
//! \~english
//! \~english // States are created via new and added to machine or another state
//! \~english PIStateLambda *state1 = new PIStateLambda([]() {}, nullptr, "State1");
//! \~english PIStateLambda *state2 = new PIStateLambda([]() {}, nullptr, "State2");
//! \~english
//! \~english machine->addState(state1);
//! \~english machine->addState(state2);
//! \~english
//! \~english // Transitions are added to states via addTransition
//! \~english state1->addTransition(state2, 1);
//! \~english
//! \~english // Machine is started
//! \~english machine->start();
//! \~english ```
//! \~russian ```cpp
//! \~russian PIStateMachine *machine = new PIStateMachine("Main");
//! \~russian
//! \~russian // Состояния создаются через new и добавляются в машину или другое состояние
//! \~russian PIStateLambda *state1 = new PIStateLambda([]() {}, nullptr, "State1");
//! \~russian PIStateLambda *state2 = new PIStateLambda([]() {}, nullptr, "State2");
//! \~russian
//! \~russian machine->addState(state1);
//! \~russian machine->addState(state2);
//! \~russian
//! \~russian // Переходы добавляются к состояниям через addTransition
//! \~russian state1->addTransition(state2, 1);
//! \~russian
//! \~russian // Машина запускается
//! \~russian machine->start();
//! \~russian ```
//!
//! \~english \subsection memory_cleanup Memory Cleanup
//! \~russian \subsection memory_cleanup Очистка памяти
//!
//! \~english All objects (states, transitions) are automatically deleted when the parent object is destroyed:
//! \~russian Все объекты (состояния, переходы) автоматически удаляются при уничтожении родительского объекта:
//!
//! \~english - When `PIStateMachine` is destroyed, all states and transitions are deleted
//! \~russian - При уничтожении `PIStateMachine` удаляются все состояния и переходы
//! \~english - When `PIStateBase` is destroyed, all child states and transitions are deleted
//! \~russian - При уничтожении `PIStateBase` удаляются все дочерние состояния и переходы
//!
//! \~english \section debugging Debugging
//! \~russian \section debugging Отладка
//!
//! \~english For debugging, you can use the `print()` method to output the state tree:
//! \~russian Для отладки можно использовать метод `print()` для вывода дерева состояний:
//!
//! \~english ```cpp
//! \~english machine->print();
//! \~english ```
//! \~russian ```cpp
//! \~russian machine->print();
//! \~russian ```
//!
//! \~english Also, you can use `activeAtomics()` to get a list of active states.
//! \~russian Также можно использовать `activeAtomics()` для получения списка активных состояний.
//!
//! \~english \section related_modules Related Modules
//! \~russian \section related_modules Связанные модули
//!
//! \~english - \ref DateTime module for `PISystemTime` used in timeout transitions
//! \~russian - \ref DateTime модуль для `PISystemTime`, используемого в переходах по таймауту
//!
//! \~\}
#ifndef PISTATEMACHINEMODULE_H
#define PISTATEMACHINEMODULE_H