Skip to content

Commit fbefdbd

Browse files
committed
hyperapp: add spawn()
1 parent 9971afe commit fbefdbd

File tree

1 file changed

+29
-27
lines changed

1 file changed

+29
-27
lines changed

src/hyperapp.rs

Lines changed: 29 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,10 @@ use serde::{Deserialize, Serialize};
1515
use thiserror::Error;
1616
use uuid::Uuid;
1717

18-
// macro_export puts it in the root,
19-
// so we re-export here so you can use as either
20-
// hyperware_process_lib::run_async
21-
// or
22-
// hyperware_process_lib::hyperapp::run_async
23-
pub use crate::run_async;
24-
2518
thread_local! {
19+
static SPAWN_QUEUE: RefCell<Vec<Pin<Box<dyn Future<Output = ()>>>>> = RefCell::new(Vec::new());
20+
21+
2622
pub static APP_CONTEXT: RefCell<AppContext> = RefCell::new(AppContext {
2723
hidden_state: None,
2824
executor: Executor::new(),
@@ -140,22 +136,39 @@ pub struct Executor {
140136
tasks: Vec<Pin<Box<dyn Future<Output = ()>>>>,
141137
}
142138

139+
pub fn spawn(fut: impl Future<Output = ()> + 'static) {
140+
SPAWN_QUEUE.with(|queue| {
141+
queue.borrow_mut().push(Box::pin(fut));
142+
})
143+
}
144+
145+
143146
impl Executor {
144147
pub fn new() -> Self {
145148
Self { tasks: Vec::new() }
146149
}
147150

148-
pub fn spawn(&mut self, fut: impl Future<Output = ()> + 'static) {
149-
self.tasks.push(Box::pin(fut));
150-
}
151-
152151
pub fn poll_all_tasks(&mut self) {
153-
let mut ctx = Context::from_waker(noop_waker_ref());
154-
let mut completed = Vec::new();
152+
loop {
153+
SPAWN_QUEUE.with(|queue| {
154+
self.tasks.append(&mut queue.borrow_mut());
155+
});
156+
157+
let mut ctx = Context::from_waker(noop_waker_ref());
158+
let mut completed = Vec::new();
159+
160+
for i in 0..self.tasks.len() {
161+
if let Poll::Ready(()) = self.tasks[i].as_mut().poll(&mut ctx) {
162+
completed.push(i);
163+
}
164+
}
155165

156-
for i in 0..self.tasks.len() {
157-
if let Poll::Ready(()) = self.tasks[i].as_mut().poll(&mut ctx) {
158-
completed.push(i);
166+
// tasks can spawn more tasks
167+
let should_break = SPAWN_QUEUE.with(|queue| {
168+
queue.is_empty()
169+
});
170+
if should_break {
171+
break;
159172
}
160173
}
161174

@@ -282,17 +295,6 @@ where
282295
return Err(AppSendError::SendError(e));
283296
}
284297

285-
#[macro_export]
286-
macro_rules! run_async {
287-
($($code:tt)*) => {
288-
hyperware_process_lib::hyperapp::APP_CONTEXT.with(|ctx| {
289-
ctx.borrow_mut().executor.spawn(async move {
290-
$($code)*
291-
})
292-
})
293-
};
294-
}
295-
296298
// Enum defining the state persistance behaviour
297299
#[derive(Clone)]
298300
pub enum SaveOptions {

0 commit comments

Comments
 (0)