egui_cha/app.rs
1//! Core App trait - The heart of TEA
2
3use crate::{error::FrameworkError, sub::Sub, Cmd, ViewCtx};
4
5/// The main application trait following TEA (The Elm Architecture)
6///
7/// # Type Parameters
8/// - `Model`: Application state
9/// - `Msg`: Message type for state updates
10///
11/// # Example
12/// ```ignore
13/// struct MyApp;
14///
15/// impl App for MyApp {
16/// type Model = AppModel;
17/// type Msg = AppMsg;
18///
19/// fn init() -> (Self::Model, Cmd<Self::Msg>) {
20/// (AppModel::default(), Cmd::none())
21/// }
22///
23/// fn update(model: &mut Self::Model, msg: Self::Msg) -> Cmd<Self::Msg> {
24/// match msg {
25/// AppMsg::Increment => model.count += 1,
26/// AppMsg::Decrement => model.count -= 1,
27/// }
28/// Cmd::none()
29/// }
30///
31/// fn view(model: &Self::Model, ctx: &mut ViewCtx<Self::Msg>) {
32/// ctx.ui.label(format!("Count: {}", model.count));
33/// }
34/// }
35/// ```
36pub trait App: Sized + 'static {
37 /// Application state
38 type Model: Send + 'static;
39
40 /// Message type for triggering state updates
41 type Msg: Clone + Send + 'static;
42
43 /// Initialize the application with initial model and optional commands
44 fn init() -> (Self::Model, Cmd<Self::Msg>);
45
46 /// Update the model based on a message, optionally returning commands
47 fn update(model: &mut Self::Model, msg: Self::Msg) -> Cmd<Self::Msg>;
48
49 /// Render the view - use `ctx.emit()` to dispatch messages
50 fn view(model: &Self::Model, ctx: &mut ViewCtx<Self::Msg>);
51
52 /// Declare subscriptions based on current model state
53 ///
54 /// Called each frame. The runtime manages starting/stopping
55 /// subscriptions as they appear or disappear.
56 ///
57 /// # Example
58 /// ```ignore
59 /// fn subscriptions(model: &Model) -> Sub<Msg> {
60 /// if model.auto_refresh {
61 /// Sub::interval("refresh", Duration::from_secs(30), Msg::Refresh)
62 /// } else {
63 /// Sub::none()
64 /// }
65 /// }
66 /// ```
67 fn subscriptions(_model: &Self::Model) -> Sub<Self::Msg> {
68 Sub::none()
69 }
70
71 /// Handle framework errors
72 ///
73 /// Called when the framework encounters an internal error (task panic,
74 /// runtime failure, etc.). Override this to integrate with your app's
75 /// error handling.
76 ///
77 /// Default implementation logs to tracing and continues.
78 ///
79 /// # Example
80 /// ```ignore
81 /// fn on_framework_error(model: &mut Model, err: FrameworkError) -> Cmd<Msg> {
82 /// // Add to your error console
83 /// model.errors.push_with_level(&err.message, err.severity.into());
84 ///
85 /// // Or convert to your app's error type
86 /// Cmd::msg(Msg::Error(err.format_message()))
87 /// }
88 /// ```
89 fn on_framework_error(_model: &mut Self::Model, err: FrameworkError) -> Cmd<Self::Msg> {
90 err.log();
91 Cmd::none()
92 }
93}