use std::marker::PhantomData;
use crate::sys as ffi;
use crate::controls::ControlList;
use crate::error::{Error, Result};
use crate::frame_buffer::{FrameBuffer, FrameBufferRef};
use crate::stream::Stream;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum RequestStatus {
Pending,
Complete,
Cancelled,
}
pub struct Request {
pub(crate) ptr: *mut ffi::lc_request_t,
}
unsafe impl Send for Request {}
impl Request {
pub(crate) fn from_raw(ptr: *mut ffi::lc_request_t) -> Self {
Self { ptr }
}
pub fn reuse(&self) {
unsafe { ffi::lc_request_reuse(self.ptr) };
}
pub fn add_buffer(&self, stream: &Stream, buffer: &FrameBuffer) -> Result<()> {
let ret = unsafe { ffi::lc_request_add_buffer(self.ptr, stream.ptr, buffer.ptr) };
if ret != 0 {
return Err(Error::AddBufferFailed);
}
Ok(())
}
pub fn status(&self) -> RequestStatus {
let raw = unsafe { ffi::lc_request_status(self.ptr) };
match raw {
ffi::lc_request_status_t_LC_REQUEST_STATUS_PENDING => RequestStatus::Pending,
ffi::lc_request_status_t_LC_REQUEST_STATUS_COMPLETE => RequestStatus::Complete,
_ => RequestStatus::Cancelled,
}
}
pub fn cookie(&self) -> u64 {
unsafe { ffi::lc_request_cookie(self.ptr) }
}
pub fn sequence(&self) -> u32 {
unsafe { ffi::lc_request_sequence(self.ptr) }
}
pub fn controls(&self) -> ControlList {
let cl_ptr = unsafe { ffi::lc_request_controls(self.ptr) };
ControlList::from_raw(cl_ptr, false)
}
pub fn metadata(&self) -> ControlList {
let cl_ptr = unsafe { ffi::lc_request_metadata(self.ptr) };
ControlList::from_raw(cl_ptr, false)
}
pub fn find_buffer(&self, stream: &Stream) -> Option<FrameBuffer> {
let fb_ptr = unsafe { ffi::lc_request_find_buffer(self.ptr, stream.ptr) };
if fb_ptr.is_null() {
None
} else {
Some(FrameBuffer::from_raw(fb_ptr))
}
}
}
impl Drop for Request {
fn drop(&mut self) {
unsafe { ffi::lc_request_destroy(self.ptr) };
}
}
pub struct CompletedRequest<'a> {
ptr: *mut ffi::lc_request_t,
_phantom: PhantomData<&'a ()>,
}
impl<'a> CompletedRequest<'a> {
pub(crate) fn from_raw(ptr: *mut ffi::lc_request_t) -> Self {
Self {
ptr,
_phantom: PhantomData,
}
}
pub fn status(&self) -> RequestStatus {
let raw = unsafe { ffi::lc_request_status(self.ptr) };
match raw {
ffi::lc_request_status_t_LC_REQUEST_STATUS_PENDING => RequestStatus::Pending,
ffi::lc_request_status_t_LC_REQUEST_STATUS_COMPLETE => RequestStatus::Complete,
_ => RequestStatus::Cancelled,
}
}
pub fn cookie(&self) -> u64 {
unsafe { ffi::lc_request_cookie(self.ptr) }
}
pub fn sequence(&self) -> u32 {
unsafe { ffi::lc_request_sequence(self.ptr) }
}
pub fn metadata(&self) -> ControlList {
let cl_ptr = unsafe { ffi::lc_request_metadata(self.ptr) };
ControlList::from_raw(cl_ptr, false)
}
pub fn find_buffer(&self, stream: &Stream) -> Option<FrameBufferRef<'a>> {
let fb_ptr = unsafe { ffi::lc_request_find_buffer(self.ptr, stream.ptr) };
if fb_ptr.is_null() {
None
} else {
Some(FrameBufferRef {
ptr: fb_ptr,
_phantom: PhantomData,
})
}
}
}