SimulationRunner¶
class nmeasim::io::SimulationRunner · Library API
Runs the simulation of a profile on a timer and writes its output to the profile's transports and to an optional recording.
#include <nmeasim/io/simulation_runner.hpp>
Inherits QObject
Declared in src/io/include/nmeasim/io/simulation_runner.hpp (line 135)
Life cycle: apply_profile builds the simulation and one OutputChannel per enabled output, with every transport closed. start opens the outputs and starts the tick timer; pause and resume stop and continue the simulated clock while the outputs stay open; stop stops the timer and closes the outputs. step and seek work in any of these states once a profile is applied. A finite source that reaches its end emits finished and stops the run.
Timing: the tick timer fires every Profile::tick_ms milliseconds of wall-clock time. Each tick hands the simulation the wall-clock time elapsed since the previous tick in whole milliseconds, carrying the remainder to the next tick so that the simulated clock keeps pace with the real one. When the host falls behind by more than one second (the event loop was blocked, the machine was suspended), the tick advances one second only and the rest is dropped, so the vessel never jumps ahead by more than one second in a tick. Time spent paused is not caught up either.
Encoding: every sentence the simulation emits goes, as a line ending in CR LF, to every open NMEA 0183 channel whose filter admits it, with an IEC 61162-450 TAG block in front when the output enables one. After every tick, each open Signal K and ViewSync channel that is due gets one message built from the current state. A recording receives every sentence, unfiltered and without TAG block, but no state message.
Ownership: the runner owns the simulation, the channels with their transports and the recording transport. The transports have no Qt parent.
Threads: the runner, its simulation and its transports are used from the thread that created the runner, which must run a Qt event loop for the timer and the sockets. Every signal is emitted on that thread, either synchronously from inside the public call that caused it or from a timer or socket event.
See also
- docs/explanation/architecture.md, section "Runtime model".
Summary¶
Public member functions
| Name | Description |
|---|---|
SimulationRunner() |
Creates a runner without a simulation. |
~SimulationRunner() |
Destroys the runner, stopping a running simulation first. |
apply_profile() |
Replaces the simulation and the outputs with those described by a profile. |
start() |
Opens every output and the recording, and starts ticking. |
pause() |
Stops advancing the simulated clock while keeping the outputs open. |
resume() |
Continues a paused run without catching up on the time spent paused. |
stop() |
Stops ticking and closes every output and the recording. |
step() |
Takes the smallest step while paused: one recorded sentence during a replay, one tick of Profile::tick_ms otherwise. |
seek() |
Moves a finite source to a position; the state changes at once. |
duration() |
Returns the length of a finite source. |
position() |
Returns the elapsed position within a finite source. |
set_recording() |
Records every emitted sentence to a log file, in addition to the profile outputs. |
recording_path() |
Returns the path of the current recording. |
is_recording() |
Returns whether a recording is set, whether or not the run is going. |
recorder() |
Returns the log transport of the recording, for its state and counters. |
is_running() |
Returns whether the run is going. |
is_paused() |
Returns whether a running simulation is paused. |
simulation() |
Returns the current simulation, for reading the state and changing it between ticks. |
simulation() |
Returns the current simulation, read-only. |
outputs() |
Returns the channels of the enabled outputs of the applied profile. |
profile() |
Returns the profile last applied successfully. |
sentences_emitted() |
Returns the number of NMEA 0183 sentences produced since the profile was applied. |
state_messages_sent() |
Returns the number of Signal K deltas and ViewSync packets sent since the profile was applied. |
Signals
| Name | Description |
|---|---|
started() |
Emitted when the outputs have been opened and ticking began, from start or from step on a runner that was not running. |
paused_changed() |
Emitted when the run is paused or resumed, from pause, resume or step, and with false when stop ends a paused run. |
stopped() |
Emitted when a running simulation stopped and its outputs were closed, from stop, apply_profile, the destructor, or after finished at the end of a finite source. |
ticked() |
Emitted after every tick that advanced the simulation, every step and every seek. |
sentence_emitted() |
Emitted for every line produced, before filtering and whether or not an output is open, from a tick or from step. |
output_error() |
Emitted when an output or the recording reports an error through Transport::error_occurred. |
finished() |
Emitted when the track or log reached its end and does not loop, from a tick or from step; stopped follows immediately. |
recording_changed() |
Emitted when set_recording sets or clears the recording; not when it fails to open the file at once. |
Private member functions
| Name | Description |
|---|---|
tick() |
Advances the simulation by the wall-clock time since the previous tick and sends what it produced; connected to the timeout of tick_timer_. |
emit_sentences() |
Writes sentences to the admitting NMEA 0183 channels and to the recording. |
emit_state_messages() |
Sends one message on every open Signal K and ViewSync channel that is due. |
finish_if_done() |
Emits finished and stops the run (emitting stopped) when the source has reached its end. |
restart_wall_clock() |
Restarts the wall-clock reference of the tick, so that the time before this call is never handed to the simulation. |
make_transport() |
Creates the transport for an output, closed. |
make_source() |
Creates the source of a profile's mode, seeded with the profile's start time. |
Private data members
| Name | Description |
|---|---|
profile_ |
The profile last applied successfully. |
simulation_ |
The simulation of profile_; null before the first successful apply_profile. |
outputs_ |
One channel per enabled output of profile_, in profile order. |
recorder_ |
The recording, or null when not recording. |
tick_timer_ |
Precise timer firing every Profile::tick_ms milliseconds while running; active from start to stop, paused or not. |
wall_clock_ |
Wall-clock reference of the tick, restarted by start, resume and seek. |
wall_consumed_ |
Wall-clock time since wall_clock_ started that has been handed to the simulation. |
paused_ |
True while a running simulation is paused. |
sentences_emitted_ |
Sentences produced since the profile was applied, as sentences_emitted returns. |
state_messages_sent_ |
State messages sent since the profile was applied, as state_messages_sent returns. |
Public member functions¶
SimulationRunner()¶
explicit SimulationRunner(QObject* parent = nullptr)
Creates a runner without a simulation.
Call apply_profile before start; until then start, step and seek do nothing.
Parameters
| Name | Type | Description |
|---|---|---|
parent |
QObject* |
Qt parent that owns the runner; may be null. |
Declared in src/io/include/nmeasim/io/simulation_runner.hpp:144 · defined in src/io/src/simulation_runner.cpp:95
~SimulationRunner()¶
~SimulationRunner() override
Destroys the runner, stopping a running simulation first.
Emits stopped from the destructor when the run was going.
Declared in src/io/include/nmeasim/io/simulation_runner.hpp:148 · defined in src/io/src/simulation_runner.cpp:100
apply_profile()¶
bool apply_profile(const Profile& profile, QString* error)
Replaces the simulation and the outputs with those described by a profile.
Stops a running simulation first (emitting stopped), then builds the source (delta, track or replay) with the profile's seed, the sentence schedule, and one channel per enabled output, in profile order. The transports are created closed; they open at start. The seed's clock is set to Profile::start_time, or to the current UTC time when that is empty; a timed track then follows its timestamps and a replay the time fields of its sentences. The count of emitted sentences is reset to zero; a recording is kept and takes the new profile name.
Every transport is built once, here. A Signal K WebSocket output gets a greeting function that builds the Signal K hello from the current state and wall clock each time a client connects. Transports that later fail to open are not a profile error: they are reported through output_error when the run starts.
Parameters
| Name | Type | Description |
|---|---|---|
profile |
const Profile& |
The profile to run; copied, so it need not outlive the call. |
error (out) |
QString* |
Receives the reason when the profile cannot be applied: a track or log file that cannot be read or parsed, or an enabled output of a type the runner cannot build. May be null. Untouched on success. |
Returns bool: True when the profile was applied. False when it could not be; the run is then stopped but the previous simulation, outputs and profile are kept.
Declared in src/io/include/nmeasim/io/simulation_runner.hpp:171 · defined in src/io/src/simulation_runner.cpp:186
start()¶
void start()
Opens every output and the recording, and starts ticking.
Does nothing before a profile has been applied or while running. Outputs that fail to open are reported through output_error, synchronously from this call, and skipped; the run proceeds with the rest. ViewSync counters restart at zero and every state message is due at the first tick. The simulation itself continues from where it was: starting again after stop does not rewind it.
Emits started.
Declared in src/io/include/nmeasim/io/simulation_runner.hpp:182 · defined in src/io/src/simulation_runner.cpp:245
pause()¶
void pause()
Stops advancing the simulated clock while keeping the outputs open.
Does nothing when not running or already paused. The timer keeps running but its ticks are ignored, so nothing is sent until resume or step. Emits paused_changed with true.
Declared in src/io/include/nmeasim/io/simulation_runner.hpp:188 · defined in src/io/src/simulation_runner.cpp:267
resume()¶
void resume()
Continues a paused run without catching up on the time spent paused.
Does nothing when not running or not paused. Emits paused_changed with false.
Declared in src/io/include/nmeasim/io/simulation_runner.hpp:192 · defined in src/io/src/simulation_runner.cpp:275
stop()¶
void stop()
Stops ticking and closes every output and the recording.
Safe to call in any state. Clears the paused flag, emitting paused_changed with false when the run was paused. The simulation keeps its state and the channels keep their counters. Emits stopped only when the run was going, after paused_changed.
Declared in src/io/include/nmeasim/io/simulation_runner.hpp:198 · defined in src/io/src/simulation_runner.cpp:284
step()¶
void step()
Takes the smallest step while paused: one recorded sentence during a replay, one tick of Profile::tick_ms otherwise.
Does nothing before a profile has been applied. Starts the run paused when it is not running (emitting started and paused_changed) and pauses it when it is running (emitting paused_changed unless already paused). Then emits what the step produced through the outputs and sentence_emitted, emits ticked, and emits finished and stopped when the step reached the end of a finite source.
Declared in src/io/include/nmeasim/io/simulation_runner.hpp:208 · defined in src/io/src/simulation_runner.cpp:303
seek()¶
void seek(std::chrono::milliseconds position)
Moves a finite source to a position; the state changes at once.
Endless sources (the delta simulation) keep their position, but in either case every NMEA 0183 sentence and every Signal K and ViewSync message becomes due again at the next tick, so that receivers see the new position at once. Nothing is sent by the seek itself. Works whether running, paused or stopped. The wall-clock reference restarts, so the time since the previous tick is not handed to the simulation. Does nothing before a profile has been applied. Emits ticked.
Parameters
| Name | Type | Description |
|---|---|---|
position |
std::chrono::milliseconds |
Position within the source, clamped by the source to [0, duration()]. |
Declared in src/io/include/nmeasim/io/simulation_runner.hpp:221 · defined in src/io/src/simulation_runner.cpp:318
duration()¶
std::optional<std::chrono::milliseconds> duration() const
Returns the length of a finite source.
Returns std::optional<std::chrono::milliseconds>: The duration of the track or log in simulated time; std::nullopt for the delta simulation and before a profile has been applied.
Declared in src/io/include/nmeasim/io/simulation_runner.hpp:226 · defined in src/io/src/simulation_runner.cpp:332
position()¶
std::chrono::milliseconds position() const
Returns the elapsed position within a finite source.
Returns std::chrono::milliseconds: The position in [0, duration()], restarting from zero when a looping source wraps; zero for the delta simulation and before a profile has been applied.
Declared in src/io/include/nmeasim/io/simulation_runner.hpp:231 · defined in src/io/src/simulation_runner.cpp:336
set_recording()¶
bool set_recording(const QString& path)
Records every emitted sentence to a log file, in addition to the profile outputs.
The recording uses the log format of ADR 0012 and holds the plain sentences, before any filter and without TAG block; Signal K and ViewSync messages are not recorded. The file is truncated when the recording first opens and continued across stop and start until the recording is cleared or replaced. While running the file opens at once, and the previous recording, if any, is closed and replaced only once it has; otherwise the recording is set at once and the file opens at the next start, where a failure is reported through output_error and leaves the recording set.
Emits recording_changed with path when the recording was set or cleared. When the file cannot be opened at once, emits output_error synchronously instead and changes nothing.
Parameters
| Name | Type | Description |
|---|---|---|
path |
const QString& |
Log file to record to; an empty path stops recording. |
Returns bool: False when the file was opened at once and that failed; the previous recording, or none, then stays. True otherwise.
See also
- docs/reference/log-format.md
Declared in src/io/include/nmeasim/io/simulation_runner.hpp:251 · defined in src/io/src/simulation_runner.cpp:340
recording_path()¶
QString recording_path() const
Returns the path of the current recording.
Returns QString: The path given to set_recording; empty when not recording.
Declared in src/io/include/nmeasim/io/simulation_runner.hpp:255 · defined in src/io/src/simulation_runner.cpp:368
is_recording()¶
bool is_recording() const noexcept
Returns whether a recording is set, whether or not the run is going.
Returns bool: True from a successful set_recording call with a non-empty path until one with an empty path, also when the file failed to open at a later start.
Declared in src/io/include/nmeasim/io/simulation_runner.hpp:260
recorder()¶
const LogTransport* recorder() const noexcept
Returns the log transport of the recording, for its state and counters.
Returns const LogTransport*: The recording transport, owned by the runner and valid until the next set_recording call or the runner's destruction; null when not recording.
Declared in src/io/include/nmeasim/io/simulation_runner.hpp:265
is_running()¶
bool is_running() const noexcept
Returns whether the run is going.
Returns bool: True between start and stop, paused or not.
Declared in src/io/include/nmeasim/io/simulation_runner.hpp:270
is_paused()¶
bool is_paused() const noexcept
Returns whether a running simulation is paused.
Returns bool: True from pause or step until resume or stop; always false when not running.
Declared in src/io/include/nmeasim/io/simulation_runner.hpp:275
simulation()¶
core::simulation::Simulation* simulation() noexcept
Returns the current simulation, for reading the state and changing it between ticks.
Returns core::simulation::Simulation*: The simulation owned by the runner, valid until the next successful apply_profile or the runner's destruction; null before a profile has been applied.
Declared in src/io/include/nmeasim/io/simulation_runner.hpp:281
simulation()¶
const core::simulation::Simulation* simulation() const noexcept
Returns the current simulation, read-only.
Returns const core::simulation::Simulation*: The simulation owned by the runner, valid until the next successful apply_profile or the runner's destruction; null before a profile has been applied.
Declared in src/io/include/nmeasim/io/simulation_runner.hpp:286
outputs()¶
const std::vector<OutputChannel>& outputs() const noexcept
Returns the channels of the enabled outputs of the applied profile.
Returns const std::vector<OutputChannel>&: The channels in profile order, disabled outputs omitted; empty before a profile has been applied. The reference stays valid for the runner's lifetime; the elements are replaced by the next successful apply_profile.
Declared in src/io/include/nmeasim/io/simulation_runner.hpp:294
profile()¶
const Profile& profile() const noexcept
Returns the profile last applied successfully.
Returns const Profile&: The runner's copy, replaced by the next successful apply_profile; a default-constructed profile before the first one.
Declared in src/io/include/nmeasim/io/simulation_runner.hpp:299
sentences_emitted()¶
qint64 sentences_emitted() const noexcept
Returns the number of NMEA 0183 sentences produced since the profile was applied.
Returns qint64: Every sentence the simulation emitted, before filtering and whether or not an output was open; Signal K and ViewSync messages are counted by state_messages_sent. Kept across stop and start.
Declared in src/io/include/nmeasim/io/simulation_runner.hpp:305
state_messages_sent()¶
qint64 state_messages_sent() const noexcept
Returns the number of Signal K deltas and ViewSync packets sent since the profile was applied.
Returns qint64: The state messages sent, counted once per channel that sent one. Together with sentences_emitted, the number of sentence_emitted signals since the profile was applied. Kept across stop and start.
Declared in src/io/include/nmeasim/io/simulation_runner.hpp:312
Signals¶
started()¶
void started()
Emitted when the outputs have been opened and ticking began, from start or from step on a runner that was not running.
Declared in src/io/include/nmeasim/io/simulation_runner.hpp:317
paused_changed()¶
void paused_changed(bool paused)
Emitted when the run is paused or resumed, from pause, resume or step, and with false when stop ends a paused run.
Not emitted when the flag does not change.
Parameters
| Name | Type | Description |
|---|---|---|
paused |
bool |
True when the run was paused, false when it was resumed or stopped. |
Declared in src/io/include/nmeasim/io/simulation_runner.hpp:324
stopped()¶
void stopped()
Emitted when a running simulation stopped and its outputs were closed, from stop, apply_profile, the destructor, or after finished at the end of a finite source.
Declared in src/io/include/nmeasim/io/simulation_runner.hpp:327
ticked()¶
void ticked()
Emitted after every tick that advanced the simulation, every step and every seek.
Hosts refresh their view of simulation()->state() in response. Ticks that are ignored (while paused, or less than a millisecond after the previous one) do not emit it.
Declared in src/io/include/nmeasim/io/simulation_runner.hpp:332
sentence_emitted()¶
void sentence_emitted(const QString& id, const QString& text)
Emitted for every line produced, before filtering and whether or not an output is open, from a tick or from step.
NMEA 0183 sentences are reported once each. Signal K and ViewSync messages are reported once per channel that sent one.
Parameters
| Name | Type | Description |
|---|---|---|
id |
const QString& |
The registry or custom sentence id (for a replayed sentence, its formatter, such as RMC), or SIGNALK or VIEWSYNC for a state message. |
text |
const QString& |
The sentence or message without TAG block and line terminator. |
Declared in src/io/include/nmeasim/io/simulation_runner.hpp:342
output_error()¶
void output_error(const QString& description, const QString& message)
Emitted when an output or the recording reports an error through Transport::error_occurred.
Emitted synchronously from start or set_recording when a transport fails to open, and later from socket, device or write errors.
Parameters
| Name | Type | Description |
|---|---|---|
description |
const QString& |
The Transport::description of the transport, naming it. |
message |
const QString& |
The error message of the transport. |
Declared in src/io/include/nmeasim/io/simulation_runner.hpp:351
finished()¶
void finished()
Emitted when the track or log reached its end and does not loop, from a tick or from step; stopped follows immediately.
Declared in src/io/include/nmeasim/io/simulation_runner.hpp:354
recording_changed()¶
void recording_changed(const QString& path)
Emitted when set_recording sets or clears the recording; not when it fails to open the file at once.
Parameters
| Name | Type | Description |
|---|---|---|
path |
const QString& |
The new recording path, or empty when the recording was cleared. |
Declared in src/io/include/nmeasim/io/simulation_runner.hpp:359
Private member functions¶
tick()¶
void tick()
Advances the simulation by the wall-clock time since the previous tick and sends what it produced; connected to the timeout of tick_timer_.
Emits sentence_emitted, ticked, and finished and stopped at the end of a finite source. Returns without effect while paused or when less than a millisecond has passed.
Declared in src/io/include/nmeasim/io/simulation_runner.hpp:367 · defined in src/io/src/simulation_runner.cpp:449
emit_sentences()¶
void emit_sentences(const std::vector<core::simulation::EmittedSentence>& sentences)
Writes sentences to the admitting NMEA 0183 channels and to the recording.
The TAG block, where enabled, is put in front of the sentence by core::nmea0183::prepend_tag_block and carries the simulated UTC time of the current state as its c: parameter. Emits sentence_emitted for every sentence.
Parameters
| Name | Type | Description |
|---|---|---|
sentences |
const std::vector<core::simulation::EmittedSentence>& |
The sentences the simulation produced, in order, without line terminator. |
See also
- IEC 61162-450, TAG block parameter "c".
Declared in src/io/include/nmeasim/io/simulation_runner.hpp:377 · defined in src/io/src/simulation_runner.cpp:372
emit_state_messages()¶
void emit_state_messages()
Sends one message on every open Signal K and ViewSync channel that is due.
Signal K channels send a delta with the paths their filter admits; ViewSync channels send a packet with their counter. Emits sentence_emitted for every message.
See also
Declared in src/io/include/nmeasim/io/simulation_runner.hpp:384 · defined in src/io/src/simulation_runner.cpp:402
finish_if_done()¶
void finish_if_done()
Emits finished and stops the run (emitting stopped) when the source has reached its end.
Declared in src/io/include/nmeasim/io/simulation_runner.hpp:387 · defined in src/io/src/simulation_runner.cpp:437
restart_wall_clock()¶
void restart_wall_clock()
Restarts the wall-clock reference of the tick, so that the time before this call is never handed to the simulation.
Declared in src/io/include/nmeasim/io/simulation_runner.hpp:390 · defined in src/io/src/simulation_runner.cpp:444
make_transport()¶
std::unique_ptr<Transport> make_transport(const OutputConfig& config) const
Creates the transport for an output, closed.
The path of a file or log output is resolved with Profile::resolve_path of profile_, so a relative path names a file next to the profile file.
Parameters
| Name | Type | Description |
|---|---|---|
config |
const OutputConfig& |
The output to build the transport for. |
Returns std::unique_ptr<Transport>: A new transport without a Qt parent; null for an output type the runner does not know.
Declared in src/io/include/nmeasim/io/simulation_runner.hpp:399 · defined in src/io/src/simulation_runner.cpp:104
make_source()¶
std::unique_ptr<core::simulation::Source> make_source(
const Profile& profile,
QString* error) const
Creates the source of a profile's mode, seeded with the profile's start time.
Parameters
| Name | Type | Description |
|---|---|---|
profile |
const Profile& |
The profile whose mode, seed, track or replay settings to use; the track or log path is resolved with its Profile::resolve_path. |
error (out) |
QString* |
Receives the reason when a track or log cannot be loaded; may be null. |
Returns std::unique_ptr<core::simulation::Source>: The new source; null when the track or log cannot be loaded.
Declared in src/io/include/nmeasim/io/simulation_runner.hpp:407 · defined in src/io/src/simulation_runner.cpp:135
Private data members¶
profile_¶
Profile profile_
The profile last applied successfully.
Declared in src/io/include/nmeasim/io/simulation_runner.hpp:411
simulation_¶
std::unique_ptr<core::simulation::Simulation> simulation_
The simulation of profile_; null before the first successful apply_profile.
Declared in src/io/include/nmeasim/io/simulation_runner.hpp:413
outputs_¶
std::vector<OutputChannel> outputs_
One channel per enabled output of profile_, in profile order.
Declared in src/io/include/nmeasim/io/simulation_runner.hpp:415
recorder_¶
std::unique_ptr<LogTransport> recorder_
The recording, or null when not recording.
Declared in src/io/include/nmeasim/io/simulation_runner.hpp:417
tick_timer_¶
QTimer tick_timer_
Precise timer firing every Profile::tick_ms milliseconds while running; active from start to stop, paused or not.
Declared in src/io/include/nmeasim/io/simulation_runner.hpp:420
wall_clock_¶
QElapsedTimer wall_clock_
Wall-clock reference of the tick, restarted by start, resume and seek.
Declared in src/io/include/nmeasim/io/simulation_runner.hpp:422
wall_consumed_¶
std::chrono::nanoseconds wall_consumed_{0}
Wall-clock time since wall_clock_ started that has been handed to the simulation.
Declared in src/io/include/nmeasim/io/simulation_runner.hpp:424
paused_¶
bool paused_{false}
True while a running simulation is paused.
Declared in src/io/include/nmeasim/io/simulation_runner.hpp:426
sentences_emitted_¶
qint64 sentences_emitted_{0}
Sentences produced since the profile was applied, as sentences_emitted returns.
Declared in src/io/include/nmeasim/io/simulation_runner.hpp:428
state_messages_sent_¶
qint64 state_messages_sent_{0}
State messages sent since the profile was applied, as state_messages_sent returns.
Declared in src/io/include/nmeasim/io/simulation_runner.hpp:430