@@ -7,11 +7,12 @@ use crate::core::{Element, Size};
77use crate :: program:: Program ;
88use crate :: runtime:: futures:: futures:: StreamExt ;
99use crate :: runtime:: futures:: futures:: channel:: mpsc;
10+ use crate :: runtime:: futures:: futures:: stream;
1011use crate :: runtime:: futures:: subscription;
1112use crate :: runtime:: futures:: { Executor , Runtime } ;
1213use crate :: runtime:: task;
1314use crate :: runtime:: user_interface;
14- use crate :: runtime:: { Action , UserInterface } ;
15+ use crate :: runtime:: { Action , Task , UserInterface } ;
1516
1617#[ allow( missing_debug_implementations) ]
1718pub struct Emulator < P : Program > {
@@ -52,18 +53,10 @@ impl<P: Program + 'static> Emulator<P> {
5253 ) )
5354 . expect ( "Create emulator renderer" ) ;
5455
55- let mut runtime = Runtime :: new ( executor, sender) ;
56-
56+ let runtime = Runtime :: new ( executor, sender) ;
5757 let ( state, task) = program. boot ( ) ;
5858
59- if let Some ( stream) = task:: into_stream ( task) {
60- runtime. run ( stream. map ( Event :: Action ) . boxed ( ) ) ;
61- }
62-
63- // TODO: Async boot environments
64- runtime. send ( Event :: Ready ) ;
65-
66- Self {
59+ let mut emulator = Self {
6760 state,
6861 runtime,
6962 renderer,
@@ -72,7 +65,12 @@ impl<P: Program + 'static> Emulator<P> {
7265 cursor : mouse:: Cursor :: Unavailable ,
7366 window : window:: Id :: unique ( ) ,
7467 cache : Some ( user_interface:: Cache :: default ( ) ) ,
75- }
68+ } ;
69+
70+ // TODO: Configurable
71+ emulator. wait_for ( task) ;
72+
73+ emulator
7674 }
7775
7876 pub fn update ( & mut self , program : & P , message : P :: Message ) {
@@ -82,11 +80,7 @@ impl<P: Program + 'static> Emulator<P> {
8280 self . runtime . run ( stream. map ( Event :: Action ) . boxed ( ) ) ;
8381 }
8482
85- self . runtime . track ( subscription:: into_recipes (
86- program
87- . subscription ( & self . state )
88- . map ( |message| Event :: Action ( Action :: Output ( message) ) ) ,
89- ) ) ;
83+ self . resubscribe ( program) ;
9084 }
9185
9286 pub fn perform ( & mut self , program : & P , action : Action < P :: Message > ) {
@@ -152,11 +146,35 @@ impl<P: Program + 'static> Emulator<P> {
152146
153147 self . cache = Some ( user_interface. into_cache ( ) ) ;
154148
155- for message in messages {
156- self . update ( program, message) ;
149+ let task = Task :: batch (
150+ messages
151+ . into_iter ( )
152+ . map ( |message| program. update ( & mut self . state , message) ) ,
153+ ) ;
154+
155+ // TODO: Configurable
156+ self . wait_for ( task) ;
157+
158+ self . resubscribe ( program) ;
159+ }
160+
161+ pub fn wait_for ( & mut self , task : Task < P :: Message > ) {
162+ if let Some ( stream) = task:: into_stream ( task) {
163+ self . runtime . run (
164+ stream
165+ . map ( Event :: Action )
166+ . chain ( stream:: once ( async { Event :: Ready } ) )
167+ . boxed ( ) ,
168+ ) ;
157169 }
170+ }
158171
159- self . runtime . send ( Event :: Ready ) ;
172+ pub fn resubscribe ( & mut self , program : & P ) {
173+ self . runtime . track ( subscription:: into_recipes (
174+ program
175+ . subscription ( & self . state )
176+ . map ( |message| Event :: Action ( Action :: Output ( message) ) ) ,
177+ ) ) ;
160178 }
161179
162180 pub fn view (
0 commit comments