Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
46 lines
1.5 KiB
C++
46 lines
1.5 KiB
C++
// SPDX-License-Identifier: MIT
|
|
// SPDX-FileCopyrightText: 2026 Martino Ferrari
|
|
|
|
#pragma once
|
|
|
|
#include "model.hpp"
|
|
|
|
#include <cstdint>
|
|
|
|
namespace udpscope {
|
|
|
|
/// One signal's values in a frame. `values` points into the source's own buffer and is valid
|
|
/// only while the `on_data` call that received the frame is running.
|
|
struct SignalValues {
|
|
const double* values = nullptr;
|
|
std::uint32_t count = 0;
|
|
};
|
|
|
|
/// A data frame in source-neutral form; it mirrors `udps_frame_t`. A source with no packet
|
|
/// counter supplies a running one and `lost = 0`: the hole, backfill and time-base logic only
|
|
/// needs `counter`, `lost` and `late`.
|
|
struct Frame {
|
|
std::uint32_t counter = 0;
|
|
std::uint32_t lost = 0;
|
|
bool late = false;
|
|
double recv_time = 0.0;
|
|
std::uint8_t publish_mode = 0;
|
|
std::uint32_t num_samples = 0;
|
|
std::uint32_t num_signals = 0;
|
|
const SignalInfo* signals = nullptr;
|
|
const SignalValues* values = nullptr;
|
|
|
|
/// Element `elem` of signal `sig` at sample `sample`. Mirrors `udps_frame_value`: a scalar
|
|
/// signal carried once per sample is indexed by `sample`, a vector/matrix signal by `elem`.
|
|
/// Out of range reads 0.0.
|
|
double value(std::uint32_t sig, std::uint32_t sample, std::uint32_t elem) const noexcept {
|
|
if (sig >= num_signals) return 0.0;
|
|
const SignalValues& v = values[sig];
|
|
const std::uint32_t idx =
|
|
(v.count == num_samples && signals[sig].elements() == 1u) ? sample : elem;
|
|
return idx < v.count ? v.values[idx] : 0.0;
|
|
}
|
|
};
|
|
|
|
} // namespace udpscope
|