use std::{cell::Cell, marker::PhantomData};
use cxx::UniquePtr;
use mirtal_sys::ffi;
use crate::{Array, Device, Element, Error, Graph, Result, element};
pub struct Stream {
raw: UniquePtr<ffi::Stream>,
not_sync: PhantomData<Cell<()>>,
}
impl Stream {
pub(crate) fn new(device: Device) -> Result<Self> {
let raw = ffi::new_stream(device.native_kind(), device.native_index()?)?;
if raw.is_null() {
return Err(Error::NullHandle("stream"));
}
Ok(Self { raw, not_sync: PhantomData })
}
#[must_use]
pub fn id(&self) -> u64 {
self.raw.as_ref().map_or(0, ffi::stream_id)
}
#[must_use]
pub const fn graph(&self) -> Graph<'_> {
Graph::new(self)
}
pub fn eval(&self, array: &Array) -> Result<()> {
Ok(ffi::array_eval(array.native()?)?)
}
pub fn synchronize(&self) -> Result<()> {
Ok(ffi::synchronize(self.native()?)?)
}
pub fn read<T: Element>(&self, array: &Array) -> Result<Vec<T>> {
element::copy(array, self)
}
pub fn read_scalar_u32(&self, array: &Array) -> Result<u32> {
Ok(ffi::item_u32(array.native()?, self.native()?)?)
}
pub(crate) fn native(&self) -> Result<&ffi::Stream> {
self.raw.as_ref().ok_or(Error::NullHandle("stream"))
}
}
impl std::fmt::Debug for Stream {
fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
formatter.debug_struct("Stream").field("id", &self.id()).finish_non_exhaustive()
}
}