use crate::{ffi, PhidgetRef, Result, ReturnCode};
use phidget_sys::{PhidgetHandle, PhidgetManagerHandle};
use std::{ffi::c_void, ptr};
pub type ManagerAttachCallback = dyn Fn(&PhidgetRef) + Send + 'static;
pub type ManagerDetachCallback = dyn Fn(&PhidgetRef) + Send + 'static;
pub struct PhidgetManager {
mgr: PhidgetManagerHandle,
attach_cb: Option<*mut c_void>,
detach_cb: Option<*mut c_void>,
}
impl PhidgetManager {
pub fn new() -> Self {
let mut mgr: PhidgetManagerHandle = ptr::null_mut();
unsafe {
ffi::PhidgetManager_create(&mut mgr);
}
Self::from(mgr)
}
pub fn open(&mut self) -> Result<()> {
ReturnCode::result(unsafe { ffi::PhidgetManager_open(self.mgr) })
}
pub fn close(&mut self) -> Result<()> {
ReturnCode::result(unsafe { ffi::PhidgetManager_close(self.mgr) })
}
unsafe extern "C" fn on_attach_device(
_: PhidgetManagerHandle,
ctx: *mut c_void,
phid: PhidgetHandle,
) {
if !ctx.is_null() {
let cb: &mut Box<ManagerAttachCallback> = &mut *(ctx as *mut _);
let ph = PhidgetRef::from(phid);
cb(&ph);
}
}
unsafe extern "C" fn on_detach_device(
_: PhidgetManagerHandle,
ctx: *mut c_void,
phid: PhidgetHandle,
) {
if !ctx.is_null() {
let cb: &mut Box<ManagerDetachCallback> = &mut *(ctx as *mut _);
let ph = PhidgetRef::from(phid);
cb(&ph);
}
}
pub fn set_on_attach_handler<F>(&mut self, cb: F) -> Result<()>
where
F: Fn(&PhidgetRef) + Send + 'static,
{
let cb: Box<Box<ManagerAttachCallback>> = Box::new(Box::new(cb));
let ctx = Box::into_raw(cb) as *mut c_void;
ReturnCode::result(unsafe {
ffi::PhidgetManager_setOnAttachHandler(self.mgr, Some(Self::on_attach_device), ctx)
})?;
self.attach_cb = Some(ctx);
Ok(())
}
pub fn set_on_detach_handler<F>(&mut self, cb: F) -> Result<()>
where
F: Fn(&PhidgetRef) + Send + 'static,
{
let cb: Box<Box<ManagerDetachCallback>> = Box::new(Box::new(cb));
let ctx = Box::into_raw(cb) as *mut c_void;
ReturnCode::result(unsafe {
ffi::PhidgetManager_setOnDetachHandler(self.mgr, Some(Self::on_detach_device), ctx)
})?;
self.detach_cb = Some(ctx);
Ok(())
}
}
impl Default for PhidgetManager {
fn default() -> Self {
Self::new()
}
}
impl From<PhidgetManagerHandle> for PhidgetManager {
fn from(mgr: PhidgetManagerHandle) -> Self {
PhidgetManager {
mgr,
attach_cb: None,
detach_cb: None,
}
}
}
impl Drop for PhidgetManager {
fn drop(&mut self) {
let _ = unsafe { ffi::PhidgetManager_close(self.mgr) };
}
}