Skip to content

Commit b21b1cb

Browse files
authored
Simplify the implementation of the message buffering (#2123)
* Simplify the implementation of the message buffering * Add assert to ensure list is empty
1 parent e3bb11e commit b21b1cb

File tree

3 files changed

+46
-25
lines changed

3 files changed

+46
-25
lines changed

editor/src/application.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ impl Editor {
1616
}
1717

1818
pub fn handle_message<T: Into<Message>>(&mut self, message: T) -> Vec<FrontendMessage> {
19-
self.dispatcher.handle_message(message);
19+
self.dispatcher.handle_message(message, true);
2020

2121
std::mem::take(&mut self.dispatcher.responses)
2222
}

editor/src/dispatcher.rs

Lines changed: 38 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -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) => {

editor/src/messages/tool/tool_messages/select_tool.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -912,6 +912,7 @@ impl Fsm for SelectToolFsmState {
912912
responses.add(DocumentMessage::EndTransaction);
913913

914914
if !tool_data.has_dragged && input.keyboard.key(remove_from_selection) && tool_data.layer_selected_on_start.is_none() {
915+
// When you click on the layer with remove from selection key (shift) pressed, we deselect all nodes that are children.
915916
let quad = tool_data.selection_quad();
916917
let intersection = document.intersect_quad_no_artboards(quad, input);
917918

@@ -942,6 +943,7 @@ impl Fsm for SelectToolFsmState {
942943
});
943944
}
944945
} else if let Some(selecting_layer) = tool_data.select_single_layer.take() {
946+
// Previously, we may have had many layers selected. If the user clicks without dragging, we should just select the one layer that has been clicked.
945947
if !tool_data.has_dragged {
946948
if selecting_layer == LayerNodeIdentifier::ROOT_PARENT {
947949
log::error!("selecting_layer should not be ROOT_PARENT");
@@ -1207,6 +1209,9 @@ fn drag_deepest_manipulation(responses: &mut VecDeque<Message>, selected: Vec<La
12071209
});
12081210
}
12091211

1212+
/// Called when you double click on the layer of the shallowest layer.
1213+
/// If possible, the direct sibling of an old selected layer is the new selected layer.
1214+
/// Otherwise, the first non-parent ancestor is selected.
12101215
fn edit_layer_shallowest_manipulation(document: &DocumentMessageHandler, layer: LayerNodeIdentifier, responses: &mut VecDeque<Message>) {
12111216
let Some(new_selected) = layer.ancestors(document.metadata()).filter(not_artboard(document)).find(|ancestor| {
12121217
ancestor
@@ -1224,6 +1229,8 @@ fn edit_layer_shallowest_manipulation(document: &DocumentMessageHandler, layer:
12241229
responses.add(NodeGraphMessage::SelectedNodesSet { nodes: vec![new_selected.to_node()] });
12251230
}
12261231

1232+
/// Called when a double click on a layer in deep select mode.
1233+
/// If the layer is text, the text tool is selected.
12271234
fn edit_layer_deepest_manipulation(layer: LayerNodeIdentifier, network_interface: &NodeNetworkInterface, responses: &mut VecDeque<Message>) {
12281235
if is_layer_fed_by_node_of_name(layer, network_interface, "Text") {
12291236
responses.add_front(ToolMessage::ActivateTool { tool_type: ToolType::Text });

0 commit comments

Comments
 (0)