Skip to content

Commit 947a131

Browse files
0HyperCubeKeavon
andauthored
Add graph type error diagnostics to the UI (#1535)
* Fontend input types * Fix index of errors / types * Bug fixes, styling improvements, and code review * Improvements to the error box --------- Co-authored-by: Keavon Chambers <[email protected]>
1 parent 96b5d7b commit 947a131

File tree

20 files changed

+567
-171
lines changed

20 files changed

+567
-171
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ pub struct DocumentMessageHandler {
6565
#[serde(default = "default_rulers_visible")]
6666
pub rulers_visible: bool,
6767
#[serde(default = "default_collapsed")]
68-
pub collapsed: Vec<LayerNodeIdentifier>, // TODO: Is this actually used? Maybe or maybe not. Investigate and potentially remove.
68+
pub collapsed: Vec<LayerNodeIdentifier>,
6969
// =============================================
7070
// Fields omitted from the saved document format
7171
// =============================================
@@ -265,7 +265,7 @@ impl MessageHandler<DocumentMessage, DocumentInputs<'_>> for DocumentMessageHand
265265
node_graph_message_handler: &self.node_graph_handler,
266266
executor,
267267
document_name: self.name.as_str(),
268-
document_network: &mut self.network,
268+
document_network: &self.network,
269269
document_metadata: &mut self.metadata,
270270
};
271271
self.properties_panel_message_handler

editor/src/messages/portfolio/document/node_graph/node_graph_message.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
use crate::messages::prelude::*;
2-
32
use graph_craft::document::value::TaggedValue;
43
use graph_craft::document::{DocumentNode, NodeId, NodeInput};
4+
use graph_craft::proto::GraphErrors;
5+
use interpreted_executor::dynamic_executor::ResolvedDocumentNodeTypes;
56

67
#[impl_message(Message, DocumentMessage, NodeGraph)]
78
#[derive(PartialEq, Clone, Debug, serde::Serialize, serde::Deserialize)]
@@ -111,4 +112,10 @@ pub enum NodeGraphMessage {
111112
node_id: NodeId,
112113
},
113114
UpdateNewNodeGraph,
115+
UpdateTypes {
116+
#[serde(skip)]
117+
resolved_types: ResolvedDocumentNodeTypes,
118+
#[serde(skip)]
119+
node_graph_errors: GraphErrors,
120+
},
114121
}

editor/src/messages/portfolio/document/node_graph/node_graph_message_handler.rs

Lines changed: 50 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@ use crate::messages::input_mapper::utility_types::macros::action_keys;
55
use crate::messages::layout::utility_types::widget_prelude::*;
66
use crate::messages::portfolio::document::utility_types::document_metadata::{DocumentMetadata, LayerNodeIdentifier};
77
use crate::messages::prelude::*;
8-
98
use graph_craft::document::value::TaggedValue;
10-
use graph_craft::document::{DocumentNode, NodeId, NodeInput, NodeNetwork, NodeOutput};
9+
use graph_craft::document::{DocumentNode, NodeId, NodeInput, NodeNetwork, NodeOutput, Source};
10+
use graph_craft::proto::GraphErrors;
1111
use graphene_core::*;
12+
use interpreted_executor::dynamic_executor::ResolvedDocumentNodeTypes;
1213
mod document_node_types;
1314
mod node_properties;
1415

@@ -23,22 +24,22 @@ pub enum FrontendGraphDataType {
2324
Raster,
2425
#[serde(rename = "color")]
2526
Color,
26-
#[serde(rename = "number")]
27+
#[serde(rename = "general")]
2728
Text,
2829
#[serde(rename = "vector")]
2930
Subpath,
3031
#[serde(rename = "number")]
3132
Number,
32-
#[serde(rename = "number")]
33+
#[serde(rename = "general")]
3334
Boolean,
3435
/// Refers to the mathematical vector, with direction and magnitude.
35-
#[serde(rename = "vec2")]
36+
#[serde(rename = "number")]
3637
Vector,
37-
#[serde(rename = "graphic")]
38+
#[serde(rename = "raster")]
3839
GraphicGroup,
3940
#[serde(rename = "artboard")]
4041
Artboard,
41-
#[serde(rename = "palette")]
42+
#[serde(rename = "color")]
4243
Palette,
4344
}
4445
impl FrontendGraphDataType {
@@ -65,13 +66,17 @@ pub struct FrontendGraphInput {
6566
#[serde(rename = "dataType")]
6667
data_type: FrontendGraphDataType,
6768
name: String,
69+
#[serde(rename = "resolvedType")]
70+
resolved_type: Option<String>,
6871
}
6972

7073
#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize, specta::Type)]
7174
pub struct FrontendGraphOutput {
7275
#[serde(rename = "dataType")]
7376
data_type: FrontendGraphDataType,
7477
name: String,
78+
#[serde(rename = "resolvedType")]
79+
resolved_type: Option<String>,
7580
}
7681

7782
#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize, specta::Type)]
@@ -92,6 +97,7 @@ pub struct FrontendNode {
9297
pub position: (i32, i32),
9398
pub disabled: bool,
9499
pub previewed: bool,
100+
pub errors: Option<String>,
95101
}
96102

97103
// (link_start, link_end, link_end_input_index)
@@ -124,6 +130,8 @@ impl FrontendNodeType {
124130
#[derive(Debug, Clone, PartialEq)]
125131
pub struct NodeGraphMessageHandler {
126132
pub network: Vec<NodeId>,
133+
pub resolved_types: ResolvedDocumentNodeTypes,
134+
pub node_graph_errors: GraphErrors,
127135
has_selection: bool,
128136
widgets: [LayoutGroup; 2],
129137
}
@@ -144,6 +152,8 @@ impl Default for NodeGraphMessageHandler {
144152

145153
Self {
146154
network: Vec::new(),
155+
resolved_types: ResolvedDocumentNodeTypes::default(),
156+
node_graph_errors: Vec::new(),
147157
has_selection: false,
148158
widgets: [LayoutGroup::Row { widgets: Vec::new() }, LayoutGroup::Row { widgets: right_side_widgets }],
149159
}
@@ -264,7 +274,7 @@ impl NodeGraphMessageHandler {
264274
}
265275
}
266276

267-
fn send_graph(network: &NodeNetwork, graph_view_overlay_open: bool, responses: &mut VecDeque<Message>) {
277+
fn send_graph(&self, network: &NodeNetwork, graph_view_overlay_open: bool, responses: &mut VecDeque<Message>) {
268278
responses.add(PropertiesPanelMessage::Refresh);
269279

270280
if !graph_view_overlay_open {
@@ -298,27 +308,34 @@ impl NodeGraphMessageHandler {
298308

299309
let mut nodes = Vec::new();
300310
for (id, node) in &network.nodes {
311+
let node_path = vec![*id];
301312
// TODO: This should be based on the graph runtime type inference system in order to change the colors of node connectors to match the data type in use
302313
let Some(node_type) = document_node_types::resolve_document_node_type(&node.name) else {
303314
warn!("Node '{}' does not exist in library", node.name);
304315
continue;
305316
};
306317

307318
// Inputs
308-
let mut inputs = node.inputs.iter().zip(node_type.inputs.iter().map(|input_type| FrontendGraphInput {
309-
data_type: input_type.data_type,
310-
name: input_type.name.to_string(),
319+
let mut inputs = node.inputs.iter().zip(node_type.inputs.iter().enumerate().map(|(index, input_type)| {
320+
let index = node.inputs.iter().take(index).filter(|input| input.is_exposed()).count();
321+
FrontendGraphInput {
322+
data_type: input_type.data_type,
323+
name: input_type.name.to_string(),
324+
resolved_type: self.resolved_types.inputs.get(&Source { node: node_path.clone(), index }).map(|input| format!("{input:?}")),
325+
}
311326
}));
312327
let primary_input = inputs.next().filter(|(input, _)| input.is_exposed()).map(|(_, input_type)| input_type);
313328
let exposed_inputs = inputs.filter(|(input, _)| input.is_exposed()).map(|(_, input_type)| input_type).collect();
314329

315330
// Outputs
316-
let mut outputs = node_type.outputs.iter().map(|output_type| FrontendGraphOutput {
331+
let mut outputs = node_type.outputs.iter().enumerate().map(|(index, output_type)| FrontendGraphOutput {
317332
data_type: output_type.data_type,
318333
name: output_type.name.to_string(),
334+
resolved_type: self.resolved_types.outputs.get(&Source { node: node_path.clone(), index }).map(|output| format!("{output:?}")),
319335
});
320336
let primary_output = if node.has_primary_output { outputs.next() } else { None };
321337

338+
let errors = self.node_graph_errors.iter().find(|error| error.node_path.starts_with(&node_path)).map(|error| error.error.clone());
322339
nodes.push(FrontendNode {
323340
is_layer: node.is_layer(),
324341
id: *id,
@@ -331,6 +348,7 @@ impl NodeGraphMessageHandler {
331348
position: node.metadata.position.into(),
332349
previewed: network.outputs_contain(*id),
333350
disabled: network.disabled.contains(id),
351+
errors: errors.map(|e| format!("{e:?}")),
334352
})
335353
}
336354
responses.add(FrontendMessage::UpdateNodeGraph { nodes, links });
@@ -607,7 +625,7 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
607625
}
608626
}
609627
if let Some(network) = document_network.nested_network(&self.network) {
610-
Self::send_graph(network, graph_view_overlay_open, responses);
628+
self.send_graph(network, graph_view_overlay_open, responses);
611629
}
612630
self.update_selected(document_network, metadata, responses);
613631
}
@@ -635,7 +653,7 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
635653
responses.add(NodeGraphMessage::InsertNode { node_id, document_node });
636654
}
637655

638-
Self::send_graph(network, graph_view_overlay_open, responses);
656+
self.send_graph(network, graph_view_overlay_open, responses);
639657
self.update_selected(document_network, metadata, responses);
640658
responses.add(NodeGraphMessage::SendGraph { should_rerender: false });
641659
}
@@ -648,7 +666,7 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
648666
self.network.pop();
649667
}
650668
if let Some(network) = document_network.nested_network(&self.network) {
651-
Self::send_graph(network, graph_view_overlay_open, responses);
669+
self.send_graph(network, graph_view_overlay_open, responses);
652670
}
653671
self.update_selected(document_network, metadata, responses);
654672
}
@@ -698,7 +716,7 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
698716
node.metadata.position += IVec2::new(displacement_x, displacement_y)
699717
}
700718
}
701-
Self::send_graph(network, graph_view_overlay_open, responses);
719+
self.send_graph(network, graph_view_overlay_open, responses);
702720
}
703721
NodeGraphMessage::PasteNodes { serialized_nodes } => {
704722
let Some(network) = document_network.nested_network(&self.network) else {
@@ -763,7 +781,7 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
763781
}
764782
NodeGraphMessage::SendGraph { should_rerender } => {
765783
if let Some(network) = document_network.nested_network(&self.network) {
766-
Self::send_graph(network, graph_view_overlay_open, responses);
784+
self.send_graph(network, graph_view_overlay_open, responses);
767785
if should_rerender {
768786
responses.add(NodeGraphMessage::RunDocumentGraph);
769787
}
@@ -890,7 +908,7 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
890908
} else if !network.inputs.contains(&node_id) && !network.original_outputs().iter().any(|output| output.node_id == node_id) {
891909
network.disabled.push(node_id);
892910
}
893-
Self::send_graph(network, graph_view_overlay_open, responses);
911+
self.send_graph(network, graph_view_overlay_open, responses);
894912

895913
// Only generate node graph if one of the selected nodes is connected to the output
896914
if network.connected_to_output(node_id) {
@@ -926,7 +944,7 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
926944
} else {
927945
return;
928946
}
929-
Self::send_graph(network, graph_view_overlay_open, responses);
947+
self.send_graph(network, graph_view_overlay_open, responses);
930948
}
931949
self.update_selection_action_buttons(document_network, metadata, responses);
932950
responses.add(NodeGraphMessage::RunDocumentGraph);
@@ -936,13 +954,25 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
936954
metadata.clear_selected_nodes();
937955
responses.add(BroadcastEvent::SelectionChanged);
938956

939-
Self::send_graph(network, graph_view_overlay_open, responses);
957+
self.send_graph(network, graph_view_overlay_open, responses);
940958

941959
let node_types = document_node_types::collect_node_types();
942960
responses.add(FrontendMessage::UpdateNodeTypes { node_types });
943961
}
944962
self.update_selected(document_network, metadata, responses);
945963
}
964+
NodeGraphMessage::UpdateTypes { resolved_types, node_graph_errors } => {
965+
let changed = self.resolved_types != resolved_types || self.node_graph_errors != node_graph_errors;
966+
967+
self.resolved_types = resolved_types;
968+
self.node_graph_errors = node_graph_errors;
969+
970+
if changed {
971+
if let Some(network) = document_network.nested_network(&self.network) {
972+
self.send_graph(network, graph_view_overlay_open, responses)
973+
}
974+
}
975+
}
946976
}
947977
self.has_selection = metadata.has_selected_nodes();
948978
}

editor/src/messages/portfolio/document/node_graph/node_graph_message_handler/node_properties.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ fn vec2_widget(document_node: &DocumentNode, node_id: NodeId, index: usize, name
214214
}
215215

216216
fn vec_f32_input(document_node: &DocumentNode, node_id: NodeId, index: usize, name: &str, text_props: TextInput, blank_assist: bool) -> Vec<WidgetHolder> {
217-
let mut widgets = start_widgets(document_node, node_id, index, name, FrontendGraphDataType::Color, blank_assist);
217+
let mut widgets = start_widgets(document_node, node_id, index, name, FrontendGraphDataType::Vector, blank_assist);
218218

219219
let from_string = |string: &str| {
220220
string
@@ -243,7 +243,7 @@ fn vec_f32_input(document_node: &DocumentNode, node_id: NodeId, index: usize, na
243243
}
244244

245245
fn vec_dvec2_input(document_node: &DocumentNode, node_id: NodeId, index: usize, name: &str, text_props: TextInput, blank_assist: bool) -> Vec<WidgetHolder> {
246-
let mut widgets = start_widgets(document_node, node_id, index, name, FrontendGraphDataType::Color, blank_assist);
246+
let mut widgets = start_widgets(document_node, node_id, index, name, FrontendGraphDataType::Vector, blank_assist);
247247

248248
let from_string = |string: &str| {
249249
string
@@ -739,7 +739,7 @@ fn gradient_positions(rows: &mut Vec<LayoutGroup>, document_node: &DocumentNode,
739739
}
740740

741741
fn color_widget(document_node: &DocumentNode, node_id: NodeId, index: usize, name: &str, color_props: ColorButton, blank_assist: bool) -> LayoutGroup {
742-
let mut widgets = start_widgets(document_node, node_id, index, name, FrontendGraphDataType::Number, blank_assist);
742+
let mut widgets = start_widgets(document_node, node_id, index, name, FrontendGraphDataType::Color, blank_assist);
743743

744744
if let NodeInput::Value { tagged_value, exposed: false } = &document_node.inputs[index] {
745745
if let &TaggedValue::Color(x) = tagged_value {
@@ -1452,9 +1452,7 @@ pub fn transform_properties(document_node: &DocumentNode, node_id: NodeId, _cont
14521452

14531453
let scale = vec2_widget(document_node, node_id, 3, "Scale", "W", "H", "x", None, add_blank_assist);
14541454

1455-
let vector_data = start_widgets(document_node, node_id, 0, "Data", FrontendGraphDataType::Vector, false);
1456-
let vector_data = LayoutGroup::Row { widgets: vector_data };
1457-
vec![vector_data, translation, rotation, scale]
1455+
vec![translation, rotation, scale]
14581456
}
14591457

14601458
pub fn node_section_font(document_node: &DocumentNode, node_id: NodeId, _context: &mut NodePropertiesContext) -> Vec<LayoutGroup> {

editor/src/messages/portfolio/document/properties_panel/utility_types.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use graph_craft::document::NodeNetwork;
66

77
pub struct PropertiesPanelMessageHandlerData<'a> {
88
pub document_name: &'a str,
9-
pub document_network: &'a mut NodeNetwork,
9+
pub document_network: &'a NodeNetwork,
1010
pub document_metadata: &'a mut DocumentMetadata,
1111
pub node_graph_message_handler: &'a NodeGraphMessageHandler,
1212
pub executor: &'a mut NodeGraphExecutor,

0 commit comments

Comments
 (0)