sensorviz-session (Rust)
A safe Rust interface to sensorViz's Qt-free core. Session wraps the
svz_* functions of tagcore_c
(sensorviz_c.h), which wrap
sensorviz::Session
(session.h): the code the Qt
sensorViz runs. So a Rust program -- the Rust sensorViz
(host/applications/sensorviz-rs), step 4 of
leaving Qt --
reads a log, runs the display transforms, builds the plot spec, and formats
the hover readout exactly as sensorViz does.
| What | Call |
|---|---|
| Open a log as File > Load does | open(path, Option<&Preferences>) |
| What the log is and holds | catalog() |
| The streams and every choice about them | view() |
| What to draw | spec(), then envelope(trace.stream, t0, t1, columns, break_gaps) per trace |
| The hover readout; a time as text | hover(t), format_time(t) |
| Transform parameters, for their controls | parameters(), set_parameter(id, value) |
| Changing the view | set_stream_visible, set_visible_streams, set_stream_range, reset_zoom, set_colors, set_axis_sides, set_title, set_title_visible, set_utc_offset, set_cursors_visible, set_break_at_gaps |
| The range dialog's starting range | range_for_dialog(id) |
| The compass panel's samples | compass_samples() |
| Per-tag preferences and their file | Preferences::load, save; Session::apply_preferences, remember_preferences, forget_preferences |
| The state dump, for checking | state_dump() |
Every setter returns the Changes it made -- streams, visibility, ranges,
appearance, title, UTC offset, cursors, gaps, parameters -- and nothing when
nothing changed, so a front end redraws only what it must.
Building
As for taglogwriter and
calibsession:
tagcore-c-sys links the library, so a program
may use all three.
cmake -DBUILD_TAGCORE_C=ON <build-dir>
cmake --build <build-dir> --target tagcore_c_static tagcore_c
export TAGCORE_C_LIB_DIR=<build-dir>/Release/lib
cargo test # macOS: libtagcore_c.a; Linux, Windows: shared
TAGCORE_C_LINK=dylib cargo test # the shared library on macOS too
The JSON
Descriptions cross the C interface as JSON, written by sensorviz_c.cc and
parsed into this crate's types, which name every field. Keys are camelCase;
numbers read back exactly (17 significant digits); a non-finite number is
null; colors are #rrggbb; time domains are epoch or elapsed; sides
left or right.
| Call | Top level | Holds |
|---|---|---|
svz_catalog_json |
object | path, tagType, profileName, preferenceKey, info (object), timeDomain, collectionStartEpochMs (or null), recordSets, eventMarkers (with times), compassCalibration (present, epoch, warning, hardIron, softIron row-major, accelOffset), compassSource, transformFailures |
svz_view_json |
object | streams (id, label, units, group, groupLabel, color, effectiveColor, derived, defaultVisible, axisSide, effectiveAxisSide, axisRange or null, timeDomain, stream handle, visible), visibleStreamIds, customRanges (id to lower, upper, explicit), title, titleVisible, utcOffsetHours, cursorsVisible, breakAtGaps, parameters (id to value) |
svz_spec_json |
object | timeDomain, utcOffsetHours, xDataRange (or null), traces (id, name, stream, color, penWidth, axis), axes (side, label, color, mode auto/linked/fixed, linkedGroup, traces, range or null), eventMarkerTimes, metadataRows, title, breakAtGaps |
svz_parameters_json |
array | id, title, prompt, units, kind (number/toggle), minimum, maximum, decimals, value |
svz_hover_json |
array | strings: the time, then label: value units per visible stream |
An auto axis takes its range from the data, padded, and widened to include
what it showed before; a renderer keeps that history itself, as the Qt one
does.
Checking
tests/session.rs, on the committed fixtures:
| Test | Checks |
|---|---|
imutag_describes_and_draws |
The catalog, view and spec parse; every trace's envelope arrives whole, within the time range; the hover readout |
compasstag_compass_and_parameters |
44 compass samples in time order; the compass parameters; declination remaking the heading only |
setters_report_changes |
Each setter's change bits, none on a repeat; the pressure range linking altitude; colors, sides and visibility landing in the view |
rust_setters_match_the_core_script |
A session driven through these setters reaches exactly the catalog, view and spec the core's own state-dump script reaches |
preferences_round_trip |
A file loaded, applied on open, changed, remembered, saved as the Qt app writes it, forgotten |
errors_are_reported |
A missing log and a refused preference file come back as errors, the open log kept |
Changing one step of the script-equivalence test (declination 12.4 for 12.5)
fails it. The core underneath is checked by sensorViz's own checks and by
session_cli against the Qt app (test README).
Maintaining
The declarations are tagcore_c_sys::svz
(svz.rs), written by hand from
sensorviz_c.h. When the header changes, change the declaration and the safe
method over it; when a signature, meaning or JSON schema changes
incompatibly, the header raises SVZ_ABI_VERSION and svz.rs must follow.
A field added to the JSON is ignored here until a type names it.