AnimationStateSnapshotter

class AnimationStateSnapshotter(parent: ModelElement, captureSpec: CaptureSpec, keyframeTime: Double, name: String? = null) : ModelElement(source)

Emits a single opening-frame keyframe at keyframeTime (a capture window's startTime, 9A.2/9B): a comprehensive re-statement of the model's current animation state, so a windowed trace whose window begins mid-run is replayable from its first frame. Without it, a renderer joining at startTime would see only the deltas that happen after startTime and would not know what already exists.

How it runs. In initialize (which fires once per replication, giving automatic re-arming) it schedules one KSLEvent.VERY_HIGH_PRIORITY event at keyframeTime — no EventGenerator, because a keyframe is a single instant, not a recurring sample. The very-high priority makes the keyframe fire before any real events scheduled at keyframeTime, so the renderer sees the full snapshot first and then the in-window deltas refine it. If keyframeTime <= time at initialization (the window already includes the run start) nothing is scheduled — the live stream already covers the opening frame.

What it emits (each guarded by sink.isActive, gated by captureSpec just as the live emitters are), in dependency order so every reference resolves:

  1. AnimationEvent.EntityCreated for every live in-flight entity (the union of every ProcessModel's suspendedEntitiesSnapshot, 9B.1) — at a scheduled instant that set is exactly the in-flight entities. Entities are not a CaptureSpec kind, so all live ones register (matching the live stream, where entity events are not element-gated).

  2. Per captured Resource: AnimationEvent.ResourceStateChanged plus an AnimationEvent.SeizeAllocated per current allocation (placing each served entity at its resource).

  3. Per captured SResource: AnimationEvent.ResourceStateChanged (station state).

  4. Per captured Queue: AnimationEvent.QueueLengthChanged plus an AnimationEvent.QObjectEnqueued per member (placing each queued entity in its queue).

  5. Per captured Conveyor: AnimationEvent.ConveyorDefined (its anchors, rebuilt from the entry/exit cells since the original fires at t=0) plus an AnimationEvent.ConveyorItemMoved per item on the belt at its front cell (placing each conveyed entity).

  6. Per captured AgentModel: AnimationEvent.SpaceDefined per projection, then per agent AnimationEvent.AgentRegistered and AnimationEvent.AgentStateEntered (current statechart state), then AnimationEvent.AgentPositionChanged for each placed agent.

  7. Per captured Response/Counter: AnimationEvent.ResponseObserved (current value/statistics).

  8. Residual entity placement (the position-resolution order): any live entity not already placed by a queue (step 4), an allocation (step 2), or a conveyor (step 5) is given a rest placement via AnimationEvent.MoveCompleted at its currentLocation, but only when that location is Cartesian (finite x/y); coordinate-free models (e.g. DistancesModel, whose coordinates are NaN) leave the entity registered-but-unplaced rather than emit a meaningless NaN position.

Semantics / limitation. The opening frame is a static rest snapshot. An entity that was mid-move when the window opened is suspended and falls to step 8, so it is shown at rest at its current location; its in-flight interpolation is not reconstructed — it snaps to correctness at its next in-window event. This is the right trade for a keyframe and avoids fabricating interpolation state.

Parameters

parent

the model element this snapshotter is parented to (typically the model)

captureSpec

the same spec that gates the live emitters, so the keyframe captures the same elements

keyframeTime

the simulated time at which to emit the opening frame (a capture window's startTime)

name

an optional model-element name

Constructors

Link copied to clipboard
constructor(parent: ModelElement, captureSpec: CaptureSpec, keyframeTime: Double, name: String? = null)

Functions

Link copied to clipboard
protected open override fun initialize()

This method should be overridden by subclasses that need actions performed to initialize prior to a replication. It is called once before each replication occurs if the model element wants initialization. It is called after beforeReplication() is called