Files
pip/doc/pages/state_machine.md
2026-03-12 14:46:57 +03:00

5.3 KiB
Raw Blame History

~english \page state_machine State machine ~russian \page state_machine Машина состояний

~english

The state machine module (\a PIStateMachine) provides hierarchical states, event-driven and timeout-driven transitions, and aligns with the SCXML idea of state charts.

Concepts

  • State — a named node with an optional entry handler. You add states with \a PIStateMachine::addState() (or equivalent on the template subclass), giving an enum or id, name, and optional handler.
  • Transition (rule) — from one state to another, triggered by an event (and optionally guarded). Use \a addRule() to register a transition; you can attach conditions and actions.
  • Event — an integer id posted with \a postEvent(); the machine delivers it to active states and runs the first matching transition guard.
  • Conditions — named flags that can be required for a transition (e.g. \a addCondition() on a \a Rule). Call \a performCondition() to set them; \a resetConditions() to clear.
  • Timeout — a transition can fire after a delay; combine with \a PITimer or internal timeout support in transition classes.

The machine is a \a PIObject subclass; you can connect timers or other objects to post events. Call \a setInitialState() and \a start() to run. Use \a switchToState() for direct state changes, \a performCondition() to satisfy named conditions.

Minimal example

Define an enum for states, subclass \a PIStateMachine, add states and rules in the constructor, set the initial state, then start. Post events from keyboard, timer, or other handlers.

\code{.cpp} enum Mode { Start, Manual, Auto, Finish, End };

class Machine : public PIStateMachine { PIOBJECT_SUBCLASS(Machine, PIObject) public: Machine() { addState(Start, "start", HANDLER(onStart)); addState(Manual, "manual", HANDLER(onManual)); addState(Auto, "auto", HANDLER(onAuto)); addRule(Start, Manual, "init_ok", HANDLER(beginManual)); addRule(Manual, Auto, HANDLER(toAuto)); addRule(Auto, Manual, HANDLER(toManual)); setInitialState(Start); } EVENT_HANDLER(void, onStart) { /* entry / } EVENT_HANDLER(void, onManual) { / entry / } EVENT_HANDLER(void, onAuto) { / entry / } EVENT_HANDLER(void, beginManual) { / transition */ } EVENT_HANDLER(void, toAuto) { } EVENT_HANDLER(void, toManual) { } };

Machine machine; // In key handler: machine.performCondition("init_ok"); or machine.switchToState(Manual); \endcode

Full example: doc/examples/pistatemachine.cpp. API details: \a PIStateMachine, \a PIStateBase, \a pistatemachine_state.h, \a pistatemachine_transition.h.

~russian

Модуль машины состояний (\a PIStateMachine) предоставляет иерархические состояния, переходы по событиям и по таймауту и ориентирован на идеи SCXML.

Концепции

  • Состояние — именованный узел с опциональным обработчиком входа. Состояния добавляются через \a PIStateMachine::addState() (или аналог в шаблонном подклассе): enum/id, имя, при необходимости обработчик.
  • Переход (правило) — из одного состояния в другое по событию (и при выполнении условий). \a addRule() регистрирует переход; можно задать условия и действия.
  • Событие — целочисленный id, посылаемый через \a postEvent(); машина доставляет его активным состояниям и выполняет первый подходящий переход.
  • Условия — именованные флаги, требуемые для перехода (например \a addCondition() на \a Rule). Установка через \a performCondition(), сброс — \a resetConditions().
  • Таймаут — переход по истечении времени; используется вместе с \a PITimer или встроенной поддержкой таймаутов в классах переходов.

Машина — подкласс \a PIObject; к ней можно подключать таймеры и другие объекты для посылки событий. Перед запуском задают \a setInitialState() и вызывают \a start(). \a switchToState() — прямая смена состояния, \a performCondition() — выполнение именованного условия.

Минимальный пример

Определяют enum состояний, подкласс \a PIStateMachine, в конструкторе добавляют состояния и правила, задают начальное состояние и запускают. События посылают из обработчика клавиш, таймера и т.д. Код минимального примера приведён выше в англоязычной секции.

Полный пример: doc/examples/pistatemachine.cpp. Детали API: \a PIStateMachine, \a PIStateBase, \a pistatemachine_state.h, \a pistatemachine_transition.h.