Fixed triggering mode change when acquiring
This commit is contained in:
1 parent
3d4085898e
commit
0d741c401b
10 files changed
+504
-106
No files matched your search
@@ -95,12 +95,45 @@ of the live ring into an immutable `EventSnapshot` and publishes it atomically.
|
||||
Pre-trigger history is what the ring already holds, so the percentage is a share of
|
||||
the event window and not of the buffer.
|
||||
|
||||
In trigger mode a trace is bound to the snapshot and to nothing else: the last
|
||||
event latched, or nothing at all before the first one. Never the live ring, not
|
||||
even while the post window is filling — a picture that changes only on an event is
|
||||
the whole point of trigger mode (SPECS: "data visualisation should not be refreshed
|
||||
till next event"), and binding the live ring mid-capture made the plot scroll for
|
||||
most of every event cycle.
|
||||
**A capture fills in view** (`DisplayMode::Capturing`). The moment an edge is accepted —
|
||||
which, by the gate below, means the pre-trigger history is already complete — the axis is
|
||||
pinned to the whole event window `[-pre, +post]` with the edge at x = 0, and the trace
|
||||
follows the live ring inside it until the snapshot lands. So the pre side is there
|
||||
immediately, the post side sweeps in from x = 0 to the right, and at the latch the
|
||||
snapshot replaces the live binding on an axis that does not move: the only visible change
|
||||
is that the picture stops.
|
||||
|
||||
This is a **deliberate deviation from the spec**, requested explicitly. SPECS:37 says the
|
||||
visualisation "should not be refreshed till next event", and an earlier iteration of this
|
||||
app read that strictly — a trace was bound to the snapshot and to nothing else, never the
|
||||
live ring, not even while the post window was filling. What that reading cost was the whole
|
||||
of every capture: for as long as the post side took to fill, the plot showed the *previous*
|
||||
event with no sign that anything was happening. The literal rule is gone; what it was
|
||||
protecting is not. A **held** event is still bound to the snapshot alone
|
||||
and is never quietly overwritten by live data, and the axis is still the event's own
|
||||
window throughout — a capture is live data on a frozen frame, not a live view.
|
||||
|
||||
The four display states are `Live` (no trigger), `Capturing`, `Held` (the frozen
|
||||
snapshot) and `Waiting` (armed, nothing captured yet: blank). `ScopeModel::display_mode()`
|
||||
answers which, and the frame tick reads it once and hands it to the bind, the display
|
||||
epoch, the axis pin and the status line — the producer can open or close a capture between
|
||||
any two reads, and the four disagreeing about which clock they are on is how a trace ends
|
||||
up drawn a window away from its axis.
|
||||
|
||||
**Disarm during a capture keeps what the capture got to.** It cuts the window at the
|
||||
newest sample, publishes that as the held event and freezes it — the axis tightens to the
|
||||
part that filled (`[-pre, +0.3 s]` for a 1 s post window disarmed 300 ms in) with the edge
|
||||
still at x = 0. It used to lose the capture outright: clearing the engine's pending flag
|
||||
dropped the display out of `Capturing` with nothing published behind it, so the view fell
|
||||
back to the *previous* event, or to blank if this was the first. No event fired, so the
|
||||
latch counter does not move; a separate `ScopeModel::event_seq()` counts published
|
||||
snapshots, and that is what the frame tick keys its framing on.
|
||||
|
||||
Mid-capture the live ring is read on the *event's* clock: `display_epoch()` is set to
|
||||
minus the edge, so `x = 0` is the edge for the live channels exactly as it is in a
|
||||
snapshot's own stamps. That re-basing machinery already existed (it was written for the
|
||||
frozen view and then never needed, since snapshots carry edge-relative stamps); this is
|
||||
what finally uses it.
|
||||
|
||||
**The whole trigger path measures the window in stream seconds, and never in
|
||||
samples.** `TriggerEngine` is fed each sample's timestamp and latches once that clock
|
||||
@@ -222,14 +255,15 @@ line always names the state it is in:
|
||||
|---|---|
|
||||
| `[live]` | trigger mode off: the view follows the stream continuously |
|
||||
| `[trigger: armed, waiting for an event]` | watching for an edge; the view shows the previous state |
|
||||
| `[trigger: CAPTURING (post-trigger window filling)]` | an edge was accepted; the post side is filling in view |
|
||||
| `[trigger: EVENT HELD …]` | an event was latched; the view is frozen on it |
|
||||
| `[trigger: disarmed (view frozen)]` | armed and waiting are not the same thing — nothing will arrive until it is armed again |
|
||||
|
||||
While an event is on screen a **red vertical line marks the trigger instant** on
|
||||
every row, at the edge's own stream time — the latch may complete a post-window
|
||||
later, but the line marks the edge, so the pre/post split can be read straight off
|
||||
the plot. It is not one of the user's cursors: it has its own colour, ignores the
|
||||
cursor show/hide toggle, and is parked (invisible) when no event is held.
|
||||
While an event is on screen — being captured or held — a **red vertical line marks the
|
||||
trigger instant** on every row, at x = 0. The latch completes a post-window later, but
|
||||
the line marks the edge, so the pre/post split can be read straight off the plot. It is
|
||||
not one of the user's cursors: it has its own colour, ignores the cursor show/hide
|
||||
toggle, and is parked (invisible) when there is no event.
|
||||
|
||||
**The status line.** It starts with an activity badge and then the mode, the
|
||||
connection, the measured rate, the packet/frame/gap counters, what plot 1 holds and
|
||||
@@ -253,7 +287,10 @@ the buffer's size and span. Three of those are worth calling out:
|
||||
then minutes, then hours. A frozen view looks the same whether the last event was a
|
||||
second or an hour ago, so without it there is no way to tell a working trigger from
|
||||
a dead one. Measured on the wall clock, not the stream's: it is a question about how
|
||||
long *you* have been waiting. Before the first latch it reads `no event yet`.
|
||||
long *you* have been waiting. The clock starts at the **edge**, not at the latch — that
|
||||
is the instant the user saw, and it is also when the capture appeared on screen — so a
|
||||
long capture reads as an event that is already ageing rather than one that has not
|
||||
happened. Before the first event it reads `no event yet`.
|
||||
|
||||
Switching the header bar's **trigger** button off returns to `[live]` and resumes
|
||||
drawing the stream; the trigger panel carries the same action as a
|
||||
@@ -403,6 +440,12 @@ answered: a live view keeps scrolling while the file chooser is up. The live cut
|
||||
through `ScopeModel::live_window_locked()`, the same index range `publish_event()`
|
||||
uses, so an export and a capture of the same window hold the same samples.
|
||||
|
||||
The export follows the display, not the trigger switch: it reads the snapshot only while
|
||||
one is **held**, and the live ring otherwise — including mid-capture, where the rows are
|
||||
on the live ring too. So exporting during a capture writes the partly filled window that
|
||||
is on screen (`time` from `-pre` up to wherever the post side has reached), not the
|
||||
previous event.
|
||||
|
||||
## Review findings not (yet) implemented
|
||||
|
||||
These are known deviations, found by a spec/code review, that are deliberate for
|
||||
@@ -429,6 +472,12 @@ now — they are listed so they are not mistaken for anything else:
|
||||
- **Pre-trigger % is a share of the *event* window**, not of the retained history —
|
||||
see the trigger section above for why (the spec's sentence predates the event
|
||||
window being a separate control).
|
||||
- **A capture is drawn as it fills**, against SPECS:37's "should not be refreshed till
|
||||
next event", which the app used to honour literally. Requested explicitly: a capture
|
||||
whose post window takes any appreciable time showed the previous event and no sign of
|
||||
progress. What the spec was protecting still holds — a *held* event is bound to its
|
||||
snapshot alone, and the axis is the event's own window from the edge onwards rather
|
||||
than a sliding live view.
|
||||
- **A plot holds at most four signals** (`RowSet::kSlotsPerRow`), because a `Plot`
|
||||
cannot give up a trace and the slots are therefore created up front.
|
||||
- **One toggle drives both cursor orientations.** The vertical markers and the
|
||||
|
||||
Reference in new issue
Block a user