@@ -63,20 +63,33 @@ impl Dispatcher {
6363 }
6464 }
6565
66- pub fn handle_message < T : Into < Message > > ( & mut self , message : T ) {
67- self . message_queues . push ( VecDeque :: from_iter ( [ message. into ( ) ] ) ) ;
68- while let Some ( message) = self . message_queues . last_mut ( ) . and_then ( VecDeque :: pop_front) {
69- // Do not buffer the EndBuffer message
70- if !matches ! ( message, Message :: EndBuffer ( _) ) {
71- if let Some ( buffered_queue) = & mut self . buffered_queue {
72- // Store each message in a deque so that its children are added before future messages
73- let mut message_deque = VecDeque :: new ( ) ;
74- message_deque. push_back ( message) ;
75- buffered_queue. push ( message_deque) ;
76- continue ;
77- }
66+ /// Add a message to a queue so that it can be executed.
67+ /// If `process_after_all_current` is set, all currently queued messages (including children) will be processed first.
68+ /// If not set, it (and its children) will be processed as soon as possible.
69+ pub fn schedule_execution ( message_queues : & mut Vec < VecDeque < Message > > , process_after_all_current : bool , messages : impl IntoIterator < Item = Message > ) {
70+ match message_queues. first_mut ( ) {
71+ // If there are currently messages being processed and we are processing after them, add to the end of the first queue
72+ Some ( queue) if process_after_all_current => queue. extend ( messages) ,
73+ // In all other cases, make a new inner queue and add our message there
74+ _ => message_queues. push ( VecDeque :: from_iter ( messages) ) ,
75+ }
76+ }
77+
78+ pub fn handle_message < T : Into < Message > > ( & mut self , message : T , process_after_all_current : bool ) {
79+ let message = message. into ( ) ;
80+ // Add all aditional messages to the buffer if it exists (except from the end buffer message)
81+ if !matches ! ( message, Message :: EndBuffer ( _) ) {
82+ if let Some ( buffered_queue) = & mut self . buffered_queue {
83+ Self :: schedule_execution ( buffered_queue, true , [ message] ) ;
84+
85+ return ;
7886 }
87+ }
88+
89+ // If we are not maintaining the buffer, simply add to the current queue
90+ Self :: schedule_execution ( & mut self . message_queues , process_after_all_current, [ message] ) ;
7991
92+ while let Some ( message) = self . message_queues . last_mut ( ) . and_then ( VecDeque :: pop_front) {
8093 // Skip processing of this message if it will be processed later (at the end of the shallowest level queue)
8194 if SIDE_EFFECT_FREE_MESSAGES . contains ( & message. to_discriminant ( ) ) {
8295 let already_in_queue = self . message_queues . first ( ) . filter ( |queue| queue. contains ( & message) ) . is_some ( ) ;
@@ -92,7 +105,7 @@ impl Dispatcher {
92105 }
93106 }
94107
95- // Print the message at a verbosity level of `log `
108+ // Print the message at a verbosity level of `info `
96109 self . log_message ( & message, & self . message_queues , self . message_handlers . debug_message_handler . message_logging_verbosity ) ;
97110
98111 // Create a new queue for the child messages
@@ -104,9 +117,11 @@ impl Dispatcher {
104117 self . buffered_queue = Some ( std:: mem:: take ( & mut self . message_queues ) ) ;
105118 }
106119 Message :: EndBuffer ( render_metadata) => {
107- // The buffered vec is added before the metadata messages, because the end of the vec is processed first
120+ // Assign the message queue to the currently buffered queue
108121 if let Some ( buffered_queue) = self . buffered_queue . take ( ) {
109- self . message_queues . extend ( buffered_queue) ;
122+ self . cleanup_queues ( false ) ;
123+ assert ! ( self . message_queues. is_empty( ) , "message queues are always empty when ending a buffer" ) ;
124+ self . message_queues = buffered_queue;
110125 } ;
111126
112127 let graphene_std:: renderer:: RenderMetadata {
@@ -115,14 +130,13 @@ impl Dispatcher {
115130 clip_targets,
116131 } = render_metadata;
117132
118- let mut update_upstream_transform = VecDeque :: new ( ) ;
119- update_upstream_transform. push_back ( DocumentMessage :: UpdateUpstreamTransforms { upstream_transforms : footprints } . into ( ) ) ;
120- self . message_queues . push ( update_upstream_transform) ;
121-
122- let mut update_click_targets = VecDeque :: new ( ) ;
123- update_click_targets. push_back ( DocumentMessage :: UpdateClickTargets { click_targets } . into ( ) ) ;
124- update_click_targets. push_back ( DocumentMessage :: UpdateClipTargets { clip_targets } . into ( ) ) ;
125- self . message_queues . push ( update_click_targets) ;
133+ // Run these update state messages immediately
134+ let messages = [
135+ DocumentMessage :: UpdateUpstreamTransforms { upstream_transforms : footprints } ,
136+ DocumentMessage :: UpdateClickTargets { click_targets } ,
137+ DocumentMessage :: UpdateClipTargets { clip_targets } ,
138+ ] ;
139+ Self :: schedule_execution ( & mut self . message_queues , false , messages. map ( Message :: from) ) ;
126140 }
127141 Message :: NoOp => { }
128142 Message :: Init => {
@@ -141,7 +155,7 @@ impl Dispatcher {
141155 } ) ;
142156 }
143157 Message :: Batched ( messages) => {
144- messages. iter ( ) . for_each ( |message| self . handle_message ( message. to_owned ( ) ) ) ;
158+ messages. iter ( ) . for_each ( |message| self . handle_message ( message. to_owned ( ) , false ) ) ;
145159 }
146160 Message :: Broadcast ( message) => self . message_handlers . broadcast_message_handler . process_message ( message, & mut queue, ( ) ) ,
147161 Message :: Debug ( message) => {
0 commit comments