zest_core/application.rs
1//! [`Application`] trait + [`Task`] + [`Subscription`] + [`Recipe`].
2
3pub mod box_future;
4pub mod subscription;
5pub mod task;
6
7use crate::screen::ScreenView;
8use embedded_graphics::pixelcolor::PixelColor;
9
10pub use box_future::BoxFuture;
11pub use subscription::{Recipe, Subscription};
12pub use task::Task;
13
14// ---- Application -------------------------------------------------------
15
16/// An application running under the [`Runtime`](crate::runtime::Runtime).
17///
18/// libcosmic-shaped: the user defines an application *type*, not an
19/// application *value*. The runtime calls [`Application::init`] to
20/// obtain the initial state and a startup [`Task`] (used to kick off
21/// async loads — read config, fetch initial data, etc.).
22pub trait Application: Sized + 'static {
23 /// Application message type. Must be `Clone` for runtime
24 /// dispatch through `update`.
25 type Message: Clone + 'static;
26 /// Pixel color type used by this application's display.
27 type Color: PixelColor;
28 /// Concrete screen type — typically a user-defined enum
29 /// dispatching to per-screen structs via match arms.
30 type Screen: ScreenView<Self::Color, Self::Message>;
31
32 /// Construct the initial application state and a startup task.
33 /// Called once by the runtime before the event loop starts.
34 fn init() -> (Self, Task<Self::Message>);
35
36 /// Mutate state in response to a message.
37 fn update(&mut self, message: Self::Message) -> Task<Self::Message>;
38
39 /// The currently-active screen (for drawing).
40 fn view(&self) -> &Self::Screen;
41
42 /// Long-lived message sources. Called once at startup and after
43 /// every processed message — refresh is automatic. Identity comes
44 /// from the [`Recipe`] inside, so changing what's returned
45 /// (or returning `Subscription::none()`) cleanly replaces the
46 /// subscription. Default: none.
47 fn subscription(&self) -> Subscription<Self::Message> {
48 Subscription::none()
49 }
50}