1use sim_kernel::{Expr, Symbol};
4use sim_lib_scene::{data_map, node, sym};
5use sim_lib_stream_core::{StreamInspectorSnapshot, StreamItem, StreamPacket};
6use sim_value::build::uint;
7
8pub const STREAM_LIST_VIEW_ID: &str = "view:stream-list";
10pub const STREAM_DETAIL_VIEW_ID: &str = "view:stream-detail";
12pub const STREAM_PACKET_PREVIEW_VIEW_ID: &str = "view:stream-packet-preview";
14pub const STREAM_DIAGNOSTIC_TIMELINE_VIEW_ID: &str = "view:stream-diagnostic-timeline";
16
17pub fn stream_list_view(streams: &[StreamInspectorSnapshot]) -> Expr {
19 node(
20 "stack",
21 vec![
22 ("lens", sym(STREAM_LIST_VIEW_ID)),
23 ("role", sym("stream-list")),
24 ("dir", sym("column")),
25 (
26 "streams",
27 Expr::List(streams.iter().map(stream_row).collect()),
28 ),
29 ],
30 )
31}
32
33pub fn stream_detail_view(stream: &StreamInspectorSnapshot) -> Expr {
35 node(
36 "box",
37 vec![
38 ("lens", sym(STREAM_DETAIL_VIEW_ID)),
39 ("role", sym("stream-detail")),
40 ("id", Expr::Symbol(stream.stream_id.clone())),
41 ("route", Expr::Symbol(stream.route.clone())),
42 ("media", Expr::Symbol(stream.media.symbol())),
43 ("profile", Expr::Symbol(stream.profile.clone())),
44 ("clock", Expr::Symbol(stream.clock.clone())),
45 ("status", Expr::Symbol(stream.status.symbol())),
46 ("queue-depth", uint(stream.queue_depth as u64)),
47 ("dropped", uint(stream.dropped_count)),
48 (
49 "last-sequence",
50 stream.last_sequence.map(uint).unwrap_or(Expr::Nil),
51 ),
52 ],
53 )
54}
55
56pub fn stream_packet_preview_view(items: &[StreamItem]) -> Expr {
58 node(
59 "table",
60 vec![
61 ("lens", sym(STREAM_PACKET_PREVIEW_VIEW_ID)),
62 ("role", sym("stream-packet-preview")),
63 (
64 "packets",
65 Expr::List(
66 items
67 .iter()
68 .enumerate()
69 .map(|(index, item)| {
70 data_map(vec![
71 ("index", uint(index as u64)),
72 ("media", Expr::Symbol(item.packet().media().symbol())),
73 ("packet-kind", Expr::Symbol(packet_kind(item.packet()))),
74 ("ticks", uint(item.ticks().len() as u64)),
75 ])
76 })
77 .collect(),
78 ),
79 ),
80 ],
81 )
82}
83
84pub fn stream_diagnostic_timeline_view(stream: &StreamInspectorSnapshot) -> Expr {
86 node(
87 "timeline",
88 vec![
89 ("lens", sym(STREAM_DIAGNOSTIC_TIMELINE_VIEW_ID)),
90 ("role", sym("stream-diagnostic-timeline")),
91 ("stream", Expr::Symbol(stream.stream_id.clone())),
92 (
93 "diagnostics",
94 Expr::List(
95 stream
96 .recent_diagnostics
97 .iter()
98 .cloned()
99 .map(Expr::Symbol)
100 .collect(),
101 ),
102 ),
103 ],
104 )
105}
106
107fn stream_row(stream: &StreamInspectorSnapshot) -> Expr {
108 data_map(vec![
109 ("id", Expr::Symbol(stream.stream_id.clone())),
110 ("route", Expr::Symbol(stream.route.clone())),
111 ("media", Expr::Symbol(stream.media.symbol())),
112 ("profile", Expr::Symbol(stream.profile.clone())),
113 ("clock", Expr::Symbol(stream.clock.clone())),
114 ("status", Expr::Symbol(stream.status.symbol())),
115 ("queue-depth", uint(stream.queue_depth as u64)),
116 ("dropped", uint(stream.dropped_count)),
117 ])
118}
119
120fn packet_kind(packet: &StreamPacket) -> Symbol {
121 match packet {
122 StreamPacket::Pcm(_) => Symbol::qualified("stream/packet", "pcm"),
123 StreamPacket::Midi(_) => Symbol::qualified("stream/packet", "midi"),
124 StreamPacket::Diagnostic(diagnostic) => diagnostic.kind().clone(),
125 StreamPacket::Data(data) => data.kind.clone(),
126 }
127}