From 149eb8a0246b618c90dca0e9265195a05f8c7d7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 4 Jun 2025 13:35:09 +0200 Subject: [PATCH] Wait for `Task` in `Emulator` automatically --- test/src/emulator.rs | 60 ++++++++++++++++++++++++++++---------------- 1 file changed, 39 insertions(+), 21 deletions(-) diff --git a/test/src/emulator.rs b/test/src/emulator.rs index cb1b7ed0..d6b5f939 100644 --- a/test/src/emulator.rs +++ b/test/src/emulator.rs @@ -7,11 +7,12 @@ use crate::core::{Element, Size}; use crate::program::Program; use crate::runtime::futures::futures::StreamExt; use crate::runtime::futures::futures::channel::mpsc; +use crate::runtime::futures::futures::stream; use crate::runtime::futures::subscription; use crate::runtime::futures::{Executor, Runtime}; use crate::runtime::task; use crate::runtime::user_interface; -use crate::runtime::{Action, UserInterface}; +use crate::runtime::{Action, Task, UserInterface}; #[allow(missing_debug_implementations)] pub struct Emulator { @@ -52,18 +53,10 @@ impl Emulator

{ )) .expect("Create emulator renderer"); - let mut runtime = Runtime::new(executor, sender); - + let runtime = Runtime::new(executor, sender); let (state, task) = program.boot(); - if let Some(stream) = task::into_stream(task) { - runtime.run(stream.map(Event::Action).boxed()); - } - - // TODO: Async boot environments - runtime.send(Event::Ready); - - Self { + let mut emulator = Self { state, runtime, renderer, @@ -72,7 +65,12 @@ impl Emulator

{ cursor: mouse::Cursor::Unavailable, window: window::Id::unique(), cache: Some(user_interface::Cache::default()), - } + }; + + // TODO: Configurable + emulator.wait_for(task); + + emulator } pub fn update(&mut self, program: &P, message: P::Message) { @@ -82,11 +80,7 @@ impl Emulator

{ self.runtime.run(stream.map(Event::Action).boxed()); } - self.runtime.track(subscription::into_recipes( - program - .subscription(&self.state) - .map(|message| Event::Action(Action::Output(message))), - )); + self.resubscribe(program); } pub fn perform(&mut self, program: &P, action: Action) { @@ -152,11 +146,35 @@ impl Emulator

{ self.cache = Some(user_interface.into_cache()); - for message in messages { - self.update(program, message); - } + let task = Task::batch( + messages + .into_iter() + .map(|message| program.update(&mut self.state, message)), + ); - self.runtime.send(Event::Ready); + // TODO: Configurable + self.wait_for(task); + + self.resubscribe(program); + } + + pub fn wait_for(&mut self, task: Task) { + if let Some(stream) = task::into_stream(task) { + self.runtime.run( + stream + .map(Event::Action) + .chain(stream::once(async { Event::Ready })) + .boxed(), + ); + } + } + + pub fn resubscribe(&mut self, program: &P) { + self.runtime.track(subscription::into_recipes( + program + .subscription(&self.state) + .map(|message| Event::Action(Action::Output(message))), + )); } pub fn view(