///|
/// A timestamped frame captured from a virtual bus.
pub struct TraceEntry {
timestamp_us : UInt64
frame : Frame
}
///|
/// An append-only trace that can be replayed deterministically.
pub struct Trace {
entries : Array[TraceEntry]
}
///|
/// Create an empty trace.
pub fn new_trace() -> Trace {
{ entries: [] }
}
///|
/// Append a timestamped frame.
pub fn Trace::record(
self : Trace,
timestamp_us : UInt64,
frame : Frame,
) -> Unit {
self.entries.push({ timestamp_us, frame })
}
///|
/// Return entries in capture order.
pub fn Trace::entries(self : Trace) -> Array[TraceEntry] {
self.entries.copy()
}
///|
/// Return the number of captured frames.
pub fn Trace::length(self : Trace) -> Int {
self.entries.length()
}
///|
/// The capture timestamp in microseconds.
pub fn TraceEntry::timestamp(self : TraceEntry) -> UInt64 {
self.timestamp_us
}
///|
/// The captured frame.
pub fn TraceEntry::frame(self : TraceEntry) -> Frame {
self.frame
}
///|
/// Replay frames to a virtual bus, preserving capture order.
pub fn Trace::replay(self : Trace, bus : VirtualBus) -> Int {
let mut delivered = 0
for entry in self.entries {
if bus.publish(entry.frame) {
delivered += 1
}
}
delivered
}