iced_runtime/multi_window/
state.rs
1use crate::core::event::{self, Event};
3use crate::core::mouse;
4use crate::core::renderer;
5use crate::core::widget::operation::{self, Operation};
6use crate::core::{Clipboard, Size};
7use crate::user_interface::{self, UserInterface};
8use crate::{Debug, Program, Task};
9
10#[allow(missing_debug_implementations)]
13pub struct State<P>
14where
15 P: Program + 'static,
16{
17 program: P,
18 caches: Option<Vec<user_interface::Cache>>,
19 queued_events: Vec<Event>,
20 queued_messages: Vec<P::Message>,
21 mouse_interaction: mouse::Interaction,
22}
23
24impl<P> State<P>
25where
26 P: Program + 'static,
27{
28 pub fn new(
31 program: P,
32 bounds: Size,
33 renderer: &mut P::Renderer,
34 debug: &mut Debug,
35 ) -> Self {
36 let user_interface = build_user_interface(
37 &program,
38 user_interface::Cache::default(),
39 renderer,
40 bounds,
41 debug,
42 );
43
44 let caches = Some(vec![user_interface.into_cache()]);
45
46 State {
47 program,
48 caches,
49 queued_events: Vec::new(),
50 queued_messages: Vec::new(),
51 mouse_interaction: mouse::Interaction::None,
52 }
53 }
54
55 pub fn program(&self) -> &P {
57 &self.program
58 }
59
60 pub fn queue_event(&mut self, event: Event) {
64 self.queued_events.push(event);
65 }
66
67 pub fn queue_message(&mut self, message: P::Message) {
71 self.queued_messages.push(message);
72 }
73
74 pub fn is_queue_empty(&self) -> bool {
76 self.queued_events.is_empty() && self.queued_messages.is_empty()
77 }
78
79 pub fn mouse_interaction(&self) -> mouse::Interaction {
81 self.mouse_interaction
82 }
83
84 pub fn update(
91 &mut self,
92 bounds: Size,
93 cursor: mouse::Cursor,
94 renderer: &mut P::Renderer,
95 theme: &P::Theme,
96 style: &renderer::Style,
97 clipboard: &mut dyn Clipboard,
98 debug: &mut Debug,
99 ) -> (Vec<Event>, Option<Task<P::Message>>) {
100 let mut user_interfaces = build_user_interfaces(
101 &self.program,
102 self.caches.take().unwrap(),
103 renderer,
104 bounds,
105 debug,
106 );
107
108 debug.event_processing_started();
109 let mut messages = Vec::new();
110
111 let uncaptured_events = user_interfaces.iter_mut().fold(
112 vec![],
113 |mut uncaptured_events, ui| {
114 let (_, event_statuses) = ui.update(
115 &self.queued_events,
116 cursor,
117 renderer,
118 clipboard,
119 &mut messages,
120 );
121
122 uncaptured_events.extend(
123 self.queued_events
124 .iter()
125 .zip(event_statuses)
126 .filter_map(|(event, status)| {
127 matches!(status, event::Status::Ignored)
128 .then_some(event)
129 })
130 .cloned(),
131 );
132 uncaptured_events
133 },
134 );
135
136 self.queued_events.clear();
137 messages.append(&mut self.queued_messages);
138 debug.event_processing_finished();
139
140 let commands = if messages.is_empty() {
141 debug.draw_started();
142
143 for ui in &mut user_interfaces {
144 self.mouse_interaction =
145 ui.draw(renderer, theme, style, cursor);
146 }
147
148 debug.draw_finished();
149
150 self.caches = Some(
151 user_interfaces
152 .drain(..)
153 .map(UserInterface::into_cache)
154 .collect(),
155 );
156
157 None
158 } else {
159 let temp_caches = user_interfaces
160 .drain(..)
161 .map(UserInterface::into_cache)
162 .collect();
163
164 drop(user_interfaces);
165
166 let commands = Task::batch(messages.into_iter().map(|msg| {
167 debug.log_message(&msg);
168
169 debug.update_started();
170 let task = self.program.update(msg);
171 debug.update_finished();
172
173 task
174 }));
175
176 let mut user_interfaces = build_user_interfaces(
177 &self.program,
178 temp_caches,
179 renderer,
180 bounds,
181 debug,
182 );
183
184 debug.draw_started();
185 for ui in &mut user_interfaces {
186 self.mouse_interaction =
187 ui.draw(renderer, theme, style, cursor);
188 }
189 debug.draw_finished();
190
191 self.caches = Some(
192 user_interfaces
193 .drain(..)
194 .map(UserInterface::into_cache)
195 .collect(),
196 );
197
198 Some(commands)
199 };
200
201 (uncaptured_events, commands)
202 }
203
204 pub fn operate(
206 &mut self,
207 renderer: &mut P::Renderer,
208 operations: impl Iterator<Item = Box<dyn Operation>>,
209 bounds: Size,
210 debug: &mut Debug,
211 ) {
212 let mut user_interfaces = build_user_interfaces(
213 &self.program,
214 self.caches.take().unwrap(),
215 renderer,
216 bounds,
217 debug,
218 );
219
220 for operation in operations {
221 let mut current_operation = Some(operation);
222
223 while let Some(mut operation) = current_operation.take() {
224 for ui in &mut user_interfaces {
225 ui.operate(renderer, operation.as_mut());
226 }
227
228 match operation.finish() {
229 operation::Outcome::None => {}
230 operation::Outcome::Some(()) => {}
231 operation::Outcome::Chain(next) => {
232 current_operation = Some(next);
233 }
234 };
235 }
236 }
237
238 self.caches = Some(
239 user_interfaces
240 .drain(..)
241 .map(UserInterface::into_cache)
242 .collect(),
243 );
244 }
245}
246
247fn build_user_interfaces<'a, P: Program>(
248 program: &'a P,
249 mut caches: Vec<user_interface::Cache>,
250 renderer: &mut P::Renderer,
251 size: Size,
252 debug: &mut Debug,
253) -> Vec<UserInterface<'a, P::Message, P::Theme, P::Renderer>> {
254 caches
255 .drain(..)
256 .map(|cache| {
257 build_user_interface(program, cache, renderer, size, debug)
258 })
259 .collect()
260}
261
262fn build_user_interface<'a, P: Program>(
263 program: &'a P,
264 cache: user_interface::Cache,
265 renderer: &mut P::Renderer,
266 size: Size,
267 debug: &mut Debug,
268) -> UserInterface<'a, P::Message, P::Theme, P::Renderer> {
269 debug.view_started();
270 let view = program.view();
271 debug.view_finished();
272
273 debug.layout_started();
274 let user_interface = UserInterface::build(view, size, cache, renderer);
275 debug.layout_finished();
276
277 user_interface
278}