1use std::sync::Arc;
16
17use sim_kernel::{
18 AbiVersion, Cx, Export, Lib, LibManifest, LibTarget, Linker, Result, Symbol, Version,
19};
20use sim_shape::{AnyShape, Shape, ShapeDoc, shape_value};
21
22const STREAM_CORE_SHAPES_LIB_ID: &str = "stream-core-shapes";
23
24pub struct StreamCoreShapesLib;
31
32impl Lib for StreamCoreShapesLib {
33 fn manifest(&self) -> LibManifest {
34 LibManifest {
35 id: Symbol::new(STREAM_CORE_SHAPES_LIB_ID),
36 version: Version(env!("CARGO_PKG_VERSION").to_owned()),
37 abi: AbiVersion { major: 0, minor: 1 },
38 target: LibTarget::HostRegistered,
39 requires: Vec::new(),
40 capabilities: Vec::new(),
41 exports: shape_specs()
42 .into_iter()
43 .map(|(symbol, _, _)| Export::Shape {
44 symbol,
45 shape_id: None,
46 })
47 .collect(),
48 }
49 }
50
51 fn load(&self, _cx: &mut sim_kernel::LoadCx, linker: &mut Linker<'_>) -> Result<()> {
52 for (symbol, name, details) in shape_specs() {
53 linker.shape_value(
54 symbol.clone(),
55 shape_value(symbol, Arc::new(DocumentedShape::new(name, details))),
56 )?;
57 }
58 Ok(())
59 }
60}
61
62pub fn install_stream_core_shapes_lib(cx: &mut Cx) -> Result<()> {
67 if cx
68 .registry()
69 .lib(&Symbol::new(STREAM_CORE_SHAPES_LIB_ID))
70 .is_some()
71 {
72 return Ok(());
73 }
74 cx.load_lib(&StreamCoreShapesLib).map(|_| ())
75}
76
77fn shape_specs() -> Vec<(Symbol, &'static str, Vec<&'static str>)> {
78 vec![
79 (
80 stream_metadata_shape_symbol(),
81 "StreamMetadata",
82 vec![
83 "stream metadata read-construct surface",
84 "fields: id, media, direction, clock, buffer",
85 ],
86 ),
87 (
88 stream_envelope_shape_symbol(),
89 "StreamEnvelope",
90 vec![
91 "versioned stream packet envelope",
92 "fields: stream id, packet id, media, direction, sequence, ticks, primary clock domain, clock domains, profile, diagnostics, packet",
93 ],
94 ),
95 (
96 stream_media_shape_symbol(),
97 "StreamMedia",
98 vec![
99 "stream media symbol used by metadata",
100 "known media include pcm, midi, diagnostic, and data",
101 ],
102 ),
103 (
104 stream_clock_domain_shape_symbol(),
105 "ClockDomain",
106 vec![
107 "shared timing vocabulary for envelopes, stream descriptors, and placement",
108 "known domains include sample, block, control, midi-tick, wall, transport, server-frame, browser-frame, trace-step, and job",
109 ],
110 ),
111 (
112 stream_latency_class_shape_symbol(),
113 "LatencyClass",
114 vec![
115 "shared latency vocabulary for streams and placement",
116 "known classes include offline-render, block-local, interactive, sample-exact, buffered-preview, collab-bardelay, and remote-collaboration",
117 ],
118 ),
119 (
120 stream_capability_shape_symbol(),
121 "StreamCapability",
122 vec![
123 "stream transport capability flags",
124 "known flags include exact, deterministic, realtime, bounded, remote, replayable, preview, persistent, resumable, and lossy",
125 ],
126 ),
127 (
128 stream_backpressure_shape_symbol(),
129 "BackpressureOutcome",
130 vec![
131 "shared stream queue outcome vocabulary",
132 "known outcomes include accepted, dropped-newest, dropped-oldest, blocked, timed-out, rejected, and closed",
133 ],
134 ),
135 (
136 stream_clock_shape_symbol(),
137 "StreamClock",
138 vec![
139 "clock chart descriptor shared by frame and MIDI indexes",
140 "kernel stream events still carry KERNEL 6 Tick values",
141 ],
142 ),
143 (
144 stream_tempo_shape_symbol(),
145 "StreamTempo",
146 vec![
147 "tempo map descriptor for MIDI clock conversion",
148 "segments require a tick-zero anchor and increasing ticks",
149 ],
150 ),
151 (
152 stream_buffer_policy_shape_symbol(),
153 "StreamBufferPolicy",
154 vec![
155 "bounded stream buffer policy",
156 "capacity plus overflow behavior map",
157 ],
158 ),
159 (
160 stream_packet_shape_symbol(),
161 "StreamPacket",
162 vec![
163 "tagged packet map for PCM, MIDI, diagnostics, and data",
164 "codec round trips preserve packet tags and payload fields",
165 ],
166 ),
167 (
168 stream_data_packet_shape_symbol(),
169 "DataPacket",
170 vec![
171 "generic runtime data packet",
172 "fields: packet stream/packet/data, kind symbol, payload expr",
173 ],
174 ),
175 (
176 stream_diagnostic_shape_symbol(),
177 "StreamDiagnostic",
178 vec![
179 "diagnostic packet payload",
180 "kind symbol plus message string",
181 ],
182 ),
183 ]
184}
185
186pub fn stream_metadata_shape_symbol() -> Symbol {
188 Symbol::qualified("stream", "Metadata")
189}
190
191pub fn stream_envelope_shape_symbol() -> Symbol {
193 Symbol::qualified("stream", "Envelope")
194}
195
196pub fn stream_media_shape_symbol() -> Symbol {
198 Symbol::qualified("stream", "Media")
199}
200
201pub fn stream_clock_domain_shape_symbol() -> Symbol {
203 Symbol::qualified("stream", "ClockDomain")
204}
205
206pub fn stream_latency_class_shape_symbol() -> Symbol {
208 Symbol::qualified("stream", "LatencyClass")
209}
210
211pub fn stream_capability_shape_symbol() -> Symbol {
213 Symbol::qualified("stream", "Capability")
214}
215
216pub fn stream_backpressure_shape_symbol() -> Symbol {
218 Symbol::qualified("stream", "BackpressureOutcome")
219}
220
221pub fn stream_clock_shape_symbol() -> Symbol {
223 Symbol::qualified("stream", "Clock")
224}
225
226pub fn stream_tempo_shape_symbol() -> Symbol {
228 Symbol::qualified("stream", "Tempo")
229}
230
231pub fn stream_buffer_policy_shape_symbol() -> Symbol {
233 Symbol::qualified("stream", "BufferPolicy")
234}
235
236pub fn stream_packet_shape_symbol() -> Symbol {
238 Symbol::qualified("stream", "Packet")
239}
240
241pub fn stream_data_packet_shape_symbol() -> Symbol {
243 Symbol::qualified("stream", "DataPacket")
244}
245
246pub fn stream_diagnostic_shape_symbol() -> Symbol {
248 Symbol::qualified("stream", "Diagnostic")
249}
250
251struct DocumentedShape {
252 name: &'static str,
253 details: Vec<&'static str>,
254}
255
256impl DocumentedShape {
257 fn new(name: &'static str, details: Vec<&'static str>) -> Self {
258 Self { name, details }
259 }
260}
261
262impl Shape for DocumentedShape {
263 fn is_total(&self) -> bool {
264 AnyShape.is_total()
265 }
266
267 fn check_value(
268 &self,
269 cx: &mut sim_kernel::Cx,
270 value: sim_kernel::Value,
271 ) -> Result<sim_shape::ShapeMatch> {
272 AnyShape.check_value(cx, value)
273 }
274
275 fn check_expr(
276 &self,
277 cx: &mut sim_kernel::Cx,
278 expr: &sim_kernel::Expr,
279 ) -> Result<sim_shape::ShapeMatch> {
280 AnyShape.check_expr(cx, expr)
281 }
282
283 fn describe(&self, _cx: &mut sim_kernel::Cx) -> Result<ShapeDoc> {
284 let mut doc = ShapeDoc::new(self.name);
285 for detail in &self.details {
286 doc = doc.with_detail(*detail);
287 }
288 Ok(doc)
289 }
290}