1use std::sync::{Arc, atomic::Ordering::*};
2
3use thedes_async_util::{
4 non_blocking::spsc::watch::{AtomicMessage, MessageBox},
5 timer::TickSession,
6};
7use tokio_util::sync::CancellationToken;
8
9use crate::{
10 grapheme,
11 input::EventReader,
12 runtime::{self},
13 screen::CanvasHandle,
14};
15
16#[derive(Debug)]
17#[non_exhaustive]
18pub struct App {
19 pub tick_session: TickSession,
20 pub canvas: CanvasHandle,
21 pub events: EventReader,
22 pub grapheme_registry: grapheme::Registry,
23 pub cancel_token: CancellationToken,
24}
25
26impl App {
27 pub(crate) fn run<F, A>(
28 self,
29 join_set: &mut runtime::JoinSet,
30 scope: F,
31 ) -> Arc<MessageBox<A::Output>>
32 where
33 F: FnOnce(Self) -> A,
34 A: Future + Send + 'static,
35 A::Output: Send + 'static,
36 {
37 let output = Arc::new(MessageBox::empty());
38 let future = scope(self);
39 join_set.spawn({
40 let output = output.clone();
41 async move {
42 output.store(future.await, Relaxed);
43 Ok(())
44 }
45 });
46 output
47 }
48}