Add handler for deferred execution of messages (#2951)

* Add Handler for defered execution of messages

* Cleanup

* Track graph execution id to associate messages with their corresponding execution id

* Rename ViewportReady -> NavigationReady

* Defer layer deselection
This commit is contained in:
Dennis Kobert
2025-07-29 01:57:11 +02:00
committed by GitHub
parent 2247dd9818
commit 35ab266bbb
21 changed files with 182 additions and 131 deletions
@@ -153,8 +153,9 @@ pub fn merge_layers(document: &DocumentMessageHandler, first_layer: LayerNodeIde
});
responses.add(NodeGraphMessage::RunDocumentGraph);
responses.add(Message::StartBuffer);
responses.add(PenToolMessage::RecalculateLatestPointsPosition);
responses.add(DeferMessage::AfterGraphRun {
messages: vec![PenToolMessage::RecalculateLatestPointsPosition.into()],
});
}
/// Merge the `first_endpoint` with `second_endpoint`.
@@ -383,8 +383,9 @@ impl Fsm for BrushToolFsmState {
else {
new_brush_layer(document, responses);
responses.add(NodeGraphMessage::RunDocumentGraph);
responses.add(Message::StartBuffer);
responses.add(BrushToolMessage::DragStart);
responses.add(DeferMessage::AfterGraphRun {
messages: vec![BrushToolMessage::DragStart.into()],
});
BrushToolFsmState::Ready
}
}
@@ -251,9 +251,12 @@ impl Fsm for FreehandToolFsmState {
let nodes = vec![(NodeId(0), node)];
let layer = graph_modification_utils::new_custom(NodeId::new(), nodes, parent, responses);
responses.add(Message::StartBuffer);
tool_options.fill.apply_fill(layer, responses);
tool_options.stroke.apply_stroke(tool_data.weight, layer, 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_data.layer = Some(layer);
FreehandToolFsmState::Drawing
@@ -1257,10 +1257,10 @@ impl PenToolData {
self.prior_segments = None;
responses.add(NodeGraphMessage::SelectedNodesSet { nodes: vec![layer.to_node()] });
// This causes the following message to be run only after the next graph evaluation runs and the transforms are updated
responses.add(Message::StartBuffer);
// It is necessary to defer this until the transform of the layer can be accurately computed (quite hacky)
responses.add(PenToolMessage::AddPointLayerPosition { layer, viewport });
responses.add(DeferMessage::AfterGraphRun {
messages: vec![PenToolMessage::AddPointLayerPosition { layer, viewport }.into()],
});
}
/// Perform extension of an existing path
@@ -1721,9 +1721,9 @@ impl Fsm for PenToolFsmState {
let next_point = tool_data.next_point;
let start = latest_point.id;
if let Some(layer) = layer {
let mut vector_data = document.network_interface.compute_modified_vector(layer).unwrap();
if let Some(layer) = layer
&& let Some(mut vector_data) = document.network_interface.compute_modified_vector(layer)
{
let closest_point = vector_data.extendable_points(preferences.vector_meshes).filter(|&id| id != start).find(|&id| {
vector_data.point_domain.position_from_id(id).map_or(false, |pos| {
let dist_sq = transform.transform_point2(pos).distance_squared(transform.transform_point2(next_point));
@@ -624,29 +624,33 @@ impl Fsm for ShapeToolFsmState {
let nodes = vec![(NodeId(0), node)];
let layer = graph_modification_utils::new_custom(NodeId::new(), nodes, document.new_layer_bounding_artboard(input), responses);
responses.add(Message::StartBuffer);
let defered_responses = &mut VecDeque::new();
match tool_data.current_shape {
ShapeType::Ellipse | ShapeType::Rectangle | ShapeType::Arc | ShapeType::Polygon | ShapeType::Star => {
responses.add(GraphOperationMessage::TransformSet {
defered_responses.add(GraphOperationMessage::TransformSet {
layer,
transform: DAffine2::from_scale_angle_translation(DVec2::ONE, 0., input.mouse.position),
transform_in: TransformIn::Viewport,
skip_rerender: false,
});
tool_options.fill.apply_fill(layer, responses);
tool_options.fill.apply_fill(layer, defered_responses);
}
ShapeType::Line => {
tool_data.line_data.weight = tool_options.line_weight;
tool_data.line_data.editing_layer = Some(layer);
}
}
tool_options.stroke.apply_stroke(tool_options.line_weight, layer, responses);
tool_options.stroke.apply_stroke(tool_options.line_weight, layer, defered_responses);
tool_options.stroke.apply_stroke(tool_options.line_weight, layer, responses);
tool_options.stroke.apply_stroke(tool_options.line_weight, layer, defered_responses);
tool_data.data.layer = Some(layer);
responses.add(DeferMessage::AfterGraphRun {
messages: defered_responses.drain(..).collect(),
});
ShapeToolFsmState::Drawing(tool_data.current_shape)
}
(ShapeToolFsmState::Drawing(shape), ShapeToolMessage::PointerMove(modifier)) => {
@@ -360,8 +360,6 @@ impl Fsm for SplineToolFsmState {
tool_options.stroke.apply_stroke(tool_data.weight, layer, responses);
tool_data.current_layer = Some(layer);
responses.add(Message::StartBuffer);
SplineToolFsmState::Drawing
}
(SplineToolFsmState::Drawing, SplineToolMessage::DragStop) => {
@@ -385,20 +385,25 @@ impl TextToolData {
parent: document.new_layer_parent(true),
insert_index: 0,
});
responses.add(Message::StartBuffer);
responses.add(GraphOperationMessage::FillSet {
layer: self.layer,
fill: if editing_text.color.is_some() {
Fill::Solid(editing_text.color.unwrap().to_gamma_srgb())
} else {
Fill::None
},
});
responses.add(GraphOperationMessage::TransformSet {
layer: self.layer,
transform: editing_text.transform,
transform_in: TransformIn::Viewport,
skip_rerender: true,
responses.add(DeferMessage::AfterGraphRun {
messages: vec![
GraphOperationMessage::FillSet {
layer: self.layer,
fill: if editing_text.color.is_some() {
Fill::Solid(editing_text.color.unwrap().to_gamma_srgb())
} else {
Fill::None
},
}
.into(),
GraphOperationMessage::TransformSet {
layer: self.layer,
transform: editing_text.transform,
transform_in: TransformIn::Viewport,
skip_rerender: true,
}
.into(),
],
});
self.editing_text = Some(editing_text);