A stream that answered CONNECT but has sent no CONFIG has no signal list, so nothing can be enabled and no DATA frame is owed. Calling that "connected, but no data is arriving: another reader may hold the source" blamed a second reader that does not exist, and the badge blinked green over it -- a working pipeline is exactly what it did not have. The glance word is `connecting` (ten characters, no wider than `event held`, so the fixed-set layout rule still holds) and the badge takes a fourth, steady yellow phase, both from the first frame rather than after the three-second stall test. The stall notice itself now splits on `have_config`: the unicast contention wording where a signal list exists, "trying to connect" where it does not, with `[udpscope] connecting:` on stderr beside the old `starved:`.
80 lines
3.3 KiB
C++
80 lines
3.3 KiB
C++
// SPDX-License-Identifier: MIT
|
|
#pragma once
|
|
|
|
#include <cstddef>
|
|
#include <cstdint>
|
|
#include <string>
|
|
|
|
namespace udpscope {
|
|
|
|
/// Everything either tier of the status bar shows, gathered once per frame by the tick so the
|
|
/// two cannot disagree. No GTK here on purpose: this is the one part of the status bar that
|
|
/// can be reasoned about as text.
|
|
struct StatusSnapshot {
|
|
/// One word from the fixed set: "connecting", "live", "paused", "armed", "capturing",
|
|
/// "event held", "disarmed". It is a word from a *fixed* set because the bar sits directly
|
|
/// above the plot and a field whose width tracked the stream would relayout it every frame --
|
|
/// so a word added here must be no wider than the widest already in it ("connecting" and
|
|
/// "event held" are both ten characters). "connecting" is the state before a CONFIG has
|
|
/// arrived, in which there is no signal list and so nothing any other word here can describe.
|
|
const char* state_word = "live";
|
|
/// The long prose the old single-line bar carried, kept for the detail string and the dump.
|
|
std::string state_detail;
|
|
|
|
bool connected = false;
|
|
bool have_config = false;
|
|
bool trigger_on = false;
|
|
|
|
/// Already collapsed to one figure or a range by the caller, without the "rate " prefix.
|
|
std::string rate_text;
|
|
double stored_rate_hz = 0.0;
|
|
double declared_rate_hz = 0.0;
|
|
|
|
/// Pre-formatted by ui.cpp's format_window(), which the window control and the Fit notices
|
|
/// also use, so it stays there rather than moving here.
|
|
std::string window_text;
|
|
|
|
std::uint64_t packets = 0;
|
|
std::uint64_t frames = 0;
|
|
std::uint64_t gaps = 0;
|
|
std::size_t signals = 0;
|
|
std::size_t channels = 0;
|
|
int plot1_traces = 0;
|
|
std::size_t plot1_samples = 0;
|
|
double buffer_mb = 0.0;
|
|
double span_s = 0.0;
|
|
std::uint64_t time_stride = 1;
|
|
bool have_event = false;
|
|
double since_event_s = 0.0;
|
|
int reconnects = 0;
|
|
|
|
/// How long the view has been frozen, in **wall** seconds, and whether it is. The producer
|
|
/// never stops while paused -- it keeps filling the live ring, which is what makes the resume
|
|
/// seamless -- so the stream's own clock says nothing about how long the user has been looking
|
|
/// at a still picture. Written through `format_elapsed()` like the event age, for the same
|
|
/// reason: it steps to a coarser unit instead of growing digits, and the bar is directly above
|
|
/// the plot.
|
|
bool paused = false;
|
|
double paused_for_s = 0.0;
|
|
};
|
|
|
|
/// The bar: "live · 10 kS/s · 2 s window", plus " · event 4.2 s ago" in trigger mode, " · for
|
|
/// 12 s" while paused, and nothing else ever. The badge glyph is a separate widget and is not
|
|
/// part of this string.
|
|
std::string format_glance(const StatusSnapshot& s);
|
|
|
|
/// The popover's prose and the exit dump's line, field for field as the old single-line bar
|
|
/// wrote it. CLAUDE.md asserts those fields are read out of the dump, so the field names and
|
|
/// their order must not change without updating it.
|
|
std::string format_detail(const StatusSnapshot& s);
|
|
|
|
/// A sample rate as "10 kS/s" — `%.3g`, so a trailing zero is dropped and the field's width
|
|
/// cannot track the stream. Moved here from ui.cpp, which still calls it.
|
|
std::string format_rate(double hz);
|
|
|
|
/// An elapsed time, stepping to a coarser unit rather than growing digits, so its width
|
|
/// cannot track the stream. Moved here from ui.cpp.
|
|
std::string format_elapsed(double seconds);
|
|
|
|
} // namespace udpscope
|