gwr_engine/events/
once.rs1use std::cell::RefCell;
6use std::pin::Pin;
7use std::rc::Rc;
8use std::task::{Context, Poll, Waker};
9
10use futures::Future;
11use futures::future::FusedFuture;
12
13use crate::sim_error;
14use crate::traits::{BoxFuture, Event};
15use crate::types::SimResult;
16
17pub struct OnceState<T>
18where
19 T: Copy,
20{
21 listen_waiting: RefCell<Vec<Waker>>,
22 triggered: RefCell<bool>,
23 result: T,
24}
25
26impl<T> OnceState<T>
27where
28 T: Copy,
29{
30 pub fn new(value: T) -> Self {
31 Self {
32 listen_waiting: RefCell::new(Vec::new()),
33 triggered: RefCell::new(false),
34 result: value,
35 }
36 }
37}
38
39impl Default for OnceState<()> {
40 fn default() -> Self {
41 Self::new(())
42 }
43}
44
45#[derive(Clone)]
46pub struct Once<T>
47where
48 T: Copy,
49{
50 state: Rc<OnceState<T>>,
51}
52
53pub struct OnceFuture<T>
54where
55 T: Copy,
56{
57 state: Rc<OnceState<T>>,
58 done: bool,
59}
60
61impl<T> FusedFuture for OnceFuture<T>
62where
63 T: Copy,
64{
65 fn is_terminated(&self) -> bool {
66 self.done
67 }
68}
69
70impl<T> Once<T>
71where
72 T: Copy,
73{
74 pub fn with_value(value: T) -> Self {
75 Self {
76 state: Rc::new(OnceState::new(value)),
77 }
78 }
79
80 pub fn notify(&self) -> SimResult {
81 if *self.state.triggered.borrow() {
82 return sim_error!("once event already triggered");
83 }
84 *self.state.triggered.borrow_mut() = true;
85 for waker in self.state.listen_waiting.borrow_mut().drain(..) {
86 waker.wake();
87 }
88 Ok(())
89 }
90}
91
92impl<T> Once<T>
93where
94 T: Copy + 'static,
95{
96 pub fn new(value: T) -> Self {
97 Self {
98 state: Rc::new(OnceState::new(value)),
99 }
100 }
101}
102
103impl Default for Once<()> {
104 fn default() -> Self {
105 Self::new(())
106 }
107}
108
109impl<T> Event<T> for Once<T>
110where
111 T: Copy + 'static,
112{
113 fn listen(&self) -> BoxFuture<'static, T> {
114 Box::pin(OnceFuture {
115 state: self.state.clone(),
116 done: false,
117 })
118 }
119
120 fn clone_dyn(&self) -> Box<dyn Event<T>> {
122 Box::new(self.clone())
123 }
124}
125
126impl<T> Future for OnceFuture<T>
127where
128 T: Copy,
129{
130 type Output = T;
131
132 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
133 if *self.state.triggered.borrow() {
134 self.done = true;
135 Poll::Ready(self.state.result)
136 } else {
137 self.state
138 .listen_waiting
139 .borrow_mut()
140 .push(cx.waker().clone());
141 Poll::Pending
142 }
143 }
144}