refactor(gem): decompose default handlers per GEM capability + YAML role bindings
register_default_handlers was a relocated app main(): one 1086-line function, all-or-nothing. It is now 15 per-capability registration functions along the lines GEM itself defines (S1F19): identification, equipment constants, clock, event reports, remote commands, trace/limits, spooling, alarms, exceptions, material tracking (E90/E116/E157), carriers (E87), recipes, object services (E39), jobs (E40/E94), terminal services. A sensor-class tool registers three functions instead of carrying carrier/job handlers it doesn't have; register_default_handlers composes all 15. Each function derives exactly the runtime aliases its handlers use (generated programmatically from the moved bodies with boundary/substitution guards — zero hand-retyping). Magic constants are gone: the control-state/clock SVIDs (were hardcoded 1/2) and the CJ Executing/Completed CEIDs (were 400/401) now come from a "roles:" block in equipment.yaml via EquipmentDescriptor, with historical defaults when absent, loader parsing, and validation (CEID roles must name declared events). The coupling is now visible in ONE file instead of silently split between YAML and C++ — the exact drift class this repo's spec-as-data philosophy exists to kill. Tests: capability subsetting, role-driven SVID refresh via S1F3, roles loader (shipped/custom/absent). Battery: core 473/3087 incl. the 53-handler conformance sweep, daemon 125/125, live GEM300 demo (client exit 0), daemon interop 20/20 vs secsgem-py. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -4,15 +4,37 @@
|
||||
|
||||
namespace secsgem::gem {
|
||||
|
||||
// Registers the full default GEM behaviour onto a runtime: every SECS message
|
||||
// handler (S1/S2/S3/S5/S6/S7/S10/S14/S16) on its Router, plus the state-change
|
||||
// emitters (control state, process/control jobs, exceptions, substrates,
|
||||
// modules) on its stores. Shared by the `secs_server` app and the gRPC daemon
|
||||
// so both speak byte-identical GEM — the protocol behaviour lives here, once.
|
||||
// The default GEM behaviour, decomposed along the capability lines GEM
|
||||
// itself defines (the S1F19 compliance list): each function registers one
|
||||
// capability's message handlers and/or state-change emitters onto a runtime.
|
||||
// Equipment implementing a subset of GEM (a sensor with no carriers, a
|
||||
// recipe-less tool) registers only what it is; register_default_handlers
|
||||
// registers everything and is what `secs_server` and `secs_gemd` use.
|
||||
//
|
||||
// Call once after constructing the runtime and before run(). Application
|
||||
// behaviour (host-command callbacks via on_command, sensor value updates) is
|
||||
// layered on top by the caller.
|
||||
// All functions are idempotent-per-slot (later registration replaces the
|
||||
// Router entry / primary handler slot) and must be called before run().
|
||||
// Application behaviour (host-command callbacks via on_command, sensor value
|
||||
// updates) is layered on top by the caller.
|
||||
//
|
||||
// The ids the built-ins target (control-state/clock SVIDs, CJ state CEIDs)
|
||||
// come from the config's `roles:` block — see EquipmentDescriptor.
|
||||
void register_identification(EquipmentRuntime& R); // S1 + E30 control state
|
||||
void register_equipment_constants(EquipmentRuntime& R); // S2F13/15/29
|
||||
void register_clock(EquipmentRuntime& R); // S2F17/31
|
||||
void register_event_reports(EquipmentRuntime& R); // S2F33/35/37, S6F5/15/19/21
|
||||
void register_remote_commands(EquipmentRuntime& R); // S2F21/41/49
|
||||
void register_trace_and_limits(EquipmentRuntime& R); // S2F23/45/47
|
||||
void register_spooling(EquipmentRuntime& R); // S2F43, S6F23
|
||||
void register_alarms(EquipmentRuntime& R); // S5F3/5/7
|
||||
void register_exceptions(EquipmentRuntime& R); // S5F9/11/15 emitters, S5F13/17
|
||||
void register_material_tracking(EquipmentRuntime& R); // E90/E116/E157 emitters
|
||||
void register_carriers(EquipmentRuntime& R); // E87: S3F17/19/25/27
|
||||
void register_recipes(EquipmentRuntime& R); // S7F1/3/5/17/19
|
||||
void register_object_services(EquipmentRuntime& R); // E39: S14F1/3
|
||||
void register_jobs(EquipmentRuntime& R); // E40/E94: S14F9/11, S16Fxx
|
||||
void register_terminal_services(EquipmentRuntime& R); // S10F1/3/5
|
||||
|
||||
// Everything above, in one call.
|
||||
void register_default_handlers(EquipmentRuntime& R);
|
||||
|
||||
} // namespace secsgem::gem
|
||||
|
||||
Reference in New Issue
Block a user