1use crate::application::{Application, Boot, View};
3use crate::program;
4use crate::theme;
5use crate::time::Instant;
6use crate::window;
7use crate::{Element, Program, Settings, Subscription, Task};
8
9pub fn timed<State, Message, Theme, Renderer>(
21 boot: impl Boot<State, Message>,
22 update: impl Update<State, Message>,
23 subscription: impl Fn(&State) -> Subscription<Message>,
24 view: impl for<'a> View<'a, State, Message, Theme, Renderer>,
25) -> Application<
26 impl Program<State = State, Message = (Message, Instant), Theme = Theme>,
27>
28where
29 State: 'static,
30 Message: program::Message + 'static,
31 Theme: Default + theme::Base + 'static,
32 Renderer: program::Renderer + 'static,
33{
34 use std::marker::PhantomData;
35
36 struct Instance<
37 State,
38 Message,
39 Theme,
40 Renderer,
41 Boot,
42 Update,
43 Subscription,
44 View,
45 > {
46 boot: Boot,
47 update: Update,
48 subscription: Subscription,
49 view: View,
50 _state: PhantomData<State>,
51 _message: PhantomData<Message>,
52 _theme: PhantomData<Theme>,
53 _renderer: PhantomData<Renderer>,
54 }
55
56 impl<State, Message, Theme, Renderer, Boot, Update, Subscription, View>
57 Program
58 for Instance<
59 State,
60 Message,
61 Theme,
62 Renderer,
63 Boot,
64 Update,
65 Subscription,
66 View,
67 >
68 where
69 Message: program::Message + 'static,
70 Theme: Default + theme::Base + 'static,
71 Renderer: program::Renderer + 'static,
72 Boot: self::Boot<State, Message>,
73 Update: self::Update<State, Message>,
74 Subscription: Fn(&State) -> self::Subscription<Message>,
75 View: for<'a> self::View<'a, State, Message, Theme, Renderer>,
76 {
77 type State = State;
78 type Message = (Message, Instant);
79 type Theme = Theme;
80 type Renderer = Renderer;
81 type Executor = iced_futures::backend::default::Executor;
82
83 fn name() -> &'static str {
84 let name = std::any::type_name::<State>();
85
86 name.split("::").next().unwrap_or("a_cool_application")
87 }
88
89 fn boot(&self) -> (State, Task<Self::Message>) {
90 let (state, task) = self.boot.boot();
91
92 (state, task.map(|message| (message, Instant::now())))
93 }
94
95 fn update(
96 &self,
97 state: &mut Self::State,
98 (message, now): Self::Message,
99 ) -> Task<Self::Message> {
100 self.update
101 .update(state, message, now)
102 .into()
103 .map(|message| (message, Instant::now()))
104 }
105
106 fn view<'a>(
107 &self,
108 state: &'a Self::State,
109 _window: window::Id,
110 ) -> Element<'a, Self::Message, Self::Theme, Self::Renderer> {
111 self.view
112 .view(state)
113 .map(|message| (message, Instant::now()))
114 }
115
116 fn subscription(
117 &self,
118 state: &Self::State,
119 ) -> self::Subscription<Self::Message> {
120 (self.subscription)(state).map(|message| (message, Instant::now()))
121 }
122 }
123
124 Application {
125 raw: Instance {
126 boot,
127 update,
128 subscription,
129 view,
130 _state: PhantomData,
131 _message: PhantomData,
132 _theme: PhantomData,
133 _renderer: PhantomData,
134 },
135 settings: Settings::default(),
136 window: window::Settings::default(),
137 }
138}
139
140pub trait Update<State, Message> {
145 fn update(
147 &self,
148 state: &mut State,
149 message: Message,
150 now: Instant,
151 ) -> impl Into<Task<Message>>;
152}
153
154impl<State, Message> Update<State, Message> for () {
155 fn update(
156 &self,
157 _state: &mut State,
158 _message: Message,
159 _now: Instant,
160 ) -> impl Into<Task<Message>> {
161 }
162}
163
164impl<T, State, Message, C> Update<State, Message> for T
165where
166 T: Fn(&mut State, Message, Instant) -> C,
167 C: Into<Task<Message>>,
168{
169 fn update(
170 &self,
171 state: &mut State,
172 message: Message,
173 now: Instant,
174 ) -> impl Into<Task<Message>> {
175 self(state, message, now)
176 }
177}