working on todo.md features
This commit is contained in:
1 parent
210d124814
commit
8f54841c2c
110 files changed
+15932
-6576
No files matched your search
@@ -0,0 +1,84 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// SPDX-FileCopyrightText: 2026 Martino Ferrari
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "model.hpp"
|
||||
|
||||
#include <cstdio>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace udpscope {
|
||||
|
||||
/// A `.npy` written by `write_npy()`: one packed structured array whose *dtype names the columns*
|
||||
/// (`time`, `abs_seconds`, then one field per signal). That is what makes an export readable again
|
||||
/// without a sidecar: the signal names are in the file.
|
||||
///
|
||||
/// Read one record at a time, not into a table: an export of a wide window on a fast stream is
|
||||
/// hundreds of megabytes, and the model's rings are the copy that matters -- a second full copy in
|
||||
/// a vector would double the peak for nothing.
|
||||
class WaveformReader {
|
||||
public:
|
||||
WaveformReader() = default;
|
||||
~WaveformReader();
|
||||
|
||||
WaveformReader(const WaveformReader&) = delete;
|
||||
WaveformReader& operator=(const WaveformReader&) = delete;
|
||||
|
||||
/// Parses the header and rewinds to the first record. On failure `error` says what the file is
|
||||
/// (not a NumPy file, not a udpscope export, truncated) and nothing else is usable.
|
||||
bool open(const std::string& path, std::string* error);
|
||||
void close() noexcept;
|
||||
|
||||
std::size_t rows() const noexcept { return rows_; }
|
||||
/// The *signal* columns, in file order: `time` and `abs_seconds` are the two time columns and are
|
||||
/// read through `next()`, not listed here.
|
||||
const std::vector<std::string>& names() const noexcept { return names_; }
|
||||
/// Seconds between the first two records: an export's `time` column is the ring's own stamps, which
|
||||
/// are uniform at the stored rate. 0 when there are fewer than two rows.
|
||||
double sample_dt() const noexcept { return sample_dt_; }
|
||||
|
||||
/// Reads the next record into `time`, `abs_seconds` and `values` (`names().size()` of them).
|
||||
/// False at the end of the file or on a short read.
|
||||
bool next(double* time, double* abs_seconds, float* values);
|
||||
|
||||
private:
|
||||
std::FILE* f_ = nullptr;
|
||||
std::size_t rows_ = 0;
|
||||
std::size_t rows_read_ = 0;
|
||||
std::size_t record_bytes_ = 0;
|
||||
double sample_dt_ = 0.0;
|
||||
std::vector<std::string> names_;
|
||||
/// Bytes per *field*, in file order: the two time columns then the signals. Kept so a column an
|
||||
/// external tool widened to `<f8` is read as one rather than mis-sliced by an assumed width.
|
||||
std::vector<std::size_t> field_bytes_;
|
||||
};
|
||||
|
||||
/// What a load put into the model, for the log and the status line.
|
||||
struct WaveformLoadReport {
|
||||
std::size_t signals = 0;
|
||||
std::size_t samples = 0;
|
||||
double span_s = 0.0;
|
||||
double rate_hz = 0.0;
|
||||
double first_time = 0.0;
|
||||
double last_time = 0.0;
|
||||
};
|
||||
|
||||
/// Loads a `.npy` export into `model` as if it had been streamed: one signal and channel per
|
||||
/// column, every sample pushed into the live ring, and the display epoch pinned to the file's last
|
||||
/// stamp so the axis reads `[-window, 0]` exactly as the export did.
|
||||
///
|
||||
/// Takes `model.mutex()` for the whole load. There is no acquisition behind this -- nothing arrives
|
||||
/// afterwards -- so the caller must not start one, and the UI must not expect frames.
|
||||
bool load_waveform_into_model(ScopeModel& model, const std::string& path,
|
||||
WaveformLoadReport* report, std::string* error);
|
||||
|
||||
/// The waveform files opened before, newest first: one path per line in
|
||||
/// `<config_dir>/waveforms.txt`. Written by `remember_waveform()`, which is called on every
|
||||
/// successful open -- including the one the command line asked for, so the list fills up from
|
||||
/// either entry point.
|
||||
std::vector<std::string> recent_waveforms();
|
||||
void remember_waveform(const std::string& path);
|
||||
|
||||
} // namespace udpscope
|
||||
Reference in new issue
Block a user