Skip to main content

ndi_sdk/
routing.rs

1use std::ffi;
2use std::sync::{Arc, Mutex};
3
4use crate::Source;
5use crate::{
6    sys::{NDIlib_routing_create_t, NDIlib_routing_instance_type},
7    NDIError, NDIResult, HANDLE,
8};
9
10struct RouteInstanceInner(*mut NDIlib_routing_instance_type);
11unsafe impl Send for RouteInstanceInner {}
12
13impl Drop for RouteInstanceInner {
14    fn drop(&mut self) {
15        if let Some(destroy_fn) = unsafe { (*HANDLE.lib).routing_destroy } {
16            unsafe { destroy_fn(self.0) };
17        }
18    }
19}
20
21pub struct RouteInstance {
22    inner: Arc<Mutex<RouteInstanceInner>>,
23}
24
25impl RouteInstance {
26    pub fn create(name: &str, groups: &[&str]) -> NDIResult<Self> {
27        let ndi_name = ffi::CString::new(name).unwrap();
28        let groups = ffi::CString::new(groups.join(",")).unwrap();
29        let settings = NDIlib_routing_create_t {
30            p_ndi_name: ndi_name.as_ptr(),
31            p_groups: groups.as_ptr(),
32        };
33
34        let Some(create_fn) = (unsafe { (*HANDLE.lib).routing_create }) else {
35            return Err(NDIError::MissingSymbolV5("routing_create"));
36        };
37        let create_t = unsafe { create_fn(&settings).as_mut() };
38        let inner = RouteInstanceInner(
39            create_t.ok_or_else(|| NDIError::UnexpectedNullPointer("routing_create"))?,
40        );
41        Ok(Self {
42            inner: Arc::new(Mutex::new(inner)),
43        })
44    }
45
46    pub fn change(&self, source: &Source) -> NDIResult<()> {
47        let Some(change_fn) = (unsafe { (*HANDLE.lib).routing_change }) else {
48            return Err(NDIError::MissingSymbolV5("routing_change"));
49        };
50
51        let guard = self.inner.lock().expect("Expected Mutex to work");
52        let _undefined = source.with_raw(|src| unsafe { change_fn((*guard).0, src) });
53        Ok(())
54    }
55
56    pub fn clear(&self) -> NDIResult<()> {
57        let Some(clear_fn) = (unsafe { (*HANDLE.lib).routing_clear }) else {
58            return Err(NDIError::MissingSymbolV5("routing_clear"));
59        };
60
61        let guard = self.inner.lock().expect("Expected Mutex to work");
62        let _undefined = unsafe { clear_fn((*guard).0) };
63        Ok(())
64    }
65}
66
67#[cfg(test)]
68mod tests {
69    use super::*;
70
71    #[test]
72    fn test_create() -> NDIResult<()> {
73        let _ri = RouteInstance::create("Router Test 1", &vec!["Public"])?;
74        Ok(())
75    }
76}