kui_trace/lib.rs
1//! kui's recording format (`docs/adr/0058-a-recording-is-a-timeline.md`):
2//! a timeline of what happened in a kui app, in frames and between them.
3//!
4//! One clock — µs since the recording began — and [`Record`]s placed on
5//! it: frames begun and finished with why they ran and who held them,
6//! presents, nested spans with their CPU time and the node they began
7//! under, inputs arriving, events handed to the app, wakes, frame
8//! requests, the driver's loop going to sleep and waking, counters,
9//! gauges, marks, the app's notes, and each component placed and how it
10//! was filled. Frames are intervals on the clock; what
11//! happens after one ends and before the next begins is the next one's
12//! gap.
13//!
14//! `kui-core` writes it (the devtools' Perf tab records it, and
15//! `KUI_PERF_TRACE=path` streams it to a file); this crate reads it with
16//! no kui at all:
17//!
18//! ```
19//! use kui_trace::{Record, Track, Trace, Span, Origin};
20//!
21//! let mut t = Trace::new();
22//! let (build, _) = t.names.get("build");
23//! t.records.push(Record::FrameBegin { t: 0, frame: 1, causes: vec![] });
24//! t.records.push(Record::Span(Span {
25//! track: Track::MAIN, id: 1, parent: 0, name: build, origin: Origin::Kui,
26//! start: 10, dur: 400, cpu: None, node: 0, cut: false,
27//! }));
28//! t.records.push(Record::FrameEnd { t: 500, frame: 1, unchanged: Some(false), nodes: 12 });
29//! let back = Trace::from_bytes(&t.to_bytes()).unwrap();
30//! let tl = back.timeline();
31//! assert_eq!(tl.frames[0].core_us(), 500);
32//! assert_eq!(back.name(tl.spans[0].name), "build");
33//! ```
34//!
35//! A recording still being written is read as it grows: a [`Stream`]
36//! decodes what its [`Transport`] hands over — a [`FileTransport`], with a
37//! [`Watch`] that says when the file moved — and keeps the record cut
38//! between reads for the next (ADR 0075, decision 5).
39//!
40//! [`analysis`] reads a timeline the way the Perf tab does — phases, an
41//! input's path to the screen, a frame's verdict, burns, spans grouped by
42//! name and origin — and [`adapters`] write it out for Chrome's trace
43//! viewer, Perfetto, speedscope and the Firefox Profiler.
44
45pub mod adapters;
46pub mod analysis;
47mod codec;
48pub mod diff;
49pub mod dump;
50mod file;
51#[cfg(feature = "lua")]
52pub mod lua;
53mod model;
54pub mod query;
55#[cfg(feature = "value")]
56pub mod query_value;
57mod record;
58mod stream;
59pub mod synth;
60
61pub use codec::{Encoder, Error, MAGIC, Reader, VERSION, Writer, header};
62pub use file::{FileTransport, Watch};
63pub use model::{
64 Event, Frame, Gauge, Holder, Input, Mark, Names, Placement, Present, Request, Timeline, Trace,
65};
66pub use record::{LoopEvent, NameId, Origin, Record, Session, Span, Track};
67pub use stream::{PollError, Polled, Stream, Transport};
68
69#[cfg(test)]
70mod tests;