use crate::{Phidget, Result, ReturnCode};
use phidget_sys::{
self as ffi, PhidgetHandle, PhidgetHumiditySensorHandle as HumiditySensorHandle,
};
use std::{ffi::c_void, mem, ptr};
pub type AttachCallback = dyn Fn(&mut HumiditySensor) + Send + 'static;
pub type DetachCallback = dyn Fn(&mut HumiditySensor) + Send + 'static;
pub type HumidityChangeCallback = dyn Fn(&HumiditySensor, f64) + Send + 'static;
pub struct HumiditySensor {
chan: HumiditySensorHandle,
cb: Option<*mut c_void>,
attach_cb: Option<*mut c_void>,
detach_cb: Option<*mut c_void>,
}
impl HumiditySensor {
pub fn new() -> Self {
let mut chan: HumiditySensorHandle = ptr::null_mut();
unsafe {
ffi::PhidgetHumiditySensor_create(&mut chan);
}
Self::from(chan)
}
unsafe extern "C" fn on_attach(phid: PhidgetHandle, ctx: *mut c_void) {
if !ctx.is_null() {
let cb: &mut Box<AttachCallback> = &mut *(ctx as *mut _);
let mut sensor = Self::from(phid as HumiditySensorHandle);
cb(&mut sensor);
mem::forget(sensor);
}
}
unsafe extern "C" fn on_detach(phid: PhidgetHandle, ctx: *mut c_void) {
if !ctx.is_null() {
let cb: &mut Box<DetachCallback> = &mut *(ctx as *mut _);
let mut sensor = Self::from(phid as HumiditySensorHandle);
cb(&mut sensor);
mem::forget(sensor);
}
}
unsafe extern "C" fn on_humidity_change(
chan: HumiditySensorHandle,
ctx: *mut c_void,
humidity: f64,
) {
if !ctx.is_null() {
let cb: &mut Box<HumidityChangeCallback> = &mut *(ctx as *mut _);
let sensor = Self::from(chan);
cb(&sensor, humidity);
mem::forget(sensor);
}
}
pub fn as_channel(&self) -> &HumiditySensorHandle {
&self.chan
}
pub fn humidity(&self) -> Result<f64> {
let mut humidity = 0.0;
ReturnCode::result(unsafe {
ffi::PhidgetHumiditySensor_getHumidity(self.chan, &mut humidity)
})?;
Ok(humidity)
}
pub fn min_humidity(&self) -> Result<f64> {
let mut humidity = 0.0;
ReturnCode::result(unsafe {
ffi::PhidgetHumiditySensor_getMinHumidity(self.chan, &mut humidity)
})?;
Ok(humidity)
}
pub fn max_humidity(&self) -> Result<f64> {
let mut humidity = 0.0;
ReturnCode::result(unsafe {
ffi::PhidgetHumiditySensor_getMaxHumidity(self.chan, &mut humidity)
})?;
Ok(humidity)
}
pub fn humidity_change_trigger(&self) -> Result<f64> {
let mut humidity = 0.0;
ReturnCode::result(unsafe {
ffi::PhidgetHumiditySensor_getHumidityChangeTrigger(self.chan, &mut humidity)
})?;
Ok(humidity)
}
pub fn set_humidity_change_trigger(&self, trigger: f64) -> Result<()> {
ReturnCode::result(unsafe {
ffi::PhidgetHumiditySensor_setHumidityChangeTrigger(self.chan, trigger)
})?;
Ok(())
}
pub fn min_humidity_change_trigger(&self) -> Result<f64> {
let mut trigger = 0.0;
ReturnCode::result(unsafe {
ffi::PhidgetHumiditySensor_getMinHumidityChangeTrigger(self.chan, &mut trigger)
})?;
Ok(trigger)
}
pub fn max_humidity_change_trigger(&self) -> Result<f64> {
let mut trigger = 0.0;
ReturnCode::result(unsafe {
ffi::PhidgetHumiditySensor_getMaxHumidityChangeTrigger(self.chan, &mut trigger)
})?;
Ok(trigger)
}
pub fn set_on_humidity_change_handler<F>(&mut self, cb: F) -> Result<()>
where
F: Fn(&HumiditySensor, f64) + Send + 'static,
{
let cb: Box<Box<HumidityChangeCallback>> = Box::new(Box::new(cb));
let ctx = Box::into_raw(cb) as *mut c_void;
self.cb = Some(ctx);
ReturnCode::result(unsafe {
ffi::PhidgetHumiditySensor_setOnHumidityChangeHandler(
self.chan,
Some(Self::on_humidity_change),
ctx,
)
})
}
pub fn set_on_attach_handler<F>(&mut self, cb: F) -> Result<()>
where
F: Fn(&mut HumiditySensor) + Send + 'static,
{
let cb: Box<Box<AttachCallback>> = Box::new(Box::new(cb));
let ctx = Box::into_raw(cb) as *mut c_void;
ReturnCode::result(unsafe {
ffi::Phidget_setOnAttachHandler(self.as_mut_handle(), Some(Self::on_attach), ctx)
})?;
self.attach_cb = Some(ctx);
Ok(())
}
pub fn set_on_detach_handler<F>(&mut self, cb: F) -> Result<()>
where
F: Fn(&mut HumiditySensor) + Send + 'static,
{
let cb: Box<Box<DetachCallback>> = Box::new(Box::new(cb));
let ctx = Box::into_raw(cb) as *mut c_void;
ReturnCode::result(unsafe {
ffi::Phidget_setOnDetachHandler(self.as_mut_handle(), Some(Self::on_detach), ctx)
})?;
self.detach_cb = Some(ctx);
Ok(())
}
}
impl Phidget for HumiditySensor {
fn as_mut_handle(&mut self) -> PhidgetHandle {
self.chan as PhidgetHandle
}
fn as_handle(&self) -> PhidgetHandle {
self.chan as PhidgetHandle
}
}
unsafe impl Send for HumiditySensor {}
impl Default for HumiditySensor {
fn default() -> Self {
Self::new()
}
}
impl From<HumiditySensorHandle> for HumiditySensor {
fn from(chan: HumiditySensorHandle) -> Self {
Self {
chan,
cb: None,
attach_cb: None,
detach_cb: None,
}
}
}
impl Drop for HumiditySensor {
fn drop(&mut self) {
if let Ok(true) = self.is_open() {
let _ = self.close();
}
unsafe {
ffi::PhidgetHumiditySensor_delete(&mut self.chan);
crate::drop_cb::<HumidityChangeCallback>(self.cb.take());
crate::drop_cb::<AttachCallback>(self.attach_cb.take());
crate::drop_cb::<DetachCallback>(self.detach_cb.take());
}
}
}