Skip to content

Typing of disconnected node outputs #4276

Description

@0HyperCube

When a node is disconnected from the graph output, the type hints for the output are not available. This occurs even if the output type is completely unambiguous such as the « tangent on path » node. This makes it rather frustrating to make graphs since nodes are often disconnected when building a graph.

diff --git a/editor/src/messages/portfolio/document/utility_types/network_interface/resolved_types.rs b/editor/src/messages/portfolio/document/utility_types/network_interface/resolved_types.rs
index 685d32e59..8f80c3208 100644
--- a/editor/src/messages/portfolio/document/utility_types/network_interface/resolved_types.rs
+++ b/editor/src/messages/portfolio/document/utility_types/network_interface/resolved_types.rs
@@ -337,12 +337,29 @@ impl NodeNetworkInterface {
 				let Some(implementation) = self.implementation(node_id, network_path) else {
 					return TypeSource::Error("Could not get implementation");
 				};
+				info!("Got node");
 				match implementation {
 					DocumentNodeImplementation::Network(_) => self.input_type(&InputConnector::Export(*output_index), &[network_path, &[*node_id]].concat()),
-					DocumentNodeImplementation::ProtoNode(_) => match self.resolved_types.types.get(&[network_path, &[*node_id]].concat()) {
-						Some(resolved_type) => TypeSource::Compiled(resolved_type.output.clone()),
-						None => TypeSource::Unknown,
-					},
+					DocumentNodeImplementation::ProtoNode(proto_node_identifier) => {
+						if let Some(resolved_type) = self.resolved_types.types.get(&[network_path, &[*node_id]].concat()) {
+							TypeSource::Compiled(resolved_type.output.clone())
+						} else {
+							let Some(implementations) = NODE_REGISTRY.get(proto_node_identifier) else {
+								error!("Protonode {proto_node_identifier:?} not found in registry in output_type");
+								return TypeSource::Error("no protonode");
+							};
+
+							let mut possible_outputs = implementations.keys().map(|io| &io.return_value).collect::<Vec<_>>();
+							possible_outputs.dedup();
+							// Only type unambiguous outputs (just one possible type)
+							if let Some([result]) = possible_outputs.as_array() {
+								TypeSource::Compiled((*result).clone())
+							} else {
+								info!("Ambiguous outputs {possible_outputs:#?}");
+								TypeSource::Unknown
+							}
+						}
+					}
 					DocumentNodeImplementation::Extract => TypeSource::Compiled(concrete!(())),
 				}
 			}

It should be possible to further filter the possible output types based on the known input types.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions