use std::sync::Arc;
use sim_kernel::{
AbiVersion, Cx, Export, Lib, LibManifest, LibTarget, Linker, Result, Symbol, Version,
};
use sim_shape::{AnyShape, Shape, ShapeDoc, shape_value};
const STREAM_CORE_SHAPES_LIB_ID: &str = "stream-core-shapes";
pub struct StreamCoreShapesLib;
impl Lib for StreamCoreShapesLib {
fn manifest(&self) -> LibManifest {
LibManifest {
id: Symbol::new(STREAM_CORE_SHAPES_LIB_ID),
version: Version(env!("CARGO_PKG_VERSION").to_owned()),
abi: AbiVersion { major: 0, minor: 1 },
target: LibTarget::HostRegistered,
requires: Vec::new(),
capabilities: Vec::new(),
exports: shape_specs()
.into_iter()
.map(|(symbol, _, _)| Export::Shape {
symbol,
shape_id: None,
})
.collect(),
}
}
fn load(&self, _cx: &mut sim_kernel::LoadCx, linker: &mut Linker<'_>) -> Result<()> {
for (symbol, name, details) in shape_specs() {
linker.shape_value(
symbol.clone(),
shape_value(symbol, Arc::new(DocumentedShape::new(name, details))),
)?;
}
Ok(())
}
}
pub fn install_stream_core_shapes_lib(cx: &mut Cx) -> Result<()> {
if cx
.registry()
.lib(&Symbol::new(STREAM_CORE_SHAPES_LIB_ID))
.is_some()
{
return Ok(());
}
cx.load_lib(&StreamCoreShapesLib).map(|_| ())
}
fn shape_specs() -> Vec<(Symbol, &'static str, Vec<&'static str>)> {
vec![
(
stream_metadata_shape_symbol(),
"StreamMetadata",
vec![
"stream metadata read-construct surface",
"fields: id, media, direction, clock, buffer",
],
),
(
stream_envelope_shape_symbol(),
"StreamEnvelope",
vec![
"versioned stream packet envelope",
"fields: stream id, packet id, media, direction, sequence, ticks, primary clock domain, clock domains, profile, diagnostics, packet",
],
),
(
stream_media_shape_symbol(),
"StreamMedia",
vec![
"stream media symbol used by metadata",
"known media include pcm, midi, diagnostic, and data",
],
),
(
stream_clock_domain_shape_symbol(),
"ClockDomain",
vec![
"shared timing vocabulary for envelopes, stream descriptors, and placement",
"known domains include sample, block, control, midi-tick, wall, transport, server-frame, browser-frame, trace-step, and job",
],
),
(
stream_latency_class_shape_symbol(),
"LatencyClass",
vec![
"shared latency vocabulary for streams and placement",
"known classes include offline-render, block-local, interactive, sample-exact, buffered-preview, collab-bardelay, and remote-collaboration",
],
),
(
stream_capability_shape_symbol(),
"StreamCapability",
vec![
"stream transport capability flags",
"known flags include exact, deterministic, realtime, bounded, remote, replayable, preview, persistent, resumable, and lossy",
],
),
(
stream_backpressure_shape_symbol(),
"BackpressureOutcome",
vec![
"shared stream queue outcome vocabulary",
"known outcomes include accepted, dropped-newest, dropped-oldest, blocked, timed-out, rejected, and closed",
],
),
(
stream_clock_shape_symbol(),
"StreamClock",
vec![
"clock chart descriptor shared by frame and MIDI indexes",
"kernel stream events still carry KERNEL 6 Tick values",
],
),
(
stream_tempo_shape_symbol(),
"StreamTempo",
vec![
"tempo map descriptor for MIDI clock conversion",
"segments require a tick-zero anchor and increasing ticks",
],
),
(
stream_buffer_policy_shape_symbol(),
"StreamBufferPolicy",
vec![
"bounded stream buffer policy",
"capacity plus overflow behavior map",
],
),
(
stream_packet_shape_symbol(),
"StreamPacket",
vec![
"tagged packet map for PCM, MIDI, diagnostics, and data",
"codec round trips preserve packet tags and payload fields",
],
),
(
stream_data_packet_shape_symbol(),
"DataPacket",
vec![
"generic runtime data packet",
"fields: packet stream/packet/data, kind symbol, payload expr",
],
),
(
stream_diagnostic_shape_symbol(),
"StreamDiagnostic",
vec![
"diagnostic packet payload",
"kind symbol plus message string",
],
),
]
}
pub fn stream_metadata_shape_symbol() -> Symbol {
Symbol::qualified("stream", "Metadata")
}
pub fn stream_envelope_shape_symbol() -> Symbol {
Symbol::qualified("stream", "Envelope")
}
pub fn stream_media_shape_symbol() -> Symbol {
Symbol::qualified("stream", "Media")
}
pub fn stream_clock_domain_shape_symbol() -> Symbol {
Symbol::qualified("stream", "ClockDomain")
}
pub fn stream_latency_class_shape_symbol() -> Symbol {
Symbol::qualified("stream", "LatencyClass")
}
pub fn stream_capability_shape_symbol() -> Symbol {
Symbol::qualified("stream", "Capability")
}
pub fn stream_backpressure_shape_symbol() -> Symbol {
Symbol::qualified("stream", "BackpressureOutcome")
}
pub fn stream_clock_shape_symbol() -> Symbol {
Symbol::qualified("stream", "Clock")
}
pub fn stream_tempo_shape_symbol() -> Symbol {
Symbol::qualified("stream", "Tempo")
}
pub fn stream_buffer_policy_shape_symbol() -> Symbol {
Symbol::qualified("stream", "BufferPolicy")
}
pub fn stream_packet_shape_symbol() -> Symbol {
Symbol::qualified("stream", "Packet")
}
pub fn stream_data_packet_shape_symbol() -> Symbol {
Symbol::qualified("stream", "DataPacket")
}
pub fn stream_diagnostic_shape_symbol() -> Symbol {
Symbol::qualified("stream", "Diagnostic")
}
struct DocumentedShape {
name: &'static str,
details: Vec<&'static str>,
}
impl DocumentedShape {
fn new(name: &'static str, details: Vec<&'static str>) -> Self {
Self { name, details }
}
}
impl Shape for DocumentedShape {
fn is_total(&self) -> bool {
AnyShape.is_total()
}
fn check_value(
&self,
cx: &mut sim_kernel::Cx,
value: sim_kernel::Value,
) -> Result<sim_shape::ShapeMatch> {
AnyShape.check_value(cx, value)
}
fn check_expr(
&self,
cx: &mut sim_kernel::Cx,
expr: &sim_kernel::Expr,
) -> Result<sim_shape::ShapeMatch> {
AnyShape.check_expr(cx, expr)
}
fn describe(&self, _cx: &mut sim_kernel::Cx) -> Result<ShapeDoc> {
let mut doc = ShapeDoc::new(self.name);
for detail in &self.details {
doc = doc.with_detail(*detail);
}
Ok(doc)
}
}