1+ use crate :: document:: PortfolioMessageHandler ;
2+ use crate :: global:: GlobalMessageHandler ;
3+ use crate :: input:: { InputMapperMessageHandler , InputPreprocessorMessageHandler } ;
14use crate :: message_prelude:: * ;
5+ use crate :: viewport_tools:: tool_message_handler:: ToolMessageHandler ;
26
3- pub use crate :: document:: PortfolioMessageHandler ;
4- pub use crate :: input:: { InputMapper , InputPreprocessor } ;
5- pub use crate :: tool:: ToolMessageHandler ;
6-
7- use crate :: global:: GlobalMessageHandler ;
87use std:: collections:: VecDeque ;
98
109#[ derive( Debug , Default ) ]
1110pub struct Dispatcher {
12- input_preprocessor : InputPreprocessor ,
13- input_mapper : InputMapper ,
11+ message_queue : VecDeque < Message > ,
12+ pub responses : Vec < FrontendMessage > ,
13+ message_handlers : DispatcherMessageHandlers ,
14+ }
15+
16+ #[ remain:: sorted]
17+ #[ derive( Debug , Default ) ]
18+ struct DispatcherMessageHandlers {
1419 global_message_handler : GlobalMessageHandler ,
15- tool_message_handler : ToolMessageHandler ,
20+ input_mapper_message_handler : InputMapperMessageHandler ,
21+ input_preprocessor_message_handler : InputPreprocessorMessageHandler ,
1622 portfolio_message_handler : PortfolioMessageHandler ,
17- messages : VecDeque < Message > ,
18- pub responses : Vec < FrontendMessage > ,
23+ tool_message_handler : ToolMessageHandler ,
1924}
2025
21- // For optimization, these are messages guaranteed to be redundant when repeated
22- // The last occurrence of the message in the message queue is sufficient to ensure correctness
23- // In addition, these messages do not change any state in the backend (aside from caches)
26+ // For optimization, these are messages guaranteed to be redundant when repeated.
27+ // The last occurrence of the message in the message queue is sufficient to ensure correct behavior.
28+ // In addition, these messages do not change any state in the backend (aside from caches).
2429const SIDE_EFFECT_FREE_MESSAGES : & [ MessageDiscriminant ] = & [
2530 MessageDiscriminant :: Portfolio ( PortfolioMessageDiscriminant :: Document ( DocumentMessageDiscriminant :: RenderDocument ) ) ,
2631 MessageDiscriminant :: Portfolio ( PortfolioMessageDiscriminant :: Document ( DocumentMessageDiscriminant :: FolderChanged ) ) ,
@@ -35,28 +40,54 @@ impl Dispatcher {
3540 Self :: default ( )
3641 }
3742
43+ #[ remain:: check]
3844 pub fn handle_message < T : Into < Message > > ( & mut self , message : T ) {
39- self . messages . push_back ( message. into ( ) ) ;
45+ self . message_queue . push_back ( message. into ( ) ) ;
4046
4147 use Message :: * ;
42- while let Some ( message) = self . messages . pop_front ( ) {
48+ while let Some ( message) = self . message_queue . pop_front ( ) {
4349 // Skip processing of this message if it will be processed later
44- if SIDE_EFFECT_FREE_MESSAGES . contains ( & message. to_discriminant ( ) ) && self . messages . contains ( & message) {
50+ if SIDE_EFFECT_FREE_MESSAGES . contains ( & message. to_discriminant ( ) ) && self . message_queue . contains ( & message) {
4551 continue ;
4652 }
53+
54+ // Print the message at a verbosity level of `log`
4755 self . log_message ( & message) ;
56+
57+ // Process the action by forwarding it to the relevant message handler, or saving the FrontendMessage to be sent to the frontend
58+ #[ remain:: sorted]
4859 match message {
49- NoOp => ( ) ,
50- Portfolio ( message) => self . portfolio_message_handler . process_action ( message, & self . input_preprocessor , & mut self . messages ) ,
51- Global ( message) => self . global_message_handler . process_action ( message, ( ) , & mut self . messages ) ,
52- Tool ( message) => self
53- . tool_message_handler
54- . process_action ( message, ( self . portfolio_message_handler . active_document ( ) , & self . input_preprocessor ) , & mut self . messages ) ,
55- Frontend ( message) => self . responses . push ( message) ,
56- InputPreprocessor ( message) => self . input_preprocessor . process_action ( message, ( ) , & mut self . messages ) ,
60+ Frontend ( message) => {
61+ // `FrontendMessage`s are saved and will be sent to the frontend after the message queue is done being processed
62+ self . responses . push ( message) ;
63+ }
64+ Global ( message) => {
65+ self . message_handlers . global_message_handler . process_action ( message, ( ) , & mut self . message_queue ) ;
66+ }
5767 InputMapper ( message) => {
5868 let actions = self . collect_actions ( ) ;
59- self . input_mapper . process_action ( message, ( & self . input_preprocessor , actions) , & mut self . messages )
69+ self . message_handlers
70+ . input_mapper_message_handler
71+ . process_action ( message, ( & self . message_handlers . input_preprocessor_message_handler , actions) , & mut self . message_queue ) ;
72+ }
73+ InputPreprocessor ( message) => {
74+ self . message_handlers . input_preprocessor_message_handler . process_action ( message, ( ) , & mut self . message_queue ) ;
75+ }
76+ NoOp => { }
77+ Portfolio ( message) => {
78+ self . message_handlers
79+ . portfolio_message_handler
80+ . process_action ( message, & self . message_handlers . input_preprocessor_message_handler , & mut self . message_queue ) ;
81+ }
82+ Tool ( message) => {
83+ self . message_handlers . tool_message_handler . process_action (
84+ message,
85+ (
86+ self . message_handlers . portfolio_message_handler . active_document ( ) ,
87+ & self . message_handlers . input_preprocessor_message_handler ,
88+ ) ,
89+ & mut self . message_queue ,
90+ ) ;
6091 }
6192 }
6293 }
@@ -65,11 +96,11 @@ impl Dispatcher {
6596 pub fn collect_actions ( & self ) -> ActionList {
6697 // TODO: Reduce the number of heap allocations
6798 let mut list = Vec :: new ( ) ;
68- list. extend ( self . input_preprocessor . actions ( ) ) ;
69- list. extend ( self . input_mapper . actions ( ) ) ;
70- list. extend ( self . global_message_handler . actions ( ) ) ;
71- list. extend ( self . tool_message_handler . actions ( ) ) ;
72- list. extend ( self . portfolio_message_handler . actions ( ) ) ;
99+ list. extend ( self . message_handlers . input_preprocessor_message_handler . actions ( ) ) ;
100+ list. extend ( self . message_handlers . input_mapper_message_handler . actions ( ) ) ;
101+ list. extend ( self . message_handlers . global_message_handler . actions ( ) ) ;
102+ list. extend ( self . message_handlers . tool_message_handler . actions ( ) ) ;
103+ list. extend ( self . message_handlers . portfolio_message_handler . actions ( ) ) ;
73104 list
74105 }
75106
@@ -82,21 +113,21 @@ impl Dispatcher {
82113 ) || MessageDiscriminant :: from ( message) . local_name ( ) . ends_with ( "MouseMove" ) )
83114 {
84115 log:: trace!( "Message: {:?}" , message) ;
85- // log::trace!("Hints: {:?}", self.input_mapper .hints(self.collect_actions()));
116+ // log::trace!("Hints: {:?}", self.input_mapper_message_handler .hints(self.collect_actions()));
86117 }
87118 }
88119}
89120
90121#[ cfg( test) ]
91122mod test {
92- use crate :: {
93- communication :: set_uuid_seed ,
94- document :: { Clipboard :: * , DocumentMessageHandler } ,
95- message_prelude:: * ,
96- misc:: test_utils:: EditorTestUtils ,
97- Editor ,
98- } ;
99- use graphene:: { color :: Color , Operation } ;
123+ use crate :: communication :: set_uuid_seed ;
124+ use crate :: document :: clipboards :: Clipboard ;
125+ use crate :: document :: DocumentMessageHandler ;
126+ use crate :: message_prelude:: * ;
127+ use crate :: misc:: test_utils:: EditorTestUtils ;
128+ use crate :: Editor ;
129+ use graphene :: color :: Color ;
130+ use graphene:: Operation ;
100131
101132 fn init_logger ( ) {
102133 let _ = env_logger:: builder ( ) . is_test ( true ) . try_init ( ) ;
@@ -129,14 +160,14 @@ mod test {
129160 init_logger ( ) ;
130161 let mut editor = create_editor_with_three_layers ( ) ;
131162
132- let document_before_copy = editor. dispatcher . portfolio_message_handler . active_document ( ) . graphene_document . clone ( ) ;
133- editor. handle_message ( PortfolioMessage :: Copy ( User ) ) ;
163+ let document_before_copy = editor. dispatcher . message_handlers . portfolio_message_handler . active_document ( ) . graphene_document . clone ( ) ;
164+ editor. handle_message ( PortfolioMessage :: Copy ( Clipboard :: User ) ) ;
134165 editor. handle_message ( PortfolioMessage :: PasteIntoFolder {
135- clipboard : User ,
166+ clipboard : Clipboard :: User ,
136167 path : vec ! [ ] ,
137168 insert_index : -1 ,
138169 } ) ;
139- let document_after_copy = editor. dispatcher . portfolio_message_handler . active_document ( ) . graphene_document . clone ( ) ;
170+ let document_after_copy = editor. dispatcher . message_handlers . portfolio_message_handler . active_document ( ) . graphene_document . clone ( ) ;
140171
141172 let layers_before_copy = document_before_copy. root . as_folder ( ) . unwrap ( ) . layers ( ) ;
142173 let layers_after_copy = document_after_copy. root . as_folder ( ) . unwrap ( ) . layers ( ) ;
@@ -163,18 +194,18 @@ mod test {
163194 init_logger ( ) ;
164195 let mut editor = create_editor_with_three_layers ( ) ;
165196
166- let document_before_copy = editor. dispatcher . portfolio_message_handler . active_document ( ) . graphene_document . clone ( ) ;
197+ let document_before_copy = editor. dispatcher . message_handlers . portfolio_message_handler . active_document ( ) . graphene_document . clone ( ) ;
167198 let shape_id = document_before_copy. root . as_folder ( ) . unwrap ( ) . layer_ids [ 1 ] ;
168199
169200 editor. handle_message ( DocumentMessage :: SetSelectedLayers ( vec ! [ vec![ shape_id] ] ) ) ;
170- editor. handle_message ( PortfolioMessage :: Copy ( User ) ) ;
201+ editor. handle_message ( PortfolioMessage :: Copy ( Clipboard :: User ) ) ;
171202 editor. handle_message ( PortfolioMessage :: PasteIntoFolder {
172- clipboard : User ,
203+ clipboard : Clipboard :: User ,
173204 path : vec ! [ ] ,
174205 insert_index : -1 ,
175206 } ) ;
176207
177- let document_after_copy = editor. dispatcher . portfolio_message_handler . active_document ( ) . graphene_document . clone ( ) ;
208+ let document_after_copy = editor. dispatcher . message_handlers . portfolio_message_handler . active_document ( ) . graphene_document . clone ( ) ;
178209
179210 let layers_before_copy = document_before_copy. root . as_folder ( ) . unwrap ( ) . layers ( ) ;
180211 let layers_after_copy = document_after_copy. root . as_folder ( ) . unwrap ( ) . layers ( ) ;
@@ -206,7 +237,7 @@ mod test {
206237
207238 editor. handle_message ( DocumentMessage :: CreateEmptyFolder ( vec ! [ ] ) ) ;
208239
209- let document_before_added_shapes = editor. dispatcher . portfolio_message_handler . active_document ( ) . graphene_document . clone ( ) ;
240+ let document_before_added_shapes = editor. dispatcher . message_handlers . portfolio_message_handler . active_document ( ) . graphene_document . clone ( ) ;
210241 let folder_id = document_before_added_shapes. root . as_folder ( ) . unwrap ( ) . layer_ids [ FOLDER_INDEX ] ;
211242
212243 // TODO: This adding of a Line and Pen should be rewritten using the corresponding functions in EditorTestUtils.
@@ -228,22 +259,22 @@ mod test {
228259
229260 editor. handle_message ( DocumentMessage :: SetSelectedLayers ( vec ! [ vec![ folder_id] ] ) ) ;
230261
231- let document_before_copy = editor. dispatcher . portfolio_message_handler . active_document ( ) . graphene_document . clone ( ) ;
262+ let document_before_copy = editor. dispatcher . message_handlers . portfolio_message_handler . active_document ( ) . graphene_document . clone ( ) ;
232263
233- editor. handle_message ( PortfolioMessage :: Copy ( User ) ) ;
264+ editor. handle_message ( PortfolioMessage :: Copy ( Clipboard :: User ) ) ;
234265 editor. handle_message ( DocumentMessage :: DeleteSelectedLayers ) ;
235266 editor. handle_message ( PortfolioMessage :: PasteIntoFolder {
236- clipboard : User ,
267+ clipboard : Clipboard :: User ,
237268 path : vec ! [ ] ,
238269 insert_index : -1 ,
239270 } ) ;
240271 editor. handle_message ( PortfolioMessage :: PasteIntoFolder {
241- clipboard : User ,
272+ clipboard : Clipboard :: User ,
242273 path : vec ! [ ] ,
243274 insert_index : -1 ,
244275 } ) ;
245276
246- let document_after_copy = editor. dispatcher . portfolio_message_handler . active_document ( ) . graphene_document . clone ( ) ;
277+ let document_after_copy = editor. dispatcher . message_handlers . portfolio_message_handler . active_document ( ) . graphene_document . clone ( ) ;
247278
248279 let layers_before_copy = document_before_copy. root . as_folder ( ) . unwrap ( ) . layers ( ) ;
249280 let layers_after_copy = document_after_copy. root . as_folder ( ) . unwrap ( ) . layers ( ) ;
@@ -294,26 +325,26 @@ mod test {
294325 const SHAPE_INDEX : usize = 1 ;
295326 const RECT_INDEX : usize = 0 ;
296327
297- let document_before_copy = editor. dispatcher . portfolio_message_handler . active_document ( ) . graphene_document . clone ( ) ;
328+ let document_before_copy = editor. dispatcher . message_handlers . portfolio_message_handler . active_document ( ) . graphene_document . clone ( ) ;
298329 let rect_id = document_before_copy. root . as_folder ( ) . unwrap ( ) . layer_ids [ RECT_INDEX ] ;
299330 let ellipse_id = document_before_copy. root . as_folder ( ) . unwrap ( ) . layer_ids [ ELLIPSE_INDEX ] ;
300331
301332 editor. handle_message ( DocumentMessage :: SetSelectedLayers ( vec ! [ vec![ rect_id] , vec![ ellipse_id] ] ) ) ;
302- editor. handle_message ( PortfolioMessage :: Copy ( User ) ) ;
333+ editor. handle_message ( PortfolioMessage :: Copy ( Clipboard :: User ) ) ;
303334 editor. handle_message ( DocumentMessage :: DeleteSelectedLayers ) ;
304335 editor. draw_rect ( 0. , 800. , 12. , 200. ) ;
305336 editor. handle_message ( PortfolioMessage :: PasteIntoFolder {
306- clipboard : User ,
337+ clipboard : Clipboard :: User ,
307338 path : vec ! [ ] ,
308339 insert_index : -1 ,
309340 } ) ;
310341 editor. handle_message ( PortfolioMessage :: PasteIntoFolder {
311- clipboard : User ,
342+ clipboard : Clipboard :: User ,
312343 path : vec ! [ ] ,
313344 insert_index : -1 ,
314345 } ) ;
315346
316- let document_after_copy = editor. dispatcher . portfolio_message_handler . active_document ( ) . graphene_document . clone ( ) ;
347+ let document_after_copy = editor. dispatcher . message_handlers . portfolio_message_handler . active_document ( ) . graphene_document . clone ( ) ;
317348
318349 let layers_before_copy = document_before_copy. root . as_folder ( ) . unwrap ( ) . layers ( ) ;
319350 let layers_after_copy = document_after_copy. root . as_folder ( ) . unwrap ( ) . layers ( ) ;
@@ -343,7 +374,7 @@ mod test {
343374 fn map_to_vec ( paths : Vec < & [ LayerId ] > ) -> Vec < Vec < LayerId > > {
344375 paths. iter ( ) . map ( |layer| layer. to_vec ( ) ) . collect :: < Vec < _ > > ( )
345376 }
346- let sorted_layers = map_to_vec ( editor. dispatcher . portfolio_message_handler . active_document ( ) . all_layers_sorted ( ) ) ;
377+ let sorted_layers = map_to_vec ( editor. dispatcher . message_handlers . portfolio_message_handler . active_document ( ) . all_layers_sorted ( ) ) ;
347378 println ! ( "Sorted layers: {:?}" , sorted_layers) ;
348379
349380 let verify_order = |handler : & mut DocumentMessageHandler | {
@@ -357,15 +388,15 @@ mod test {
357388 editor. handle_message ( DocumentMessage :: SetSelectedLayers ( sorted_layers[ ..2 ] . to_vec ( ) ) ) ;
358389
359390 editor. handle_message ( DocumentMessage :: ReorderSelectedLayers ( 1 ) ) ;
360- let ( all, non_selected, selected) = verify_order ( editor. dispatcher . portfolio_message_handler . active_document_mut ( ) ) ;
391+ let ( all, non_selected, selected) = verify_order ( editor. dispatcher . message_handlers . portfolio_message_handler . active_document_mut ( ) ) ;
361392 assert_eq ! ( all, non_selected. into_iter( ) . chain( selected. into_iter( ) ) . collect:: <Vec <_>>( ) ) ;
362393
363394 editor. handle_message ( DocumentMessage :: ReorderSelectedLayers ( -1 ) ) ;
364- let ( all, non_selected, selected) = verify_order ( editor. dispatcher . portfolio_message_handler . active_document_mut ( ) ) ;
395+ let ( all, non_selected, selected) = verify_order ( editor. dispatcher . message_handlers . portfolio_message_handler . active_document_mut ( ) ) ;
365396 assert_eq ! ( all, selected. into_iter( ) . chain( non_selected. into_iter( ) ) . collect:: <Vec <_>>( ) ) ;
366397
367398 editor. handle_message ( DocumentMessage :: ReorderSelectedLayers ( i32:: MAX ) ) ;
368- let ( all, non_selected, selected) = verify_order ( editor. dispatcher . portfolio_message_handler . active_document_mut ( ) ) ;
399+ let ( all, non_selected, selected) = verify_order ( editor. dispatcher . message_handlers . portfolio_message_handler . active_document_mut ( ) ) ;
369400 assert_eq ! ( all, non_selected. into_iter( ) . chain( selected. into_iter( ) ) . collect:: <Vec <_>>( ) ) ;
370401 }
371402}
0 commit comments