use std::{cell::RefCell, rc::Rc};
use crate::{Poll, Readiness, Token};
pub mod channel;
pub mod generic;
pub mod ping;
#[cfg(target_os = "linux")]
pub mod signals;
pub mod timer;
pub trait EventSource {
type Event;
type Metadata;
type Ret;
fn process_events<F>(
&mut self,
readiness: Readiness,
token: Token,
callback: F,
) -> std::io::Result<()>
where
F: FnMut(Self::Event, &mut Self::Metadata) -> Self::Ret;
fn register(&mut self, poll: &mut Poll, token: Token) -> std::io::Result<()>;
fn reregister(&mut self, poll: &mut Poll, token: Token) -> std::io::Result<()>;
fn unregister(&mut self, poll: &mut Poll) -> std::io::Result<()>;
}
pub(crate) struct Dispatcher<S, F> {
source: S,
callback: F,
}
impl<S, F> Dispatcher<S, F> {
pub fn new(source: S, callback: F) -> Self {
Dispatcher { source, callback }
}
}
impl<Data, S, F> EventDispatcher<Data> for RefCell<Dispatcher<S, F>>
where
S: EventSource + 'static,
F: FnMut(S::Event, &mut S::Metadata, &mut Data) -> S::Ret,
{
fn process_events(
&self,
readiness: Readiness,
token: Token,
data: &mut Data,
) -> std::io::Result<()> {
let mut disp = self.borrow_mut();
let Dispatcher {
ref mut source,
ref mut callback,
..
} = *disp;
source.process_events(readiness, token, |event, meta| callback(event, meta, data))
}
fn register(&self, poll: &mut Poll, token: Token) -> std::io::Result<()> {
self.borrow_mut().source.register(poll, token)
}
fn reregister(&self, poll: &mut Poll, token: Token) -> std::io::Result<()> {
self.borrow_mut().source.reregister(poll, token)
}
fn unregister(&self, poll: &mut Poll) -> std::io::Result<()> {
self.borrow_mut().source.unregister(poll)
}
fn as_source_any(&self) -> std::cell::RefMut<dyn std::any::Any> {
std::cell::RefMut::map(self.borrow_mut(), |disp| &mut disp.source)
}
fn into_source_any(self: Rc<Self>) -> Box<dyn std::any::Any> {
let me = Rc::try_unwrap(self).unwrap_or_else(|_| panic!("Unwrapping a shared source."));
Box::new(me.into_inner().source)
}
}
pub(crate) trait EventDispatcher<Data> {
fn process_events(
&self,
readiness: Readiness,
token: Token,
data: &mut Data,
) -> std::io::Result<()>;
fn register(&self, poll: &mut Poll, token: Token) -> std::io::Result<()>;
fn reregister(&self, poll: &mut Poll, token: Token) -> std::io::Result<()>;
fn unregister(&self, poll: &mut Poll) -> std::io::Result<()>;
fn as_source_any(&self) -> std::cell::RefMut<dyn std::any::Any>;
fn into_source_any(self: Rc<Self>) -> Box<dyn std::any::Any>;
}
pub struct Source<S: EventSource> {
pub(crate) token: Token,
pub(crate) _type: std::marker::PhantomData<*const S>,
}
pub struct Idle {
pub(crate) callback: Rc<RefCell<dyn CancellableIdle>>,
}
impl Idle {
pub fn cancel(self) {
self.callback.borrow_mut().cancel();
}
}
pub(crate) trait CancellableIdle {
fn cancel(&mut self);
}
impl<F> CancellableIdle for Option<F> {
fn cancel(&mut self) {
self.take();
}
}
pub(crate) trait IdleDispatcher<Data> {
fn dispatch(&mut self, data: &mut Data);
}
impl<Data, F> IdleDispatcher<Data> for Option<F>
where
F: FnMut(&mut Data),
{
fn dispatch(&mut self, data: &mut Data) {
if let Some(callabck) = self.as_mut() {
callabck(data);
}
}
}