udpscope: an oscilloscope view for a UDPStreamer source
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.
This commit is contained in:
1 parent
8f54841c2c
commit
0e256764d5
41 files changed
+2081
-154
No files matched your search
@@ -0,0 +1,55 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// SPDX-FileCopyrightText: 2026 Martino Ferrari
|
||||
//
|
||||
// The preferences: what a user chose about this program rather than about a source, kept between runs
|
||||
// in one file. Deliberately free of GTK and of the app's own state -- it is a handful of values, a
|
||||
// file to read them from and a file to write them to -- so the dialog that edits them, the code that
|
||||
// applies them and the tests that read them all go through the same struct.
|
||||
|
||||
#ifndef UDPSCOPE_SETTINGS_HPP
|
||||
#define UDPSCOPE_SETTINGS_HPP
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace udpscope {
|
||||
|
||||
/// Everything the preferences dialog can change.
|
||||
///
|
||||
/// The defaults are the *stated* ones: an absent file and a fresh install behave identically, so a
|
||||
/// setting is only ever a user's decision and never an accident of what a file happened to contain.
|
||||
struct Settings {
|
||||
/// Where the event cache goes: the directory each source's folder is created in. Empty means the
|
||||
/// standard `<cache>/udpscope/events`, and a path is used as given -- one directory for every
|
||||
/// source, never one between them, because two sources writing one directory is two sources
|
||||
/// overwriting each other's events.
|
||||
std::string event_cache_dir;
|
||||
/// How many events one source's cache keeps. 0 disables trimming, which is a decision about the
|
||||
/// user's disk made deliberately rather than by default.
|
||||
int event_cache_max = 32;
|
||||
/// `--relative-time`'s setting, for a source whose wall-clock stamps jitter. A *startup* setting: the
|
||||
/// buffers are planned before any stream is known, so it takes effect on the next start (the
|
||||
/// preferences dialog says so, like the configurations dialog does).
|
||||
bool relative_time = false;
|
||||
/// "auto", "light" or "dark": what the interface should look like. Kept as the three names libadwaita
|
||||
/// uses, so the file says what the setting is rather than what an enum happens to be numbered.
|
||||
std::string theme = "auto";
|
||||
};
|
||||
|
||||
/// The defaults, as a value rather than as a comment: what the dialog's *Defaults* button writes and
|
||||
/// what a missing file yields.
|
||||
Settings default_settings();
|
||||
|
||||
/// The file the settings live in: `<config>/udpscope/settings.toml`. Never empty.
|
||||
std::string settings_path();
|
||||
|
||||
/// Reads the settings, filling anything the file does not mention from the defaults. A file that
|
||||
/// cannot be read is not an error: it is a first run.
|
||||
Settings load_settings();
|
||||
|
||||
/// Writes them. Returns false when the file cannot be written, which the dialog reports rather than
|
||||
/// swallowing -- a preference that silently does not stick is worse than one that says it did not.
|
||||
bool save_settings(const Settings& settings);
|
||||
|
||||
} // namespace udpscope
|
||||
|
||||
#endif // UDPSCOPE_SETTINGS_HPP
|
||||
Reference in new issue
Block a user