1#![no_std]
8#![doc = include_str!("../README.md")]
9
10#[doc(hidden)]
11pub mod __private;
12mod future;
13mod sealed;
14mod types;
15
16pub use future::{ControlFlow, EventFnFuture};
17
18use core::fmt::{self, Debug};
19
20use higher_kinded_types::ForLifetime;
21use parking_lot::Mutex;
22
23use pin_list::{id::Unchecked, CursorMut};
24
25use types::{NodeTypes, PinList};
26
27#[macro_export]
28macro_rules! EventSource {
30 ($($ty: tt)*) => {
31 $crate::EventSource<$crate::__private::ForLt!($($ty)*)>
32 };
33}
34
35#[macro_export]
36macro_rules! emit {
38 ($source: expr, $event: expr) => {
39 $source.with_emitter(|mut emitter| while emitter.emit_next($event).is_some() {});
40 };
41}
42
43pub struct EventSource<T: ForLifetime> {
45 list: Mutex<PinList<T>>,
46}
47
48impl<T: ForLifetime> Debug for EventSource<T> {
49 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
50 f.debug_struct("EventSource")
51 .field("list", &self.list)
52 .finish()
53 }
54}
55
56impl<T: ForLifetime> EventSource<T> {
57 pub const fn new() -> Self {
59 Self {
60 list: Mutex::new(PinList::new(unsafe { Unchecked::new() })),
62 }
63 }
64
65 pub fn with_emitter(&self, emit_fn: impl FnOnce(EventEmitter<T>)) {
67 let mut list = self.list.lock();
68
69 emit_fn(EventEmitter {
70 cursor: list.cursor_front_mut(),
71 });
72 }
73
74 pub fn on<F>(&self, listener: F) -> EventFnFuture<F, T>
78 where
79 F: FnMut(T::Of<'_>, &mut ControlFlow) + Send,
80 {
81 EventFnFuture::new(self, listener)
82 }
83
84 pub async fn once<F, R>(&self, mut listener: F) -> Option<R>
88 where
89 F: FnMut(T::Of<'_>, &mut ControlFlow) -> Option<R> + Send,
90 R: Send,
91 {
92 let mut out = None;
93
94 self.on(|event, flow| {
95 if flow.done() {
96 return;
97 }
98
99 if let output @ Some(_) = listener(event, flow) {
100 out = output;
101 flow.set_done();
102 }
103 })
104 .await;
105
106 out
107 }
108}
109
110#[derive(Debug)]
112pub struct EventEmitter<'a, T: ForLifetime> {
113 cursor: CursorMut<'a, NodeTypes<T>>,
114}
115
116impl<T: ForLifetime> EventEmitter<'_, T> {
117 pub fn emit_next(&mut self, event: T::Of<'_>) -> Option<()> {
119 let node = self.cursor.protected_mut()?;
120
121 if unsafe { !node.poll(event) } {
123 return None;
124 }
125
126 self.cursor.move_next();
127
128 Some(())
129 }
130}