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 audio::AudioControllerHandle,
11 grapheme,
12 input::EventReader,
13 runtime::{self},
14 screen::CanvasHandle,
15};
16
17#[derive(Debug)]
18#[non_exhaustive]
19pub struct App {
20 pub tick_session: TickSession,
21 pub canvas: CanvasHandle,
22 pub events: EventReader,
23 pub grapheme_registry: grapheme::Registry,
24 pub audio_controller: AudioControllerHandle,
25 pub cancel_token: CancellationToken,
26}
27
28impl App {
29 pub(crate) fn run<F, A>(
30 self,
31 join_set: &mut runtime::JoinSet,
32 scope: F,
33 ) -> Arc<MessageBox<A::Output>>
34 where
35 F: FnOnce(Self) -> A,
36 A: Future + Send + 'static,
37 A::Output: Send + 'static,
38 {
39 let output = Arc::new(MessageBox::empty());
40 let future = scope(self);
41 join_set.spawn({
42 let output = output.clone();
43 async move {
44 output.store(future.await, Relaxed);
45 Ok(())
46 }
47 });
48 output
49 }
50}