From e10d56c261f2955dc863bf08d74e86e229d9402d Mon Sep 17 00:00:00 2001 From: Dennis Kobert Date: Wed, 9 Sep 2026 15:39:37 +0000 Subject: [PATCH] Box the largest message and update payloads --- .../document/node_graph/node_graph_message.rs | 3 +- .../node_graph/node_graph_message_handler.rs | 1 + .../document/node_graph/node_properties.rs | 33 +++++++++++-------- .../utility_types/network_interface.rs | 6 ++-- .../messages/portfolio/portfolio_message.rs | 2 +- .../portfolio/portfolio_message_handler.rs | 4 +-- .../graph_modification_utils.rs | 6 ++-- .../tool/tool_messages/gradient_tool.rs | 12 +++---- .../messages/tool/tool_messages/text_tool.rs | 6 ++-- editor/src/node_graph_executor.rs | 4 +-- editor/src/node_graph_executor/runtime.rs | 2 +- node-graph/node-macro/src/parsing.rs | 3 ++ 12 files changed, 46 insertions(+), 36 deletions(-) diff --git a/editor/src/messages/portfolio/document/node_graph/node_graph_message.rs b/editor/src/messages/portfolio/document/node_graph/node_graph_message.rs index 011065fd78..ad548e4c11 100644 --- a/editor/src/messages/portfolio/document/node_graph/node_graph_message.rs +++ b/editor/src/messages/portfolio/document/node_graph/node_graph_message.rs @@ -157,7 +157,8 @@ pub enum NodeGraphMessage { SetInputValue { node_id: NodeId, input_index: usize, - value: TaggedValue, + // Boxed to keep the whole editor message tree small; `TaggedValue` alone is 568 bytes + value: Box, }, SetInput { input_connector: InputConnector, diff --git a/editor/src/messages/portfolio/document/node_graph/node_graph_message_handler.rs b/editor/src/messages/portfolio/document/node_graph/node_graph_message_handler.rs index 52fb20a17f..644e4ac37c 100644 --- a/editor/src/messages/portfolio/document/node_graph/node_graph_message_handler.rs +++ b/editor/src/messages/portfolio/document/node_graph/node_graph_message_handler.rs @@ -1765,6 +1765,7 @@ impl<'a> MessageHandler> for NodeG NodeGraphMessage::SetInputValue { node_id, input_index, value } => { use graphene_std::vector::generator_nodes::*; + let value = *value; let reference = network_interface.reference(&node_id, selection_network_path); let is_text_node = reference.as_ref().is_some_and(|r| *r == DefinitionIdentifier::ProtoNode(graphene_std::text::text::IDENTIFIER)); let is_stroke_node = reference.as_ref().is_some_and(|r| *r == DefinitionIdentifier::ProtoNode(graphene_std::vector::stroke::IDENTIFIER)); diff --git a/editor/src/messages/portfolio/document/node_graph/node_properties.rs b/editor/src/messages/portfolio/document/node_graph/node_properties.rs index 59d101120f..a8e2c7a491 100644 --- a/editor/src/messages/portfolio/document/node_graph/node_properties.rs +++ b/editor/src/messages/portfolio/document/node_graph/node_properties.rs @@ -44,7 +44,12 @@ pub(crate) fn string_properties(text: &str) -> Vec { fn optionally_update_value(value: impl Fn(&T) -> Option + 'static + Send + Sync, node_id: NodeId, input_index: usize) -> impl Fn(&T) -> Message + 'static + Send + Sync { move |input_value: &T| match value(input_value) { - Some(value) => NodeGraphMessage::SetInputValue { node_id, input_index, value }.into(), + Some(value) => NodeGraphMessage::SetInputValue { + node_id, + input_index, + value: Box::new(value), + } + .into(), None => Message::NoOp, } } @@ -867,7 +872,7 @@ pub fn font_inputs(parameter_widgets_info: ParameterWidgetsInfo) -> (Vec), Node, // No transient click targets are stored exclusively for nodes } diff --git a/editor/src/messages/portfolio/portfolio_message.rs b/editor/src/messages/portfolio/portfolio_message.rs index 8edca5950d..2a0b5fb083 100644 --- a/editor/src/messages/portfolio/portfolio_message.rs +++ b/editor/src/messages/portfolio/portfolio_message.rs @@ -52,7 +52,7 @@ pub enum PortfolioMessage { reopened: bool, #[serde(skip, default)] #[derivative(Debug = "ignore", PartialEq = "ignore", Clone(clone_with = "clone_to_none"))] - gdd: Option, + gdd: Option>, }, DestroyAllDocuments, EditorPreferences, diff --git a/editor/src/messages/portfolio/portfolio_message_handler.rs b/editor/src/messages/portfolio/portfolio_message_handler.rs index 5dbd6fb55c..4116b7cdee 100644 --- a/editor/src/messages/portfolio/portfolio_message_handler.rs +++ b/editor/src/messages/portfolio/portfolio_message_handler.rs @@ -305,7 +305,7 @@ impl MessageHandler> for Portfolio // Document was closed before its working copy finished mounting. return; }; - document.set_storage(gdd); + document.set_storage(gdd.map(|gdd| *gdd)); if !reopened { document.commit_storage_snapshot(&resource_storage.resources_mut(), preferences.validate_storage_round_trip); document.retire_storage_interaction(); @@ -1914,7 +1914,7 @@ impl PortfolioMessageHandler { Message::Portfolio(PortfolioMessage::DocumentStorageMounted { document_id, reopened, - gdd: Some(gdd), + gdd: Some(Box::new(gdd)), }) }; future.into() diff --git a/editor/src/messages/tool/common_functionality/graph_modification_utils.rs b/editor/src/messages/tool/common_functionality/graph_modification_utils.rs index c1813bb6e3..0f58b12710 100644 --- a/editor/src/messages/tool/common_functionality/graph_modification_utils.rs +++ b/editor/src/messages/tool/common_functionality/graph_modification_utils.rs @@ -613,7 +613,7 @@ pub fn set_stroke_weight_for_selected_layers(weight: f64, document: &DocumentMes for layer in layers { if let Some(node_id) = get_stroke_id(layer, &document.network_interface) { let input_index = graphene_std::vector::stroke::WeightInput::INDEX; - let value = TaggedValue::F64(weight); + let value = Box::new(TaggedValue::F64(weight)); responses.add(NodeGraphMessage::SetInputValue { node_id, input_index, value }); } else if weight > 0. { let color = Some(Color::BLACK); @@ -825,7 +825,7 @@ pub fn set_stroke_color_for_selected_layers(color: Option, weight: f64, d for layer in layers { if let Some(node_id) = get_stroke_id(layer, &document.network_interface) { let input_index = graphene_std::vector::stroke::PaintInput::INDEX; - let value = TaggedValue::Color(color); + let value = Box::new(TaggedValue::Color(color)); responses.add(NodeGraphMessage::SetInputValue { node_id, input_index, value }); } else { let stroke = graphene_std::vector::style::Stroke::new(weight); @@ -896,7 +896,7 @@ pub fn set_proto_node_input_for_selected_layers( responses.add(NodeGraphMessage::SetInputValue { node_id, input_index, - value: value.clone(), + value: Box::new(value.clone()), }); } } diff --git a/editor/src/messages/tool/tool_messages/gradient_tool.rs b/editor/src/messages/tool/tool_messages/gradient_tool.rs index d8c02632dd..c5a1749e74 100644 --- a/editor/src/messages/tool/tool_messages/gradient_tool.rs +++ b/editor/src/messages/tool/tool_messages/gradient_tool.rs @@ -2146,7 +2146,7 @@ mod test_gradient { .handle_message(NodeGraphMessage::SetInputValue { node_id: gradient_node_id, input_index: 1, - value: TaggedValue::Gradient(GradientStops::new([ + value: Box::new(TaggedValue::Gradient(GradientStops::new([ GradientStop { position: 0., midpoint: 0.5, @@ -2157,7 +2157,7 @@ mod test_gradient { midpoint: 0.5, color: Color::BLUE, }, - ])), + ]))), }) .await; @@ -2183,7 +2183,7 @@ mod test_gradient { .handle_message(NodeGraphMessage::SetInputValue { node_id: gradient_node_id, input_index: 1, - value: TaggedValue::Gradient(GradientStops::new([ + value: Box::new(TaggedValue::Gradient(GradientStops::new([ GradientStop { position: 0., midpoint: 0.5, @@ -2194,7 +2194,7 @@ mod test_gradient { midpoint: 0.5, color: Color::BLUE, }, - ])), + ]))), }) .await; @@ -2826,7 +2826,7 @@ mod test_gradient { .handle_message(NodeGraphMessage::SetInputValue { node_id: gradient_value_id, input_index: 1, - value: TaggedValue::Gradient(GradientStops::new([ + value: Box::new(TaggedValue::Gradient(GradientStops::new([ GradientStop { position: 0., midpoint: 0.5, @@ -2837,7 +2837,7 @@ mod test_gradient { midpoint: 0.5, color: Color::BLUE, }, - ])), + ]))), }) .await; diff --git a/editor/src/messages/tool/tool_messages/text_tool.rs b/editor/src/messages/tool/tool_messages/text_tool.rs index d88c8c29fc..e484df54dc 100644 --- a/editor/src/messages/tool/tool_messages/text_tool.rs +++ b/editor/src/messages/tool/tool_messages/text_tool.rs @@ -118,7 +118,7 @@ fn create_text_widgets(tool: &TextTool, font_catalog: &FontCatalog, document: &D NodeGraphMessage::SetInputValue { node_id, input_index: graphene_std::text::text::FontInput::INDEX, - value: TaggedValue::Resource(resource_id), + value: Box::new(TaggedValue::Resource(resource_id)), } .into(), ]), @@ -349,7 +349,7 @@ impl<'a> MessageHandler> for Text responses.add(NodeGraphMessage::SetInputValue { node_id, input_index: graphene_std::text::text::SizeInput::INDEX, - value: TaggedValue::F64(font_size), + value: Box::new(TaggedValue::F64(font_size)), }); } } @@ -364,7 +364,7 @@ impl<'a> MessageHandler> for Text responses.add(NodeGraphMessage::SetInputValue { node_id, input_index: graphene_std::text::text::AlignInput::INDEX, - value: TaggedValue::TextAlign(align), + value: Box::new(TaggedValue::TextAlign(align)), }); } } diff --git a/editor/src/node_graph_executor.rs b/editor/src/node_graph_executor.rs index 480b328ba8..8907e80c90 100644 --- a/editor/src/node_graph_executor.rs +++ b/editor/src/node_graph_executor.rs @@ -47,7 +47,7 @@ pub struct CompilationResponse { } pub enum NodeGraphUpdate { - ExecutionResponse(ExecutionResponse), + ExecutionResponse(Box), CompilationResponse(CompilationResponse), EyedropperPreview(Raster), NodeGraphUpdateMessage(NodeGraphUpdateMessage), @@ -368,7 +368,7 @@ impl NodeGraphExecutor { responses: existing_responses, vector_modify, inspect_result, - } = execution_response; + } = *execution_response; while let Some(&(queued_execution_id, _)) = self.futures.front() { if queued_execution_id < execution_id { diff --git a/editor/src/node_graph_executor/runtime.rs b/editor/src/node_graph_executor/runtime.rs index a8e1880c08..2c1621da89 100644 --- a/editor/src/node_graph_executor/runtime.rs +++ b/editor/src/node_graph_executor/runtime.rs @@ -104,7 +104,7 @@ impl InternalNodeGraphUpdateSender { } fn send_execution_response(&self, response: ExecutionResponse) { - self.0.send(NodeGraphUpdate::ExecutionResponse(response)).expect("Failed to send response") + self.0.send(NodeGraphUpdate::ExecutionResponse(Box::new(response))).expect("Failed to send response") } fn send_eyedropper_preview(&self, raster: Raster) { diff --git a/node-graph/node-macro/src/parsing.rs b/node-graph/node-macro/src/parsing.rs index f6c6259dc9..2b74ecdc50 100644 --- a/node-graph/node-macro/src/parsing.rs +++ b/node-graph/node-macro/src/parsing.rs @@ -258,6 +258,9 @@ pub struct ParsedField { pub(crate) attribute_reads: Vec, } +// Both variants are large parsed-syntax payloads (888/672 bytes), so boxing one still leaves the other large while forcing a +// deref on every pattern match across codegen; this is built once per node at compile time, never on a hot path +#[allow(clippy::large_enum_variant)] #[derive(Clone, Debug)] pub enum ParsedFieldType { Regular(RegularParsedField),