Skip to main content

sim_lib_stream_asio/
runtime.rs

1use sim_kernel::{Cx, Lib, LibManifest, Linker, LoadCx, Result, Symbol};
2use sim_lib_core::{SurfaceField, SurfacePackLib, SurfacePackSpec, SurfaceValueSpec, install_once};
3
4use crate::{asio_backend_symbol, asio_sdk_build_requirements, asio_transport_symbol};
5
6const ASIO_LIB_ID: &str = "stream-asio";
7
8/// Host-registered lib exporting the ASIO stream-host cards, built on the shared
9/// [`SurfacePackLib`] substrate.
10pub struct AsioLib;
11
12impl Lib for AsioLib {
13    fn manifest(&self) -> LibManifest {
14        asio_pack().manifest()
15    }
16
17    fn load(&self, cx: &mut LoadCx, linker: &mut Linker<'_>) -> Result<()> {
18        asio_pack().load(cx, linker)
19    }
20}
21
22/// Installs the [`AsioLib`] into `cx` exactly once, registering its ASIO
23/// stream-host surface cards.
24pub fn install_stream_asio_lib(cx: &mut Cx) -> Result<()> {
25    install_once(cx, &AsioLib)?;
26    Ok(())
27}
28
29fn asio_symbols() -> Vec<Symbol> {
30    vec![
31        Symbol::qualified("stream", "AsioBackend"),
32        Symbol::qualified("stream", "AsioSdkBuildRequirements"),
33        Symbol::qualified("stream", "AsioBufferSwitchBridge"),
34    ]
35}
36
37fn asio_value_spec(symbol: Symbol) -> SurfaceValueSpec {
38    let role = match symbol.name.as_ref() {
39        "AsioBackend" => "ASIO host audio backend card",
40        "AsioSdkBuildRequirements" => "ASIO optional SDK build requirements card",
41        "AsioBufferSwitchBridge" => "ASIO buffer switch graph bridge card",
42        _ => "ASIO card",
43    };
44    SurfaceValueSpec {
45        symbol: symbol.clone(),
46        fields: vec![
47            (Symbol::new("symbol"), SurfaceField::Symbol(symbol)),
48            (
49                Symbol::new("layer"),
50                SurfaceField::Str("stream-host".to_owned()),
51            ),
52            (Symbol::new("kind"), SurfaceField::Str("plugin".to_owned())),
53            (
54                Symbol::new("backend"),
55                SurfaceField::Symbol(asio_backend_symbol()),
56            ),
57            (
58                Symbol::new("transport"),
59                SurfaceField::Symbol(asio_transport_symbol()),
60            ),
61            (Symbol::new("role"), SurfaceField::Str(role.to_owned())),
62            (
63                Symbol::new("requirements"),
64                SurfaceField::Strs(
65                    asio_sdk_build_requirements()
66                        .into_iter()
67                        .map(|item| item.to_owned())
68                        .collect(),
69                ),
70            ),
71        ],
72    }
73}
74
75fn asio_pack() -> SurfacePackLib {
76    SurfacePackLib {
77        spec: SurfacePackSpec {
78            lib_id: Symbol::new(ASIO_LIB_ID),
79            values: asio_symbols().into_iter().map(asio_value_spec).collect(),
80        },
81    }
82}