mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2025-08-22 14:04:05 +00:00
Track which document the deferred executions belong to (#3010)
* Track which document the deferred executions belong to * Cleanup * Fix tests * Fix freehand tool * Notify defer handler of graph execution updates asap
This commit is contained in:
parent
96a1b12a05
commit
ef2fab32a2
11 changed files with 64 additions and 41 deletions
|
@ -1,4 +1,5 @@
|
|||
use crate::messages::debug::utility_types::MessageLoggingVerbosity;
|
||||
use crate::messages::defer::DeferMessageContext;
|
||||
use crate::messages::dialog::DialogMessageContext;
|
||||
use crate::messages::layout::layout_message_handler::LayoutMessageContext;
|
||||
use crate::messages::prelude::*;
|
||||
|
@ -133,7 +134,10 @@ impl Dispatcher {
|
|||
self.message_handlers.debug_message_handler.process_message(message, &mut queue, ());
|
||||
}
|
||||
Message::Defer(message) => {
|
||||
self.message_handlers.defer_message_handler.process_message(message, &mut queue, ());
|
||||
let context = DeferMessageContext {
|
||||
portfolio: &self.message_handlers.portfolio_message_handler,
|
||||
};
|
||||
self.message_handlers.defer_message_handler.process_message(message, &mut queue, context);
|
||||
}
|
||||
Message::Dialog(message) => {
|
||||
let context = DialogMessageContext {
|
||||
|
|
|
@ -4,7 +4,7 @@ use crate::messages::prelude::*;
|
|||
#[derive(PartialEq, Clone, Debug, serde::Serialize, serde::Deserialize)]
|
||||
pub enum DeferMessage {
|
||||
SetGraphSubmissionIndex(u64),
|
||||
TriggerGraphRun(u64),
|
||||
TriggerGraphRun(u64, DocumentId),
|
||||
AfterGraphRun { messages: Vec<Message> },
|
||||
TriggerNavigationReady,
|
||||
AfterNavigationReady { messages: Vec<Message> },
|
||||
|
|
|
@ -1,18 +1,24 @@
|
|||
use crate::messages::prelude::*;
|
||||
|
||||
#[derive(ExtractField)]
|
||||
pub struct DeferMessageContext<'a> {
|
||||
pub portfolio: &'a PortfolioMessageHandler,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, ExtractField)]
|
||||
pub struct DeferMessageHandler {
|
||||
after_graph_run: Vec<(u64, Message)>,
|
||||
after_graph_run: HashMap<DocumentId, Vec<(u64, Message)>>,
|
||||
after_viewport_resize: Vec<Message>,
|
||||
current_graph_submission_id: u64,
|
||||
}
|
||||
|
||||
#[message_handler_data]
|
||||
impl MessageHandler<DeferMessage, ()> for DeferMessageHandler {
|
||||
fn process_message(&mut self, message: DeferMessage, responses: &mut VecDeque<Message>, _: ()) {
|
||||
impl MessageHandler<DeferMessage, DeferMessageContext<'_>> for DeferMessageHandler {
|
||||
fn process_message(&mut self, message: DeferMessage, responses: &mut VecDeque<Message>, context: DeferMessageContext) {
|
||||
match message {
|
||||
DeferMessage::AfterGraphRun { mut messages } => {
|
||||
self.after_graph_run.extend(messages.drain(..).map(|m| (self.current_graph_submission_id, m)));
|
||||
let after_graph_run = self.after_graph_run.entry(context.portfolio.active_document_id.unwrap_or(DocumentId(0))).or_default();
|
||||
after_graph_run.extend(messages.drain(..).map(|m| (self.current_graph_submission_id, m)));
|
||||
}
|
||||
DeferMessage::AfterNavigationReady { messages } => {
|
||||
self.after_viewport_resize.extend_from_slice(&messages);
|
||||
|
@ -20,16 +26,20 @@ impl MessageHandler<DeferMessage, ()> for DeferMessageHandler {
|
|||
DeferMessage::SetGraphSubmissionIndex(execution_id) => {
|
||||
self.current_graph_submission_id = execution_id + 1;
|
||||
}
|
||||
DeferMessage::TriggerGraphRun(execution_id) => {
|
||||
if self.after_graph_run.is_empty() {
|
||||
DeferMessage::TriggerGraphRun(execution_id, document_id) => {
|
||||
let after_graph_run = self.after_graph_run.entry(document_id).or_default();
|
||||
if after_graph_run.is_empty() {
|
||||
return;
|
||||
}
|
||||
// Find the index of the last message we can process
|
||||
let split = self.after_graph_run.partition_point(|&(id, _)| id <= execution_id);
|
||||
let elements = self.after_graph_run.drain(..split);
|
||||
let split = after_graph_run.partition_point(|&(id, _)| id <= execution_id);
|
||||
let elements = after_graph_run.drain(..split);
|
||||
for (_, message) in elements.rev() {
|
||||
responses.add_front(message);
|
||||
}
|
||||
if !after_graph_run.is_empty() {
|
||||
responses.add(NodeGraphMessage::RunDocumentGraph);
|
||||
}
|
||||
}
|
||||
DeferMessage::TriggerNavigationReady => {
|
||||
for message in self.after_viewport_resize.drain(..).rev() {
|
||||
|
|
|
@ -4,4 +4,4 @@ mod defer_message_handler;
|
|||
#[doc(inline)]
|
||||
pub use defer_message::{DeferMessage, DeferMessageDiscriminant};
|
||||
#[doc(inline)]
|
||||
pub use defer_message_handler::DeferMessageHandler;
|
||||
pub use defer_message_handler::{DeferMessageContext, DeferMessageHandler};
|
||||
|
|
|
@ -32,6 +32,11 @@ impl MessageHandler<NewDocumentDialogMessage, ()> for NewDocumentDialogMessageHa
|
|||
artboard: graphene_std::Artboard::new(IVec2::ZERO, self.dimensions.as_ivec2()),
|
||||
}
|
||||
.into(),
|
||||
NodeGraphMessage::ForceRunDocumentGraph.into(),
|
||||
DeferMessage::AfterGraphRun {
|
||||
messages: vec![DeferMessage::TriggerNavigationReady.into()],
|
||||
}
|
||||
.into(),
|
||||
],
|
||||
});
|
||||
responses.add(DeferMessage::AfterNavigationReady {
|
||||
|
|
|
@ -35,15 +35,6 @@ impl MessageHandler<InputPreprocessorMessage, InputPreprocessorMessageContext> f
|
|||
|
||||
responses.add(NavigationMessage::CanvasPan { delta: DVec2::ZERO });
|
||||
responses.add(NodeGraphMessage::SetGridAlignedEdges);
|
||||
// We have to wait until a node node graph has run and all messages from that execution have been processed.
|
||||
responses.add(DeferMessage::AfterGraphRun {
|
||||
messages: vec![
|
||||
DeferMessage::AfterGraphRun {
|
||||
messages: vec![DeferMessage::TriggerNavigationReady.into()],
|
||||
}
|
||||
.into(),
|
||||
],
|
||||
});
|
||||
}
|
||||
}
|
||||
InputPreprocessorMessage::DoubleClick { editor_mouse_state, modifier_keys } => {
|
||||
|
|
|
@ -347,12 +347,13 @@ impl MessageHandler<PortfolioMessage, PortfolioMessageContext<'_>> for Portfolio
|
|||
let inspect_node = self.inspect_node_id();
|
||||
if let Ok(message) = self.executor.submit_node_graph_evaluation(
|
||||
self.documents.get_mut(document_id).expect("Tried to render non-existent document"),
|
||||
*document_id,
|
||||
ipp.viewport_bounds.size().as_uvec2(),
|
||||
timing_information,
|
||||
inspect_node,
|
||||
true,
|
||||
) {
|
||||
responses.add(message);
|
||||
responses.add_front(message);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -378,16 +379,19 @@ impl MessageHandler<PortfolioMessage, PortfolioMessageContext<'_>> for Portfolio
|
|||
PortfolioMessage::NewDocumentWithName { name } => {
|
||||
let mut new_document = DocumentMessageHandler::default();
|
||||
new_document.name = name;
|
||||
responses.add(DocumentMessage::PTZUpdate);
|
||||
let mut new_responses = VecDeque::new();
|
||||
new_responses.add(DocumentMessage::PTZUpdate);
|
||||
|
||||
let document_id = DocumentId(generate_uuid());
|
||||
if self.active_document().is_some() {
|
||||
responses.add(BroadcastEvent::ToolAbort);
|
||||
responses.add(NavigationMessage::CanvasPan { delta: (0., 0.).into() });
|
||||
new_responses.add(BroadcastEvent::ToolAbort);
|
||||
new_responses.add(NavigationMessage::CanvasPan { delta: (0., 0.).into() });
|
||||
}
|
||||
|
||||
self.load_document(new_document, document_id, responses, false);
|
||||
responses.add(PortfolioMessage::SelectDocument { document_id });
|
||||
self.load_document(new_document, document_id, &mut new_responses, false);
|
||||
new_responses.add(PortfolioMessage::SelectDocument { document_id });
|
||||
new_responses.extend(responses.drain(..));
|
||||
*responses = new_responses;
|
||||
}
|
||||
PortfolioMessage::NextDocument => {
|
||||
if let Some(active_document_id) = self.active_document_id {
|
||||
|
@ -899,7 +903,7 @@ impl MessageHandler<PortfolioMessage, PortfolioMessageContext<'_>> for Portfolio
|
|||
transparent_background,
|
||||
..Default::default()
|
||||
};
|
||||
let result = self.executor.submit_document_export(document, export_config);
|
||||
let result = self.executor.submit_document_export(document, self.active_document_id.unwrap(), export_config);
|
||||
|
||||
if let Err(description) = result {
|
||||
responses.add(DialogMessage::DisplayDialogError {
|
||||
|
@ -917,6 +921,7 @@ impl MessageHandler<PortfolioMessage, PortfolioMessageContext<'_>> for Portfolio
|
|||
let inspect_node = self.inspect_node_id();
|
||||
let result = self.executor.submit_node_graph_evaluation(
|
||||
self.documents.get_mut(&document_id).expect("Tried to render non-existent document"),
|
||||
document_id,
|
||||
ipp.viewport_bounds.size().as_uvec2(),
|
||||
timing_information,
|
||||
inspect_node,
|
||||
|
@ -930,7 +935,7 @@ impl MessageHandler<PortfolioMessage, PortfolioMessageContext<'_>> for Portfolio
|
|||
description,
|
||||
});
|
||||
}
|
||||
Ok(message) => responses.add(message),
|
||||
Ok(message) => responses.add_front(message),
|
||||
}
|
||||
}
|
||||
PortfolioMessage::ToggleRulers => {
|
||||
|
|
|
@ -251,12 +251,8 @@ impl Fsm for FreehandToolFsmState {
|
|||
let nodes = vec![(NodeId(0), node)];
|
||||
|
||||
let layer = graph_modification_utils::new_custom(NodeId::new(), nodes, parent, responses);
|
||||
let defered_responses = &mut VecDeque::new();
|
||||
tool_options.fill.apply_fill(layer, defered_responses);
|
||||
tool_options.stroke.apply_stroke(tool_data.weight, layer, defered_responses);
|
||||
responses.add(DeferMessage::AfterGraphRun {
|
||||
messages: defered_responses.drain(..).collect(),
|
||||
});
|
||||
tool_options.fill.apply_fill(layer, responses);
|
||||
tool_options.stroke.apply_stroke(tool_data.weight, layer, responses);
|
||||
tool_data.layer = Some(layer);
|
||||
|
||||
FreehandToolFsmState::Drawing
|
||||
|
|
|
@ -706,6 +706,7 @@ impl Fsm for ShapeToolFsmState {
|
|||
responses.add(DeferMessage::AfterGraphRun {
|
||||
messages: defered_responses.drain(..).collect(),
|
||||
});
|
||||
responses.add(NodeGraphMessage::RunDocumentGraph);
|
||||
|
||||
ShapeToolFsmState::Drawing(tool_data.current_shape)
|
||||
}
|
||||
|
|
|
@ -63,6 +63,7 @@ pub struct NodeGraphExecutor {
|
|||
#[derive(Debug, Clone)]
|
||||
struct ExecutionContext {
|
||||
export_config: Option<ExportConfig>,
|
||||
document_id: DocumentId,
|
||||
}
|
||||
|
||||
impl NodeGraphExecutor {
|
||||
|
@ -133,7 +134,13 @@ impl NodeGraphExecutor {
|
|||
}
|
||||
|
||||
/// Adds an evaluate request for whatever current network is cached.
|
||||
pub(crate) fn submit_current_node_graph_evaluation(&mut self, document: &mut DocumentMessageHandler, viewport_resolution: UVec2, time: TimingInformation) -> Result<Message, String> {
|
||||
pub(crate) fn submit_current_node_graph_evaluation(
|
||||
&mut self,
|
||||
document: &mut DocumentMessageHandler,
|
||||
document_id: DocumentId,
|
||||
viewport_resolution: UVec2,
|
||||
time: TimingInformation,
|
||||
) -> Result<Message, String> {
|
||||
let render_config = RenderConfig {
|
||||
viewport: Footprint {
|
||||
transform: document.metadata().document_to_viewport,
|
||||
|
@ -153,7 +160,7 @@ impl NodeGraphExecutor {
|
|||
// Execute the node graph
|
||||
let execution_id = self.queue_execution(render_config);
|
||||
|
||||
self.futures.insert(execution_id, ExecutionContext { export_config: None });
|
||||
self.futures.insert(execution_id, ExecutionContext { export_config: None, document_id });
|
||||
|
||||
Ok(DeferMessage::SetGraphSubmissionIndex(execution_id).into())
|
||||
}
|
||||
|
@ -162,17 +169,18 @@ impl NodeGraphExecutor {
|
|||
pub fn submit_node_graph_evaluation(
|
||||
&mut self,
|
||||
document: &mut DocumentMessageHandler,
|
||||
document_id: DocumentId,
|
||||
viewport_resolution: UVec2,
|
||||
time: TimingInformation,
|
||||
inspect_node: Option<NodeId>,
|
||||
ignore_hash: bool,
|
||||
) -> Result<Message, String> {
|
||||
self.update_node_graph(document, inspect_node, ignore_hash)?;
|
||||
self.submit_current_node_graph_evaluation(document, viewport_resolution, time)
|
||||
self.submit_current_node_graph_evaluation(document, document_id, viewport_resolution, time)
|
||||
}
|
||||
|
||||
/// Evaluates a node graph for export
|
||||
pub fn submit_document_export(&mut self, document: &mut DocumentMessageHandler, mut export_config: ExportConfig) -> Result<(), String> {
|
||||
pub fn submit_document_export(&mut self, document: &mut DocumentMessageHandler, document_id: DocumentId, mut export_config: ExportConfig) -> Result<(), String> {
|
||||
let network = document.network_interface.document_network().clone();
|
||||
|
||||
// Calculate the bounding box of the region to be exported
|
||||
|
@ -204,7 +212,10 @@ impl NodeGraphExecutor {
|
|||
.send(GraphRuntimeRequest::GraphUpdate(GraphUpdate { network, inspect_node: None }))
|
||||
.map_err(|e| e.to_string())?;
|
||||
let execution_id = self.queue_execution(render_config);
|
||||
let execution_context = ExecutionContext { export_config: Some(export_config) };
|
||||
let execution_context = ExecutionContext {
|
||||
export_config: Some(export_config),
|
||||
document_id,
|
||||
};
|
||||
self.futures.insert(execution_id, execution_context);
|
||||
|
||||
Ok(())
|
||||
|
@ -279,7 +290,7 @@ impl NodeGraphExecutor {
|
|||
} else {
|
||||
self.process_node_graph_output(node_graph_output, transform, responses)?
|
||||
}
|
||||
responses.add(DeferMessage::TriggerGraphRun(execution_id));
|
||||
responses.add_front(DeferMessage::TriggerGraphRun(execution_id, execution_context.document_id));
|
||||
|
||||
// Update the spreadsheet on the frontend using the value of the inspect result.
|
||||
if self.old_inspect_node.is_some() {
|
||||
|
|
|
@ -49,7 +49,7 @@ impl EditorTestUtils {
|
|||
};
|
||||
|
||||
let viewport_resolution = glam::UVec2::ONE;
|
||||
if let Err(e) = exector.submit_current_node_graph_evaluation(document, viewport_resolution, Default::default()) {
|
||||
if let Err(e) = exector.submit_current_node_graph_evaluation(document, DocumentId(0), viewport_resolution, Default::default()) {
|
||||
return Err(format!("submit_current_node_graph_evaluation failed\n\n{e}"));
|
||||
}
|
||||
runtime.run().await;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue