merged AI doc, some new pages
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user