use std::{marker::PhantomData, sync::Arc};
use crate::{
barrier::Barrier,
builder::ProcessorSettings,
consumer::{
event_poller::EventPoller, MultiConsumerBarrier, MultiConsumerDependentsBarrier,
SingleConsumerBarrier,
},
event_handler::{EventHandler, EventHandlerWithState},
producer::single::{SingleProducer, SingleProducerBarrier},
sequence::DependentSequence,
sequence::GatedSequence,
wait_strategies::WaitStrategy,
};
use super::{Builder, Shared, MC, NC, SC};
type GateArray<const N: usize, W> = [GatedSequence<<W as WaitStrategy>::Notifier>; N];
type SPGateResult<S, E, W, B, const N: usize> = (SPBuilder<S, E, W, B>, GateArray<N, W>);
type SPPollerResult<S, E, W, B> = (
EventPoller<E, B, <W as WaitStrategy>::Notifier>,
SPBuilder<S, E, W, B>,
);
pub struct SPBuilder<State, E, W, B>
where
W: WaitStrategy,
{
state: PhantomData<State>,
shared: Shared<E, W>,
producer_barrier: Arc<SingleProducerBarrier>,
dependent_barrier: Arc<B>,
}
impl<E, W, B, S> ProcessorSettings<E, W> for SPBuilder<S, E, W, B>
where
W: WaitStrategy,
{
fn shared(&mut self) -> &mut Shared<E, W> {
&mut self.shared
}
}
impl<E, W, B, S> Builder<E, W, B> for SPBuilder<S, E, W, B>
where
E: 'static + Send + Sync,
W: 'static + WaitStrategy,
B: 'static + Barrier,
{
fn dependent_barrier(&self) -> Arc<B> {
Arc::clone(&self.dependent_barrier)
}
}
impl<E, W, B, S> SPBuilder<S, E, W, B>
where
E: 'static + Send + Sync,
W: 'static + WaitStrategy,
B: 'static + Barrier,
{
pub fn new_gates<const N: usize>(self) -> SPGateResult<S, E, W, B, N> {
let notifier = self.shared.notifier.clone();
let gating: [DependentSequence; N] = std::array::from_fn(|_| DependentSequence::new());
let gated_sequences: [GatedSequence<W::Notifier>; N] =
std::array::from_fn(|i| GatedSequence::new(gating[i].clone(), notifier.clone()));
(
SPBuilder {
state: PhantomData,
shared: self.shared,
producer_barrier: self.producer_barrier,
dependent_barrier: self.dependent_barrier,
},
gated_sequences,
)
}
}
impl<E, W, B> SPBuilder<NC, E, W, B>
where
E: 'static + Send + Sync,
W: 'static + WaitStrategy,
B: 'static + Barrier,
{
pub(super) fn new<F>(
size: usize,
event_factory: F,
wait_strategy: W,
producer_barrier: Arc<SingleProducerBarrier>,
dependent_barrier: Arc<B>,
) -> Self
where
F: FnMut() -> E,
{
let shared = Shared::new(size, event_factory, wait_strategy);
Self {
state: PhantomData,
shared,
producer_barrier,
dependent_barrier,
}
}
pub fn event_poller(mut self) -> SPPollerResult<SC, E, W, B> {
let event_poller = self.get_event_poller();
(
event_poller,
SPBuilder {
state: PhantomData,
shared: self.shared,
producer_barrier: self.producer_barrier,
dependent_barrier: self.dependent_barrier,
},
)
}
pub fn handle_events_with<EH>(mut self, event_handler: EH) -> SPBuilder<SC, E, W, B>
where
EH: 'static + EventHandler<E>,
{
self.add_event_handler(event_handler);
SPBuilder {
state: PhantomData,
shared: self.shared,
producer_barrier: self.producer_barrier,
dependent_barrier: self.dependent_barrier,
}
}
pub fn handle_events_and_state_with<EH, S, IS>(
mut self,
event_handler: EH,
initialize_state: IS,
) -> SPBuilder<SC, E, W, B>
where
EH: 'static + EventHandlerWithState<E, S>,
IS: 'static + Send + FnOnce() -> S,
{
self.add_event_handler_with_state(event_handler, initialize_state);
SPBuilder {
state: PhantomData,
shared: self.shared,
producer_barrier: self.producer_barrier,
dependent_barrier: self.dependent_barrier,
}
}
}
impl<E, W, B> SPBuilder<SC, E, W, B>
where
E: 'static + Send + Sync,
W: 'static + WaitStrategy,
B: 'static + Barrier,
{
pub fn build(mut self) -> SingleProducer<E, SingleConsumerBarrier, W> {
let mut consumer_cursors = self.shared().current_consumer_cursors.take().unwrap();
let consumer_barrier = SingleConsumerBarrier::new(consumer_cursors.remove(0));
SingleProducer::new(
self.shared.shutdown_at_sequence,
self.shared.ring_buffer,
self.producer_barrier,
self.shared.consumers,
consumer_barrier,
self.shared.notifier.clone(),
)
}
pub fn event_poller(mut self) -> SPPollerResult<MC, E, W, B> {
let event_poller = self.get_event_poller();
(
event_poller,
SPBuilder {
state: PhantomData,
shared: self.shared,
producer_barrier: self.producer_barrier,
dependent_barrier: self.dependent_barrier,
},
)
}
pub fn and_then(mut self) -> SPBuilder<NC, E, W, SingleConsumerBarrier> {
let consumer_cursors = self.shared().current_consumer_cursors.as_mut().unwrap();
let dependent_barrier = Arc::new(SingleConsumerBarrier::new(consumer_cursors.remove(0)));
SPBuilder {
state: PhantomData,
shared: self.shared,
producer_barrier: self.producer_barrier,
dependent_barrier,
}
}
pub fn and_then_with_dependents(
mut self,
gates: &[GatedSequence<W::Notifier>],
) -> SPBuilder<NC, E, W, MultiConsumerDependentsBarrier> {
let consumer_cursors = self
.shared()
.current_consumer_cursors
.replace(vec![])
.unwrap();
let gating: Vec<DependentSequence> = gates.iter().map(|gate| gate.dependent()).collect();
let dependent_barrier = Arc::new(MultiConsumerDependentsBarrier::new(
consumer_cursors,
gating,
));
SPBuilder {
state: PhantomData,
shared: self.shared,
producer_barrier: self.producer_barrier,
dependent_barrier,
}
}
pub fn handle_events_with<EH>(mut self, event_handler: EH) -> SPBuilder<MC, E, W, B>
where
EH: 'static + EventHandler<E>,
{
self.add_event_handler(event_handler);
SPBuilder {
state: PhantomData,
shared: self.shared,
producer_barrier: self.producer_barrier,
dependent_barrier: self.dependent_barrier,
}
}
pub fn handle_events_and_state_with<EH, S, IS>(
mut self,
event_handler: EH,
initalize_state: IS,
) -> SPBuilder<MC, E, W, B>
where
EH: 'static + EventHandlerWithState<E, S>,
IS: 'static + Send + FnOnce() -> S,
{
self.add_event_handler_with_state(event_handler, initalize_state);
SPBuilder {
state: PhantomData,
shared: self.shared,
producer_barrier: self.producer_barrier,
dependent_barrier: self.dependent_barrier,
}
}
}
impl<E, W, B> SPBuilder<MC, E, W, B>
where
E: 'static + Send + Sync,
W: 'static + WaitStrategy,
B: 'static + Barrier,
{
pub fn event_poller(mut self) -> SPPollerResult<MC, E, W, B> {
let event_poller = self.get_event_poller();
(
event_poller,
SPBuilder {
state: PhantomData,
shared: self.shared,
producer_barrier: self.producer_barrier,
dependent_barrier: self.dependent_barrier,
},
)
}
pub fn handle_events_with<EH>(mut self, event_handler: EH) -> SPBuilder<MC, E, W, B>
where
EH: 'static + EventHandler<E>,
{
self.add_event_handler(event_handler);
self
}
pub fn handle_events_and_state_with<EH, S, IS>(
mut self,
event_handler: EH,
initialize_state: IS,
) -> SPBuilder<MC, E, W, B>
where
EH: 'static + EventHandlerWithState<E, S>,
IS: 'static + Send + FnOnce() -> S,
{
self.add_event_handler_with_state(event_handler, initialize_state);
self
}
pub fn and_then(mut self) -> SPBuilder<NC, E, W, MultiConsumerBarrier> {
let consumer_cursors = self
.shared()
.current_consumer_cursors
.replace(vec![])
.unwrap();
let dependent_barrier = Arc::new(MultiConsumerBarrier::new(consumer_cursors));
SPBuilder {
dependent_barrier,
state: PhantomData,
shared: self.shared,
producer_barrier: self.producer_barrier,
}
}
pub fn and_then_with_dependents(
mut self,
gates: &[GatedSequence<W::Notifier>],
) -> SPBuilder<NC, E, W, MultiConsumerDependentsBarrier> {
let consumer_cursors = self
.shared()
.current_consumer_cursors
.replace(vec![])
.unwrap();
let gating: Vec<DependentSequence> = gates.iter().map(|gate| gate.dependent()).collect();
let dependent_barrier = Arc::new(MultiConsumerDependentsBarrier::new(
consumer_cursors,
gating,
));
SPBuilder {
dependent_barrier,
state: PhantomData,
shared: self.shared,
producer_barrier: self.producer_barrier,
}
}
pub fn build(mut self) -> SingleProducer<E, MultiConsumerBarrier, W> {
let consumer_cursors = self.shared().current_consumer_cursors.take().unwrap();
let consumer_barrier = MultiConsumerBarrier::new(consumer_cursors);
SingleProducer::new(
self.shared.shutdown_at_sequence,
self.shared.ring_buffer,
self.producer_barrier,
self.shared.consumers,
consumer_barrier,
self.shared.notifier.clone(),
)
}
}