#pragma once #include #include #include #include #include #include "secsgem/gem/carrier_state.hpp" // shared CarrierTransition template // E157 §6 Module Process Tracking — per-module state model for a process // step within a recipe. The lifecycle is similar to E40 PJ but scoped // to a single module step rather than a whole job; an E157 instance is // typically created per (Module, Substrate, RecipeStep) triple by the // process executive when a wafer arrives at a module. // // Wire-byte values per E157-0712 §10.3. namespace secsgem::gem { enum class ModuleState : uint8_t { NotExecuting = 0, GeneralExecuting = 1, // setup, pre-process, etc. StepExecuting = 2, // actively running the recipe step StepCompleted = 3, NoState = 255, }; const char* module_state_name(ModuleState s); std::optional parse_module_state(const std::string& s); enum class ModuleEvent { StartGeneral, // NotExecuting -> GeneralExecuting StartStep, // GeneralExecuting -> StepExecuting CompleteStep, // StepExecuting -> StepCompleted Reset, // any -> NotExecuting (cancellation) Abort, // any -> StepCompleted (early termination) }; const char* module_event_name(ModuleEvent e); using ModuleTable = CarrierTransitionTable; ModuleTable default_module_table(); class ModuleStateMachine { public: using StateChangeHandler = std::function; ModuleStateMachine(); ModuleState state() const { return state_; } void set_state_change_handler(StateChangeHandler h) { on_change_ = std::move(h); } bool on_event(ModuleEvent e); private: ModuleTable table_; ModuleState state_ = ModuleState::NotExecuting; StateChangeHandler on_change_; }; } // namespace secsgem::gem