use std::rc::Rc;
use std::cell::RefCell;
use std::sync::mpsc::Sender;
use crate::{Push, Pull};
pub struct Pusher<T, P: Push<T>> {
index: usize,
events: Rc<RefCell<Vec<usize>>>,
pusher: P,
phantom: ::std::marker::PhantomData<T>,
}
impl<T, P: Push<T>> Pusher<T, P> {
pub fn new(pusher: P, index: usize, events: Rc<RefCell<Vec<usize>>>) -> Self {
Pusher {
index,
events,
pusher,
phantom: ::std::marker::PhantomData,
}
}
}
impl<T, P: Push<T>> Push<T> for Pusher<T, P> {
#[inline]
fn push(&mut self, element: &mut Option<T>) {
self.events
.borrow_mut()
.push(self.index);
self.pusher.push(element)
}
}
pub struct ArcPusher<T, P: Push<T>> {
index: usize,
events: Sender<usize>,
pusher: P,
phantom: ::std::marker::PhantomData<T>,
buzzer: crate::buzzer::Buzzer,
}
impl<T, P: Push<T>> ArcPusher<T, P> {
pub fn new(pusher: P, index: usize, events: Sender<usize>, buzzer: crate::buzzer::Buzzer) -> Self {
ArcPusher {
index,
events,
pusher,
phantom: ::std::marker::PhantomData,
buzzer,
}
}
}
impl<T, P: Push<T>> Push<T> for ArcPusher<T, P> {
#[inline]
fn push(&mut self, element: &mut Option<T>) {
self.pusher.push(element);
let _ = self.events.send(self.index);
self.buzzer.buzz();
}
}
pub struct Puller<T, P: Pull<T>> {
index: usize,
count: usize,
events: Rc<RefCell<Vec<usize>>>,
puller: P,
phantom: ::std::marker::PhantomData<T>,
}
impl<T, P: Pull<T>> Puller<T, P> {
pub fn new(puller: P, index: usize, events: Rc<RefCell<Vec<usize>>>) -> Self {
Puller {
index,
count: 0,
events,
puller,
phantom: ::std::marker::PhantomData,
}
}
}
impl<T, P: Pull<T>> Pull<T> for Puller<T, P> {
#[inline]
fn pull(&mut self) -> &mut Option<T> {
let result = self.puller.pull();
if result.is_none() {
if self.count != 0 {
self.events
.borrow_mut()
.push(self.index);
self.count = 0;
}
}
else {
self.count += 1;
}
result
}
}