GTK4 and libadwaita. It receives one UDP stream through the vendored udpsclient, buffers it in a large ring, and draws it with the vendored plotter: a trigger with a pre/post event window, a pause that freezes the window, cursors, measurements, math channels in a node editor, an event cache, named configurations, preferences, and an export of the visible window to .npy/.csv. Waveform files can be opened and analysed in place. The interface is two threads -- a producer that owns the socket and the GTK main thread that owns every widget and the GL context -- sharing one model under one mutex, with samples crossing through lock-free rings. deps/plotter is a submodule pinned to the commit this tree builds against; deps/udpsclient is vendored in place. docs/claude/ documents the rules that cost a defect to learn, and SPECS.md is the requirement document.
72 lines
3.3 KiB
C++
72 lines
3.3 KiB
C++
// SPDX-License-Identifier: MIT
|
|
// SPDX-FileCopyrightText: 2026 Martino Ferrari
|
|
|
|
#pragma once
|
|
|
|
#include <cstdint>
|
|
#include <string>
|
|
|
|
namespace udpscope {
|
|
|
|
/// Everything the command line can say. Defaults are the ones the spec names
|
|
/// (200 MB per buffer, 10 ms trigger hold-off) unless the user overrides them.
|
|
struct Config {
|
|
std::string server = "127.0.0.1"; ///< IPv4 dotted quad of the stream source.
|
|
std::uint16_t port = 8000; ///< UDP port (unicast) or TCP port (multicast).
|
|
std::string multicast; ///< Empty selects unicast.
|
|
std::string interface_addr; ///< Local IPv4 to join the group on; empty = default route.
|
|
|
|
/// Whether `--server` was given. Absent, the application asks which source to open rather
|
|
/// than silently taking the default above -- so this is "did the user choose", not "is
|
|
/// `server` valid". The default stays a usable value for every other path.
|
|
bool server_specified = false;
|
|
|
|
/// Size of *each* of the two sample buffers, in megabytes. The application
|
|
/// always allocates two identical buffers (spec item 1).
|
|
double buffer_mb = 200.0;
|
|
/// Whether `--buffer-mb` was given. A stored configuration's buffer size fills in only when the
|
|
/// flag was *absent*: an explicit flag beats a saved setting, and "not asked" is not the same
|
|
/// question as "asked for 200".
|
|
bool buffer_mb_specified = false;
|
|
|
|
/// Largest time window the toolbar offers, in seconds. The buffer partition is
|
|
/// sized to hold at least this much time (spec: decimation).
|
|
double max_window_s = 600.0;
|
|
|
|
double trigger_holdoff_s = 0.010;
|
|
int recv_buffer_bytes = 8 * 1024 * 1024;
|
|
|
|
/// Number of stacked plots (rows) to start with, 1..`RowSet::kMaxRows`. Only the
|
|
/// starting point: rows are added and removed from the layout editor.
|
|
int plots = 1;
|
|
|
|
/// Take the plot's time from the packet counter and the declared sample rate rather than
|
|
/// from the stream's own time signal, so arrival and producer-clock jitter cannot move a
|
|
/// sample's x. Absolute stream time is still recorded, for export only (`todo.md` item 2).
|
|
bool relative_time = false;
|
|
|
|
/// Whether relative time was *stated* rather than left at its default -- by `--relative-time`, or
|
|
/// by the preferences, which the source chooser can reach before this run is planned. A source's
|
|
/// stored configuration is a statement from an *older* session, so it only fills in the gap.
|
|
bool relative_time_specified = false;
|
|
|
|
/// `--capture-packets N`: the ring size of the raw-datagram capture, 1..100000.
|
|
/// 0 means the flag was absent: the capture is off, and the popover button then
|
|
/// uses the 1000-slot default when the user toggles it.
|
|
std::uint32_t capture_packets = 0;
|
|
|
|
/// `--open FILE`: a `.npy` an earlier run exported, opened for viewing and analysis instead of a
|
|
/// live source. File mode and source mode are exclusive -- there is no acquisition behind a file,
|
|
/// and the chooser's Waveforms page sets this rather than the connection fields.
|
|
std::string open_waveform;
|
|
};
|
|
|
|
/// Parses argv. On `--help` prints usage to stdout and exits(0); on a bad
|
|
/// argument prints a diagnostic to stderr and exits(2).
|
|
Config parse_args(int argc, char** argv);
|
|
|
|
/// Writes the usage text to `out`.
|
|
void print_usage(std::FILE* out, const char* argv0);
|
|
|
|
} // namespace udpscope
|