@@ -15,14 +15,10 @@ use serde::{Deserialize, Serialize};
15
15
use thiserror:: Error ;
16
16
use uuid:: Uuid ;
17
17
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
-
25
18
thread_local ! {
19
+ static SPAWN_QUEUE : RefCell <Vec <Pin <Box <dyn Future <Output = ( ) >>>>> = RefCell :: new( Vec :: new( ) ) ;
20
+
21
+
26
22
pub static APP_CONTEXT : RefCell <AppContext > = RefCell :: new( AppContext {
27
23
hidden_state: None ,
28
24
executor: Executor :: new( ) ,
@@ -140,22 +136,39 @@ pub struct Executor {
140
136
tasks : Vec < Pin < Box < dyn Future < Output = ( ) > > > > ,
141
137
}
142
138
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
+
143
146
impl Executor {
144
147
pub fn new ( ) -> Self {
145
148
Self { tasks : Vec :: new ( ) }
146
149
}
147
150
148
- pub fn spawn ( & mut self , fut : impl Future < Output = ( ) > + ' static ) {
149
- self . tasks . push ( Box :: pin ( fut) ) ;
150
- }
151
-
152
151
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
+ }
155
165
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 ;
159
172
}
160
173
}
161
174
@@ -282,17 +295,6 @@ where
282
295
return Err ( AppSendError :: SendError ( e) ) ;
283
296
}
284
297
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
-
296
298
// Enum defining the state persistance behaviour
297
299
#[ derive( Clone ) ]
298
300
pub enum SaveOptions {
0 commit comments