11use crate :: core:: event:: { self , Event } ;
22use crate :: core:: mouse;
33use crate :: core:: renderer;
4+ use crate :: core:: widget:: operation:: {
5+ Operation , OperationOutputWrapper , OperationWrapper , Outcome ,
6+ } ;
47use crate :: core:: { Clipboard , Point , Size } ;
58use crate :: user_interface:: { self , UserInterface } ;
6- use crate :: { Command , Debug , Program } ;
9+ use crate :: { command :: Action , Command , Debug , Program } ;
710
811/// The execution state of a [`Program`]. It leverages caching, event
912/// processing, and rendering primitive storage.
97100 style : & renderer:: Style ,
98101 clipboard : & mut dyn Clipboard ,
99102 debug : & mut Debug ,
100- ) -> ( Vec < Event > , Option < Command < P :: Message > > ) {
103+ ) -> ( Vec < Event > , Vec < Action < P :: Message > > ) {
101104 let mut user_interface = build_user_interface (
102105 id,
103106 & mut self . program ,
@@ -132,21 +135,21 @@ where
132135 messages. append ( & mut self . queued_messages ) ;
133136 debug. event_processing_finished ( ) ;
134137
135- let command = if messages. is_empty ( ) {
138+ let actions = if messages. is_empty ( ) {
136139 debug. draw_started ( ) ;
137140 self . mouse_interaction =
138141 user_interface. draw ( renderer, theme, style, cursor_position) ;
139142 debug. draw_finished ( ) ;
140143
141144 self . cache = Some ( user_interface. into_cache ( ) ) ;
142145
143- None
146+ Vec :: new ( )
144147 } else {
145148 // When there are messages, we are forced to rebuild twice
146149 // for now :^)
147150 let temp_cache = user_interface. into_cache ( ) ;
148151
149- let commands =
152+ let ( actions , widget_actions ) =
150153 Command :: batch ( messages. into_iter ( ) . map ( |message| {
151154 debug. log_message ( & message) ;
152155
@@ -155,7 +158,12 @@ where
155158 debug. update_finished ( ) ;
156159
157160 command
158- } ) ) ;
161+ } ) )
162+ . actions ( )
163+ . into_iter ( )
164+ . partition :: < Vec < _ > , _ > ( |action| {
165+ !matches ! ( action, Action :: Widget ( _) )
166+ } ) ;
159167
160168 let mut user_interface = build_user_interface (
161169 id,
@@ -166,17 +174,58 @@ where
166174 debug,
167175 ) ;
168176
177+ let had_operations = !widget_actions. is_empty ( ) ;
178+ for operation in widget_actions
179+ . into_iter ( )
180+ . map ( |action| match action {
181+ Action :: Widget ( widget_action) => widget_action,
182+ _ => unreachable ! ( ) ,
183+ } )
184+ . map ( OperationWrapper :: Message )
185+ {
186+ let mut current_operation = Some ( operation) ;
187+ while let Some ( mut operation) = current_operation. take ( ) {
188+ user_interface. operate ( renderer, & mut operation) ;
189+ match operation. finish ( ) {
190+ Outcome :: Some ( OperationOutputWrapper :: Message (
191+ message,
192+ ) ) => self . queued_messages . push ( message) ,
193+ Outcome :: Chain ( op) => {
194+ current_operation =
195+ Some ( OperationWrapper :: Wrapper ( op) ) ;
196+ }
197+ _ => { }
198+ } ;
199+ }
200+ }
201+
202+ let mut user_interface = if had_operations {
203+ // When there were operations, we are forced to rebuild thrice ...
204+ let temp_cache = user_interface. into_cache ( ) ;
205+
206+ build_user_interface (
207+ id,
208+ & mut self . program ,
209+ temp_cache,
210+ renderer,
211+ bounds,
212+ debug,
213+ )
214+ } else {
215+ user_interface
216+ } ;
217+
169218 debug. draw_started ( ) ;
170219 self . mouse_interaction =
171220 user_interface. draw ( renderer, theme, style, cursor_position) ;
172221 debug. draw_finished ( ) ;
173222
174223 self . cache = Some ( user_interface. into_cache ( ) ) ;
175224
176- Some ( commands )
225+ actions
177226 } ;
178227
179- ( uncaptured_events, command )
228+ ( uncaptured_events, actions )
180229 }
181230}
182231
0 commit comments