gwr_engine/events/
any_of.rs1use std::cell::RefCell;
64use std::future::Future;
65use std::pin::Pin;
66use std::rc::Rc;
67use std::task::{Context, Poll};
68
69use futures::StreamExt;
70use futures::future::{FusedFuture, LocalBoxFuture};
71use futures::stream::FuturesUnordered;
72
73use crate::traits::{BoxFuture, Event};
74use crate::types::Eventable;
75
76pub struct AnyOfState<T> {
77 any_of: RefCell<Vec<Eventable<T>>>,
78}
79
80impl<T> AnyOfState<T> {
81 #[must_use]
82 pub fn new(any_of: Vec<Eventable<T>>) -> Self {
83 Self {
84 any_of: RefCell::new(any_of),
85 }
86 }
87}
88
89pub struct AnyOf<T> {
90 state: Rc<AnyOfState<T>>,
91}
92
93impl<T> AnyOf<T> {
94 #[must_use]
95 pub fn new(any_of: Vec<Eventable<T>>) -> Self {
96 Self {
97 state: Rc::new(AnyOfState::new(any_of)),
98 }
99 }
100}
101
102impl<T> Clone for AnyOf<T> {
103 fn clone(&self) -> Self {
104 let any_of = self.state.any_of.borrow();
105 let cloned = any_of.to_vec();
106 Self {
107 state: Rc::new(AnyOfState::new(cloned)),
108 }
109 }
110}
111
112impl<T> Event<T> for AnyOf<T>
113where
114 T: 'static,
115{
116 fn listen(&self) -> BoxFuture<'static, T> {
117 Box::pin(AnyOfFuture {
118 state: self.state.clone(),
119 future: None,
120 done: false,
121 })
122 }
123
124 fn clone_dyn(&self) -> Box<dyn Event<T>> {
126 Box::new(self.clone())
127 }
128}
129
130pub struct AnyOfFuture<T> {
131 state: Rc<AnyOfState<T>>,
132 future: Option<LocalBoxFuture<'static, T>>,
133 done: bool,
134}
135
136impl<T> FusedFuture for AnyOfFuture<T>
137where
138 T: 'static,
139{
140 fn is_terminated(&self) -> bool {
141 self.done
142 }
143}
144
145impl<T> Future for AnyOfFuture<T>
146where
147 T: 'static,
148{
149 type Output = T;
150
151 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
152 if self.future.is_none() {
153 let events = self.state.any_of.borrow_mut().drain(..).collect();
154 let future = any_of(events);
155 let pinned_future = Box::pin(future);
156 self.future = Some(pinned_future);
157 }
158
159 let future = self.future.as_mut().unwrap();
160 match future.as_mut().poll(cx) {
161 Poll::Ready(value) => {
162 self.done = true;
163 Poll::Ready(value)
164 }
165 Poll::Pending => Poll::Pending,
166 }
167 }
168}
169
170async fn any_of<T>(events: Vec<Box<dyn Event<T>>>) -> T {
171 let mut futures = FuturesUnordered::new();
172 for e in &events {
173 futures.push(e.listen());
174 }
175
176 futures.next().await.unwrap()
177}