use crate::error::Result;
use mdflib_sys as ffi;
use std::marker::PhantomData;
#[derive(Debug, Clone, Copy)]
pub struct ChannelObserverRef<'a> {
pub(crate) inner: *const ffi::IChannelObserver,
_marker: PhantomData<&'a ()>,
}
impl std::fmt::Display for ChannelObserverRef<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"ChannelObserver {{ nof_samples: {} }}",
self.get_nof_samples()
)
}
}
impl<'a> ChannelObserverRef<'a> {
#[allow(dead_code)]
pub(crate) fn new(inner: *const ffi::IChannelObserver) -> Self {
Self {
inner,
_marker: PhantomData,
}
}
pub fn get_nof_samples(&self) -> usize {
unsafe { ffi::ChannelObserverGetNofSamples(self.inner) }
}
pub fn get_channel_value(&self, sample: usize) -> Option<f64> {
let mut value = 0.0;
let valid = unsafe { ffi::ChannelObserverGetChannelValue(self.inner, sample, &mut value) };
if valid {
Some(value)
} else {
None
}
}
pub fn get_eng_value(&self, sample: usize) -> Option<f64> {
let mut value = 0.0;
let valid = unsafe { ffi::ChannelObserverGetEngValue(self.inner, sample, &mut value) };
if valid {
Some(value)
} else {
None
}
}
pub fn is_valid(&self, sample: usize) -> bool {
unsafe { ffi::ChannelObserverGetValid(self.inner, sample) }
}
pub fn get_all_channel_values(&self) -> Vec<Option<f64>> {
let nof_samples = self.get_nof_samples();
let mut values = Vec::with_capacity(nof_samples);
for sample in 0..nof_samples {
values.push(self.get_channel_value(sample));
}
values
}
pub fn get_all_eng_values(&self) -> Vec<Option<f64>> {
let nof_samples = self.get_nof_samples();
let mut values = Vec::with_capacity(nof_samples);
for sample in 0..nof_samples {
values.push(self.get_eng_value(sample));
}
values
}
}
#[derive(Debug)]
pub struct ChannelObserver<'a> {
pub(crate) inner: *mut ffi::IChannelObserver,
_marker: PhantomData<&'a ()>,
}
impl<'a> ChannelObserver<'a> {
#[allow(dead_code)]
pub(crate) fn new(inner: *mut ffi::IChannelObserver) -> Self {
Self {
inner,
_marker: PhantomData,
}
}
}
impl<'a> std::ops::Deref for ChannelObserver<'a> {
type Target = ChannelObserverRef<'a>;
fn deref(&self) -> &Self::Target {
unsafe { &*(self as *const ChannelObserver as *const ChannelObserverRef) }
}
}
impl<'a> Drop for ChannelObserver<'a> {
fn drop(&mut self) {
if !self.inner.is_null() {
unsafe {
ffi::ChannelObserverUnInit(self.inner);
}
}
}
}
unsafe impl<'a> Send for ChannelObserver<'a> {}
unsafe impl<'a> Sync for ChannelObserver<'a> {}
pub unsafe fn create_channel_observer<'a>(
data_group: *const ffi::IDataGroup,
channel_group: *const ffi::IChannelGroup,
channel: *const ffi::IChannel,
) -> Result<ChannelObserver<'a>> {
let observer = unsafe { ffi::CreateChannelObserver(data_group, channel_group, channel) };
if observer.is_null() {
return Err(crate::error::MdfError::NullPointer);
}
Ok(ChannelObserver::new(observer))
}