1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
//! Defines the sensor context.

use crate::{
    common::*,
    device_hub::DeviceHub,
    device_list::DeviceList,
    error::{ErrorChecker, Result},
};

#[derive(Debug)]
pub struct Context {
    pub(crate) ptr: NonNull<sys::rs2_context>,
}

impl Context {
    /// Create an instance.
    pub fn new() -> Result<Self> {
        let ptr = {
            let mut checker = ErrorChecker::new();
            let context = unsafe {
                sys::rs2_create_context(sys::RS2_API_VERSION as i32, checker.inner_mut_ptr())
            };
            checker.check()?;
            context
        };

        let context = Self {
            ptr: NonNull::new(ptr).unwrap(),
        };

        Ok(context)
    }

    /// Create an [DeviceHub](DeviceHub) instance.
    pub fn create_device_hub(&self) -> Result<DeviceHub> {
        let ptr = unsafe {
            let mut checker = ErrorChecker::new();
            let ptr = sys::rs2_create_device_hub(self.ptr.as_ptr(), checker.inner_mut_ptr());
            checker.check()?;
            ptr
        };

        let hub = DeviceHub {
            ptr: NonNull::new(ptr).unwrap(),
        };
        Ok(hub)
    }

    /// Discover available devices.
    pub fn query_devices(&self, product_mask: Option<c_int>) -> Result<DeviceList> {
        let list = match product_mask {
            Some(mask) => unsafe {
                let mut checker = ErrorChecker::new();
                let list =
                    sys::rs2_query_devices_ex(self.ptr.as_ptr(), mask, checker.inner_mut_ptr());
                checker.check()?;
                DeviceList::from_raw(list)
            },
            None => unsafe {
                let mut checker = ErrorChecker::new();
                let list = sys::rs2_query_devices(self.ptr.as_ptr(), checker.inner_mut_ptr());
                checker.check()?;
                DeviceList::from_raw(list)
            },
        };

        Ok(list)
    }

    /// Add device file to context.
    pub fn add_device<P>(&mut self, file: P) -> Result<()>
    where
        P: AsRef<Path>,
    {
        let cstring = CString::new(file.as_ref().as_os_str().as_bytes()).unwrap();
        unsafe {
            let mut checker = ErrorChecker::new();
            sys::rs2_context_add_device(
                self.ptr.as_ptr(),
                cstring.as_ptr(),
                checker.inner_mut_ptr(),
            );
            checker.check()?;
        }
        Ok(())
    }

    // /// Remove device file from context. (unimplemented)
    // pub fn remove_device<P>(&mut self, file: P) -> Result<()>
    // where
    //     P: AsRef<Path>,
    // {
    //     todo!();
    // }

    pub fn into_raw(self) -> *mut sys::rs2_context {
        let ptr = self.ptr;
        mem::forget(self);
        ptr.as_ptr()
    }

    pub unsafe fn from_raw(ptr: *mut sys::rs2_context) -> Self {
        Self {
            ptr: NonNull::new(ptr).unwrap(),
        }
    }

    pub(crate) unsafe fn unsafe_clone(&self) -> Self {
        Self { ptr: self.ptr }
    }
}

impl Drop for Context {
    fn drop(&mut self) {
        unsafe { sys::rs2_delete_context(self.ptr.as_ptr()) }
    }
}

unsafe impl Send for Context {}