Files
raphael d159bd39d7 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>
2026-06-08 03:35:05 +02:00

63 lines
1.9 KiB
C++

#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