use core::mem::MaybeUninit;
use core::ptr::NonNull;
use emcyphal_encoding::BufferType;
use crate::buffer::BufferToken;
use crate::buffer::rx_priority_fifo::RxPriorityFifoInner;
use crate::buffer::rx_req::{Buffer, SealedBuffer};
use crate::core::ServiceId;
use crate::frame::DataSpecifier;
use crate::registry;
use crate::time::Duration;
use crate::utils::TriplexArray;
pub use crate::buffer::rx_priority_fifo::{MAX_SESSION_COUNT, MAX_TRANSFER_COUNT};
pub struct PriorityFifo<T: BufferType, const SN: usize, const TN: usize> {
buffers: TriplexArray<T::Buffer, 1, SN, TN>,
inner: MaybeUninit<RxPriorityFifoInner<T, SN, TN>>,
entry: MaybeUninit<registry::rx_req::Entry>,
}
impl<T: BufferType + 'static, const SN: usize, const TN: usize> PriorityFifo<T, SN, TN> {
pub fn new() -> Self {
Self {
buffers: Default::default(),
inner: MaybeUninit::uninit(),
entry: MaybeUninit::uninit(),
}
}
}
impl<T: BufferType + 'static, const SN: usize, const TN: usize> Default
for PriorityFifo<T, SN, TN>
{
fn default() -> Self {
Self::new()
}
}
impl<T: BufferType + 'static, const SN: usize, const TN: usize> SealedBuffer<T>
for PriorityFifo<T, SN, TN>
{
unsafe fn init(
&mut self,
service: ServiceId,
timeout: Duration,
) -> (NonNull<registry::rx_req::Entry>, BufferToken<'_>) {
let buffers: &mut [T::Buffer] = &mut self.buffers;
let inner = &mut self.inner;
let entry = &mut self.entry;
let buffer_value = unsafe {
RxPriorityFifoInner::new(
DataSpecifier::Request(service),
timeout,
buffers.as_mut_ptr(),
buffers.len(),
)
};
let buffer_ptr = NonNull::from(inner.write(buffer_value));
let entry_value = unsafe { registry::rx_req::Entry::new(service, buffer_ptr) };
let entry_ptr = NonNull::from(entry.write(entry_value));
let buf_token = unsafe { BufferToken::create() };
(entry_ptr, buf_token)
}
}
impl<T: BufferType + 'static, const SN: usize, const TN: usize> Buffer<T>
for PriorityFifo<T, SN, TN>
{
}