G: CemObjectStore (E120 Common Equipment Model)
Hierarchical object tree for equipment self-description. Each object carries a CemObjectType (Equipment / Subsystem / IODevice / Module / MaterialLocation / Other), an optional parent_objid, and a flat attribute map keyed by name (the wire shape S14F1 / F3 returns). Operations covered: add(CemObject) - dedup'd, validates parent exists get / has - lookup by objid get_attr / set_attr - E14 GetAttr / SetAttr semantics children(parent) - tree traversal; empty parent = roots The flat-map representation matches how E14 ObjectService traffic addresses nodes (by OBJSPEC string). Wiring S14F1/F2 GetAttr and S14F3/F4 SetAttr to this store is a downstream commit; the data model is what was missing. Joins EquipmentDataModel alongside the other top-level stores. Three test cases cover hierarchical add+dedup, children() traversal, and get/set/missing attribute semantics. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#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<ModuleState> 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<ModuleState, ModuleEvent>;
|
||||
ModuleTable default_module_table();
|
||||
|
||||
class ModuleStateMachine {
|
||||
public:
|
||||
using StateChangeHandler =
|
||||
std::function<void(ModuleState from, ModuleState to, ModuleEvent)>;
|
||||
|
||||
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
|
||||
Reference in New Issue
Block a user