This commit is contained in:
2026-03-12 19:21:03 +03:00
parent 40cdc90131
commit 6e4a64e64a
4 changed files with 22 additions and 659 deletions

View File

@@ -26,16 +26,14 @@
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/>.
*/
//! \addtogroup Geo
//! \{
//! \~\file pigeomodule.h
//! \defgroup Geo Geo
//! \~\brief
//! \~english Geographical position and Earth models module.
//! \~russian Модуль географической позиции и моделей Земли.
//!
//! \~\details
//! \~english \section cmake_module_Cloud Building with CMake
//! \~russian \section cmake_module_Cloud Сборка с использованием CMake
//! \~english \section cmake_module_Geo Building with CMake
//! \~russian \section cmake_module_Geo Сборка с использованием CMake
//!
//! \~\code
//! find_package(PIP REQUIRED)
@@ -55,10 +53,8 @@
//!
//! \~\authors
//! \~english
//! Ivan Pelipenko peri4ko@yandex.ru;
//! Andrey Bychkov work.a.b@yandex.ru;
//! \~russian
//! Иван Пелипенко peri4ko@yandex.ru;
//! Андрей Бычков work.a.b@yandex.ru;
//!

View File

@@ -33,10 +33,15 @@
//! \~english HTTP client
//! \~russian HTTP клиент
//!
//! \~\details
//! \~english \section cmake_module_HTTPClient Building with CMake
//! \~russian \section cmake_module_HTTPClient Сборка с использованием CMake
//!
//! \~\code
//! find_package(PIP REQUIRED)
//! target_link_libraries([target] PIP::HTTPClient)
//! \endcode
//!
//! \~\details
//! \~english
//! These files provide HTTP client functionality using libcurl for performing asynchronous HTTP requests with callbacks.

View File

@@ -29,10 +29,15 @@
//! \~english HTTP server
//! \~russian HTTP сервер
//!
//! \~\details
//! \~english \section cmake_module_HTTPServer Building with CMake
//! \~russian \section cmake_module_HTTPServer Сборка с использованием CMake
//!
//! \~\code
//! find_package(PIP REQUIRED)
//! target_link_libraries([target] PIP::HTTPServer)
//! \endcode
//!
//! \~\details
//! \~english This file provides includes for the HTTP server module
//! \~russian Этот файл предоставляет включения для модуля HTTP сервера

View File

@@ -1,17 +1,12 @@
/*! \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 Подключает публичные заголовки машины состояний, состояний и переходов.
*/
//! \file pistatemachinemodule.h
//! \ingroup StateMachine
//! \~\brief
//! \~english Declares module entry includes for the state machine API
//! \~russian Объявляет основной include модуля API машины состояний
/*
PIP - Platform Independent Primitives
Module includes
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
@@ -46,656 +41,18 @@
//! \~english
//! The module provides hierarchical states, event-driven transitions, timeout
//! transitions and helper state classes for callback-based logic.
//! Details in \ref state_machine_overview
//! \~russian
//! Модуль предоставляет иерархические состояния, переходы по событиям,
//! переходы по таймауту и вспомогательные классы состояний для логики на callback-функциях.
//! Подробнее \ref state_machine_overview
//!
//! \~\authors
//! \~english
//! Ivan Pelipenko peri4ko@yandex.ru;
//! Andrey Bychkov work.a.b@yandex.ru;
//! \~russian
//! Иван Пелипенко 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