Skip to content

Commit 45095a3

Browse files
committed
Add Handler for defered execution of messages
1 parent 7bdf167 commit 45095a3

19 files changed

+158
-107
lines changed

editor/src/dispatcher.rs

Lines changed: 4 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ use crate::messages::prelude::*;
55

66
#[derive(Debug, Default)]
77
pub struct Dispatcher {
8-
buffered_queue: Option<Vec<VecDeque<Message>>>,
98
message_queues: Vec<VecDeque<Message>>,
109
pub responses: Vec<FrontendMessage>,
1110
pub message_handlers: DispatcherMessageHandlers,
@@ -17,6 +16,7 @@ pub struct DispatcherMessageHandlers {
1716
app_window_message_handler: AppWindowMessageHandler,
1817
broadcast_message_handler: BroadcastMessageHandler,
1918
debug_message_handler: DebugMessageHandler,
19+
defer_message_handler: DeferMessageHandler,
2020
dialog_message_handler: DialogMessageHandler,
2121
globals_message_handler: GlobalsMessageHandler,
2222
input_preprocessor_message_handler: InputPreprocessorMessageHandler,
@@ -91,14 +91,6 @@ impl Dispatcher {
9191

9292
pub fn handle_message<T: Into<Message>>(&mut self, message: T, process_after_all_current: bool) {
9393
let message = message.into();
94-
// Add all additional messages to the buffer if it exists (except from the end buffer message)
95-
if !matches!(message, Message::EndBuffer { .. }) {
96-
if let Some(buffered_queue) = &mut self.buffered_queue {
97-
Self::schedule_execution(buffered_queue, true, [message]);
98-
99-
return;
100-
}
101-
}
10294

10395
// If we are not maintaining the buffer, simply add to the current queue
10496
Self::schedule_execution(&mut self.message_queues, process_after_all_current, [message]);
@@ -137,6 +129,9 @@ impl Dispatcher {
137129
Message::Debug(message) => {
138130
self.message_handlers.debug_message_handler.process_message(message, &mut queue, ());
139131
}
132+
Message::Defer(message) => {
133+
self.message_handlers.defer_message_handler.process_message(message, &mut queue, ());
134+
}
140135
Message::Dialog(message) => {
141136
let context = DialogMessageContext {
142137
portfolio: &self.message_handlers.portfolio_message_handler,
@@ -232,37 +227,6 @@ impl Dispatcher {
232227
Message::Batched { messages } => {
233228
messages.iter().for_each(|message| self.handle_message(message.to_owned(), false));
234229
}
235-
Message::StartBuffer => {
236-
self.buffered_queue = Some(std::mem::take(&mut self.message_queues));
237-
}
238-
Message::EndBuffer { render_metadata } => {
239-
// Assign the message queue to the currently buffered queue
240-
if let Some(buffered_queue) = self.buffered_queue.take() {
241-
self.cleanup_queues(false);
242-
assert!(self.message_queues.is_empty(), "message queues are always empty when ending a buffer");
243-
self.message_queues = buffered_queue;
244-
};
245-
246-
let graphene_std::renderer::RenderMetadata {
247-
upstream_footprints: footprints,
248-
local_transforms,
249-
first_instance_source_id,
250-
click_targets,
251-
clip_targets,
252-
} = render_metadata;
253-
254-
// Run these update state messages immediately
255-
let messages = [
256-
DocumentMessage::UpdateUpstreamTransforms {
257-
upstream_footprints: footprints,
258-
local_transforms,
259-
first_instance_source_id,
260-
},
261-
DocumentMessage::UpdateClickTargets { click_targets },
262-
DocumentMessage::UpdateClipTargets { clip_targets },
263-
];
264-
Self::schedule_execution(&mut self.message_queues, false, messages.map(Message::from));
265-
}
266230
}
267231

268232
// If there are child messages, append the queue to the list of queues
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
use crate::messages::prelude::*;
2+
3+
#[impl_message(Message, Defer)]
4+
#[derive(PartialEq, Clone, Debug, serde::Serialize, serde::Deserialize)]
5+
pub enum DeferMessage {
6+
TriggerGraphRun,
7+
AfterGraphRun { messages: Vec<Message> },
8+
TriggerViewportResize,
9+
AfterViewportResize { messages: Vec<Message> },
10+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
use crate::messages::prelude::*;
2+
3+
#[derive(Debug, Default, ExtractField)]
4+
pub struct DeferMessageHandler {
5+
after_graph_run: Vec<Message>,
6+
after_viewport_resize: Vec<Message>,
7+
}
8+
9+
#[message_handler_data]
10+
impl MessageHandler<DeferMessage, ()> for DeferMessageHandler {
11+
fn process_message(&mut self, message: DeferMessage, responses: &mut VecDeque<Message>, _: ()) {
12+
match message {
13+
DeferMessage::AfterGraphRun { messages } => {
14+
self.after_graph_run.extend_from_slice(&messages);
15+
}
16+
DeferMessage::AfterViewportResize { messages } => {
17+
self.after_viewport_resize.extend_from_slice(&messages);
18+
}
19+
DeferMessage::TriggerGraphRun => {
20+
for message in self.after_graph_run.drain(..) {
21+
responses.push_front(message);
22+
}
23+
}
24+
DeferMessage::TriggerViewportResize => {
25+
for message in self.after_viewport_resize.drain(..) {
26+
responses.push_front(message);
27+
}
28+
}
29+
}
30+
}
31+
32+
advertise_actions!(DeferMessageDiscriminant;
33+
);
34+
}

editor/src/messages/defer/mod.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
mod defer_message;
2+
mod defer_message_handler;
3+
4+
#[doc(inline)]
5+
pub use defer_message::{DeferMessage, DeferMessageDiscriminant};
6+
#[doc(inline)]
7+
pub use defer_message_handler::DeferMessageHandler;

editor/src/messages/dialog/new_document_dialog/new_document_dialog_message_handler.rs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,23 @@ impl MessageHandler<NewDocumentDialogMessage, ()> for NewDocumentDialogMessageHa
2424

2525
let create_artboard = !self.infinite && self.dimensions.x > 0 && self.dimensions.y > 0;
2626
if create_artboard {
27-
responses.add(Message::StartBuffer);
28-
responses.add(GraphOperationMessage::NewArtboard {
29-
id: NodeId::new(),
30-
artboard: graphene_std::Artboard::new(IVec2::ZERO, self.dimensions.as_ivec2()),
27+
responses.add(NodeGraphMessage::RunDocumentGraph);
28+
responses.add(DeferMessage::AfterGraphRun {
29+
messages: vec![
30+
GraphOperationMessage::NewArtboard {
31+
id: NodeId::new(),
32+
artboard: graphene_std::Artboard::new(IVec2::ZERO, self.dimensions.as_ivec2()),
33+
}
34+
.into(),
35+
],
3136
});
3237
}
3338

3439
// TODO: Figure out how to get StartBuffer to work here so we can delete this and use `DocumentMessage::ZoomCanvasToFitAll` instead
3540
// Currently, it is necessary to use `FrontendMessage::TriggerDelayedZoomCanvasToFitAll` rather than `DocumentMessage::ZoomCanvasToFitAll` because the size of the viewport is not yet populated
36-
responses.add(Message::StartBuffer);
37-
responses.add(FrontendMessage::TriggerDelayedZoomCanvasToFitAll);
41+
responses.add(DeferMessage::AfterViewportResize {
42+
messages: vec![DocumentMessage::ZoomCanvasToFitAll.into()],
43+
});
3844
responses.add(DocumentMessage::DeselectAllLayers);
3945
}
4046
}

editor/src/messages/input_preprocessor/input_preprocessor_message_handler.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ impl MessageHandler<InputPreprocessorMessage, InputPreprocessorMessageContext> f
3434
self.viewport_bounds = bounds;
3535

3636
responses.add(NavigationMessage::CanvasPan { delta: DVec2::ZERO });
37+
responses.add(DeferMessage::TriggerGraphRun);
3738
responses.add(NodeGraphMessage::SetGridAlignedEdges);
3839
}
3940
}

editor/src/messages/message.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use crate::messages::prelude::*;
2-
use graphene_std::renderer::RenderMetadata;
32
use graphite_proc_macros::*;
43

54
#[impl_message]
@@ -15,6 +14,8 @@ pub enum Message {
1514
#[child]
1615
Debug(DebugMessage),
1716
#[child]
17+
Defer(DeferMessage),
18+
#[child]
1819
Dialog(DialogMessage),
1920
#[child]
2021
Frontend(FrontendMessage),
@@ -40,10 +41,6 @@ pub enum Message {
4041
Batched {
4142
messages: Box<[Message]>,
4243
},
43-
StartBuffer,
44-
EndBuffer {
45-
render_metadata: RenderMetadata,
46-
},
4744
}
4845

4946
/// Provides an impl of `specta::Type` for `MessageDiscriminant`, the struct created by `impl_message`.

editor/src/messages/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ pub mod animation;
44
pub mod app_window;
55
pub mod broadcast;
66
pub mod debug;
7+
pub mod defer;
78
pub mod dialog;
89
pub mod frontend;
910
pub mod globals;

editor/src/messages/portfolio/document/document_message_handler.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1866,14 +1866,14 @@ impl DocumentMessageHandler {
18661866

18671867
let previous_network = std::mem::replace(&mut self.network_interface, network_interface);
18681868

1869-
// Push the UpdateOpenDocumentsList message to the bus in order to update the save status of the open documents
1870-
responses.add(PortfolioMessage::UpdateOpenDocumentsList);
1871-
responses.add(NodeGraphMessage::SelectedNodesUpdated);
1872-
responses.add(NodeGraphMessage::ForceRunDocumentGraph);
18731869
// TODO: Remove once the footprint is used to load the imports/export distances from the edge
1874-
responses.add(NodeGraphMessage::UnloadWires);
1875-
responses.add(NodeGraphMessage::SetGridAlignedEdges);
1876-
responses.add(Message::StartBuffer);
1870+
responses.push_front(NodeGraphMessage::UnloadWires.into());
1871+
responses.push_front(NodeGraphMessage::SetGridAlignedEdges.into());
1872+
1873+
// Push the UpdateOpenDocumentsList message to the bus in order to update the save status of the open documents
1874+
responses.push_front(NodeGraphMessage::ForceRunDocumentGraph.into());
1875+
responses.push_front(NodeGraphMessage::SelectedNodesUpdated.into());
1876+
responses.push_front(PortfolioMessage::UpdateOpenDocumentsList.into());
18771877
Some(previous_network)
18781878
}
18791879
pub fn redo_with_history(&mut self, ipp: &InputPreprocessorMessageHandler, responses: &mut VecDeque<Message>) {

editor/src/messages/portfolio/portfolio_message_handler.rs

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -568,8 +568,9 @@ impl MessageHandler<PortfolioMessage, PortfolioMessageContext<'_>> for Portfolio
568568

569569
responses.add(NodeGraphMessage::RunDocumentGraph);
570570
responses.add(NodeGraphMessage::SelectedNodesSet { nodes: all_new_ids });
571-
responses.add(Message::StartBuffer);
572-
responses.add(PortfolioMessage::CenterPastedLayers { layers });
571+
responses.add(DeferMessage::AfterGraphRun {
572+
messages: vec![PortfolioMessage::CenterPastedLayers { layers }.into()],
573+
});
573574
}
574575
}
575576
}
@@ -701,13 +702,13 @@ impl MessageHandler<PortfolioMessage, PortfolioMessageContext<'_>> for Portfolio
701702

702703
if create_document {
703704
// Wait for the document to be rendered so the click targets can be calculated in order to determine the artboard size that will encompass the pasted image
704-
responses.add(Message::StartBuffer);
705-
responses.add(DocumentMessage::WrapContentInArtboard { place_artboard_at_origin: true });
705+
responses.add(DeferMessage::AfterGraphRun {
706+
messages: vec![DocumentMessage::WrapContentInArtboard { place_artboard_at_origin: true }.into()],
707+
});
706708

707-
// TODO: Figure out how to get StartBuffer to work here so we can delete this and use `DocumentMessage::ZoomCanvasToFitAll` instead
708-
// Currently, it is necessary to use `FrontendMessage::TriggerDelayedZoomCanvasToFitAll` rather than `DocumentMessage::ZoomCanvasToFitAll` because the size of the viewport is not yet populated
709-
responses.add(Message::StartBuffer);
710-
responses.add(FrontendMessage::TriggerDelayedZoomCanvasToFitAll);
709+
responses.add(DeferMessage::AfterViewportResize {
710+
messages: vec![DocumentMessage::ZoomCanvasToFitAll.into()],
711+
});
711712
}
712713
}
713714
PortfolioMessage::PasteSvg {
@@ -733,13 +734,13 @@ impl MessageHandler<PortfolioMessage, PortfolioMessageContext<'_>> for Portfolio
733734

734735
if create_document {
735736
// Wait for the document to be rendered so the click targets can be calculated in order to determine the artboard size that will encompass the pasted image
736-
responses.add(Message::StartBuffer);
737-
responses.add(DocumentMessage::WrapContentInArtboard { place_artboard_at_origin: true });
737+
responses.add(DeferMessage::AfterGraphRun {
738+
messages: vec![DocumentMessage::WrapContentInArtboard { place_artboard_at_origin: true }.into()],
739+
});
738740

739-
// TODO: Figure out how to get StartBuffer to work here so we can delete this and use `DocumentMessage::ZoomCanvasToFitAll` instead
740-
// Currently, it is necessary to use `FrontendMessage::TriggerDelayedZoomCanvasToFitAll` rather than `DocumentMessage::ZoomCanvasToFitAll` because the size of the viewport is not yet populated
741-
responses.add(Message::StartBuffer);
742-
responses.add(FrontendMessage::TriggerDelayedZoomCanvasToFitAll);
741+
responses.add(DeferMessage::AfterViewportResize {
742+
messages: vec![DocumentMessage::ZoomCanvasToFitAll.into()],
743+
});
743744
}
744745
}
745746
PortfolioMessage::PrevDocument => {
@@ -1019,9 +1020,7 @@ impl PortfolioMessageHandler {
10191020
/text>"#
10201021
// It's a mystery why the `/text>` tag above needs to be missing its `<`, but when it exists it prints the `<` character in the text. However this works with it removed.
10211022
.to_string();
1022-
responses.add(Message::EndBuffer {
1023-
render_metadata: graphene_std::renderer::RenderMetadata::default(),
1024-
});
1023+
responses.add(DeferMessage::TriggerGraphRun);
10251024
responses.add(FrontendMessage::UpdateDocumentArtwork { svg: error });
10261025
}
10271026
result

0 commit comments

Comments
 (0)