Replay¶
Requires the replay extra (pip install "longeron[replay]").
The replay widget itself lives in longeron.widgets.replay; this module is the kernel-side timeline recorder.
Replay state-machine and action executions over rendered diagrams.
record_timeline() drives a StateMachine
through the same event protocol as Interpreter.simulate while observing
every step through the machine’s on_step hook, producing a
Timeline: per-state activation keyframes plus fired-transition
instants, addressed by instance-qualified names – the machine’s
qualified name extended along the active-state path (the same :: ids
the diagrams and headless SVG use, unique per typed-submachine expansion
site). record_action_timeline() does the
same for action executions via the executor’s step observer: the active
node is the currently-executing named action step, fired records are the
traversed successions, and the axis is always the step index.
The replay widget itself lives in longeron.widgets.replay
(replay_widget() bakes the matching
diagram to SVG and animates the timeline over it); this module is the
kernel-side recorder and needs no widget toolkit. Importing
replay_widget from here still works but is deprecated.
- class longeron.replay.FiredTransition(t, source, target, event)[source]¶
Bases:
objectA fired transition, addressed by model qualified names.
- class longeron.replay.Timeline(t_start, t_end, step_mode, n_steps, tracks, fired, final_state, trace, ignored_events, env, sends, time=0.0, active_states=<factory>, parents=<factory>, env_steps=<factory>)[source]¶
Bases:
objectA recorded simulation, keyed for replay over the state diagram.
Track keyframes and
firedtimes use sim time, except in step mode (t_end == t_start, a pure event cascade): then the key is the step index, and the front-end scrubs over steps instead of time (see the matchingstepModelogic in the widget’s_ESM).- tracks: dict[str, list[tuple[float, bool]]]¶
per-state keyframes [(t_or_index, active)], recorded on change only
- parents: dict[str, str]¶
parent relation between recorded nodes (child qname -> parent qname): the recorded truth the front-end tints composite ancestors with – keys are instance-qualified, so it now agrees with the “::” prefix relation, but it stays authoritative (and keeps older front-end payload handling honest)
- longeron.replay.record_action_timeline(interpreter, action, events=None, *, inputs=None)[source]¶
Run an action and record a replayable
Timeline.Mirrors
Interpreter.run_actionsemantics (eventsfeedacceptstatements), observing every named action step through the executor’son_stephook. The axis is always the step index (step_modeisTrue): step k is the k-th named step entered, active while it executes (nested steps nest, like composite states), and consecutive same-depth steps yield fired records for the traversed successions – routed through intermediate control nodes (decide/merge/fork/join), so each drawn edge on the path pulses. Fired records are matched against the action diagram’s edges by the front-end; records with no matching edge (e.g. across fork branches) are inert.- Return type:
- longeron.replay.record_timeline(interpreter, state_machine, events=None, *, inputs=None, max_steps=1000)[source]¶
Simulate a state machine and record a replayable
Timeline.Mirrors
Interpreter.simulatesemantics:eventsentries are event names or(name, payload)tuples; plain numbers advance the clock.- Return type: