ReplayingΒΆ
If you have a Sen archive, you can play it back using the replayer component.
There are two ways of starting a replay. The simplest one is to do:
# load the archive and start the playback straight away
$ sen replay my_archive
# load the archive but keep the replay stopped
$ sen replay my_archive --stopped
You can see that this approach creates the replay in an independent process. While convenient, sometimes you might want to do embed replay in your own process. For example, in testing or during development.
This can be done by adding the replayer component to your configuration file. For example:
- name: replayer
autoOpen: school_recording # this is the path to the archive
autoPlay: true # start the playback right away
group: 20
The configuration options are defined in the component's STL:
package sen.components.replayer;
// Overall component configuration
struct Configuration
{
bus : string, // bus to publish the object (local.replay by default)
samplingPeriod : Duration, // max sampling period for flushing the replayed data
autoOpen : string, // optional archive path to auto open on start-up (empty by default)
autoPlay : bool // if autoOpen is not empty, try to play it on start-up (false by default)
}
The main object of the replayer component is the Replayer object. It allows you to open multiple
archives for replay. Every time you open an archive, a Replay object is created, which is the one
you can use to control the playback.
The interface for these objects is this:
import "stl/sen/db/basic_types.stl"
package sen.components.replayer;
// represents the replayer component and manages Replay objects.
class Replayer
{
// if true, automatically calls play when opening a replay
var autoPlay : bool [static];
// opens an archive in a given path, and creates a named Replay object.
fn open(name: string, path: string) [confirmed];
// closes the named Replay object, if any.
fn close(name: string) [confirmed];
// closes all previously opened replays
fn closeAll() [confirmed];
}
// the state in which a Replay can be
enum ReplayStatus: u8
{
stopped, // not running, at the start of the archive
paused, // not running, at the position when pause was called
playing // performing the replay
}
// controls the replay of a given archive
class Replay
{
// information about the archive being replayed
var archiveInfo : sen.db.Summary [static];
// file path to the archive
var archivePath : string [static];
// playback status
var status : ReplayStatus [confirmed];
// playback time
var playbackTime : TimeStamp [bestEffort];
// starts the playback from the current position
fn play() [confirmed];
// hold the playback position, if playing
fn pause() [confirmed];
// goes to the start of the playback, erasing all objects
fn stop() [confirmed];
// restores the playback to the keyframe that's closest to a given time
fn seek(time: TimeStamp) [confirmed];
// if paused or stopped, advances the playback a given time delta
fn advance(time: Duration);
}
The typical usage would be something like this:
sequenceDiagram
actor You
You->>+Replayer: open(archive)
Replayer->>+Replay: create()
You->>+Replay: play()
You->>+Replay: pause()
You->>+Replay: moveTo(time)
You->>+Replayer: close(archive)
You-xReplay: delete