sim_lib_stream_host/
queue.rs1use std::sync::Arc;
4
5use sim_kernel::{Error, Result, Symbol};
6use sim_lib_stream_core::{
7 PushResult, StreamDirection, StreamInspectorSnapshot, StreamItem, StreamMedia, StreamPacket,
8 StreamStats, StreamValue, TransportProfile,
9};
10
11#[derive(Clone)]
17pub struct HostCallbackQueue {
18 media: StreamMedia,
19 direction: StreamDirection,
20 stream: Arc<StreamValue>,
21}
22
23impl HostCallbackQueue {
24 pub fn new(stream: Arc<StreamValue>) -> Self {
26 Self {
27 media: stream.metadata().media(),
28 direction: stream.metadata().direction(),
29 stream,
30 }
31 }
32
33 pub fn stream(&self) -> Arc<StreamValue> {
35 Arc::clone(&self.stream)
36 }
37
38 pub fn callback_packet(&self, packet: StreamPacket) -> Result<PushResult> {
40 self.ensure_callback_input()?;
41 self.ensure_media(&packet)?;
42 self.stream.push_packet(StreamItem::new(packet))
43 }
44
45 pub fn callback_item(&self, item: StreamItem) -> Result<PushResult> {
48 self.ensure_callback_input()?;
49 self.ensure_media(item.packet())?;
50 self.stream.push_packet(item)
51 }
52
53 pub fn drain(&self, limit: usize) -> Result<Vec<StreamItem>> {
55 self.stream.take_packets(limit)
56 }
57
58 pub fn close(&self) -> Result<()> {
60 self.stream.close_push()
61 }
62
63 pub fn cancel(&self) -> Result<()> {
65 self.stream.cancel()
66 }
67
68 pub fn stats(&self) -> Result<StreamStats> {
70 self.stream.stats()
71 }
72
73 pub fn inspector(
76 &self,
77 route: Symbol,
78 profile: &TransportProfile,
79 recent_diagnostics: Vec<Symbol>,
80 ) -> Result<StreamInspectorSnapshot> {
81 StreamInspectorSnapshot::from_stream_value(&self.stream, route, profile, recent_diagnostics)
82 }
83
84 fn ensure_media(&self, packet: &StreamPacket) -> Result<()> {
85 let packet_media = match packet {
86 StreamPacket::Pcm(_) => StreamMedia::Pcm,
87 StreamPacket::Midi(_) => StreamMedia::Midi,
88 StreamPacket::Diagnostic(_) => StreamMedia::Diagnostic,
89 StreamPacket::Data(_) => StreamMedia::Data,
90 };
91 if packet_media == self.media {
92 Ok(())
93 } else {
94 Err(Error::TypeMismatch {
95 expected: "host callback packet matching device media",
96 found: "host callback packet for another media",
97 })
98 }
99 }
100
101 fn ensure_callback_input(&self) -> Result<()> {
102 if self.direction == StreamDirection::Sink {
103 return Err(Error::Eval(
104 "host callbacks cannot push into a sink stream".to_owned(),
105 ));
106 }
107 Ok(())
108 }
109}