From 7ecd1d0054932165c184c3b371d8bef77f1c1935 Mon Sep 17 00:00:00 2001 From: Adam Date: Sun, 6 Jul 2025 13:23:24 -0700 Subject: [PATCH] Migrate pass through and value node to identity implementation --- .../node_graph/document_node_definitions.rs | 16 +++++--- .../messages/portfolio/document_migration.rs | 25 ++---------- node-graph/gcore/src/ops.rs | 7 ---- node-graph/gcore/src/value.rs | 38 +++++++++---------- node-graph/graph-craft/src/document.rs | 30 ++++++++++++--- node-graph/graph-craft/src/proto.rs | 2 +- node-graph/gstd/src/any.rs | 9 ++--- node-graph/interpreted-executor/src/lib.rs | 6 +++ .../interpreted-executor/src/node_registry.rs | 6 +-- node-graph/interpreted-executor/src/util.rs | 6 +++ node-graph/preprocessor/src/lib.rs | 6 +++ 11 files changed, 83 insertions(+), 68 deletions(-) diff --git a/editor/src/messages/portfolio/document/node_graph/document_node_definitions.rs b/editor/src/messages/portfolio/document/node_graph/document_node_definitions.rs index 900bd3a6df..5bed5d0faa 100644 --- a/editor/src/messages/portfolio/document/node_graph/document_node_definitions.rs +++ b/editor/src/messages/portfolio/document/node_graph/document_node_definitions.rs @@ -85,11 +85,17 @@ fn static_nodes() -> Vec { let custom = vec![ // TODO: Auto-generate this from its proto node macro DocumentNodeDefinition { - identifier: "Identity", + identifier: "Pass Through", category: "General", node_template: NodeTemplate { document_node: DocumentNode { +<<<<<<< HEAD implementation: DocumentNodeImplementation::ProtoNode(ops::identity::IDENTIFIER), +||||||| parent of 8e045313 (Migrate pass through and value node to identity implementation) + implementation: DocumentNodeImplementation::proto("graphene_core::ops::IdentityNode"), +======= + implementation: DocumentNodeImplementation::proto("graphene_std::any::IdentityNode"), +>>>>>>> 8e045313 (Migrate pass through and value node to identity implementation) inputs: vec![NodeInput::value(TaggedValue::None, true)], ..Default::default() }, @@ -100,14 +106,14 @@ fn static_nodes() -> Vec { }, }, description: Cow::Borrowed("Passes-through the input value without changing it. This is useful for rerouting wires for organization purposes."), - properties: Some("identity_properties"), + properties: Some("pass_through_properties"), }, DocumentNodeDefinition { identifier: "Value", category: "General", node_template: NodeTemplate { document_node: DocumentNode { - implementation: DocumentNodeImplementation::proto("graphene_core::any::ValueNode"), + implementation: DocumentNodeImplementation::proto("graphene_std::any::IdentityNode"), manual_composition: Some(generic!(T)), inputs: vec![NodeInput::value(TaggedValue::None, false)], ..Default::default() @@ -1918,8 +1924,8 @@ fn static_node_properties() -> NodeProperties { map.insert("grid_properties".to_string(), Box::new(node_properties::grid_properties)); map.insert("sample_polyline_properties".to_string(), Box::new(node_properties::sample_polyline_properties)); map.insert( - "identity_properties".to_string(), - Box::new(|_node_id, _context| node_properties::string_properties("The identity node passes its data through.")), + "pass_through_properties".to_string(), + Box::new(|_node_id, _context| node_properties::string_properties("The Pass Through node can be used to organize wires.")), ); map.insert( "monitor_properties".to_string(), diff --git a/editor/src/messages/portfolio/document_migration.rs b/editor/src/messages/portfolio/document_migration.rs index a55d63ff53..ba4a73a767 100644 --- a/editor/src/messages/portfolio/document_migration.rs +++ b/editor/src/messages/portfolio/document_migration.rs @@ -979,32 +979,13 @@ fn migrate_node(node_id: &NodeId, node: &DocumentNode, network_path: &[NodeId], document.network_interface.set_input(&InputConnector::node(*node_id, 3), old_inputs[4].clone(), network_path); document.network_interface.set_input(&InputConnector::node(*node_id, 4), old_inputs[5].clone(), network_path); document.network_interface.set_input(&InputConnector::node(*node_id, 5), old_inputs[3].clone(), network_path); - - upgraded = true; + } else { + // Swap it back if we're not changing anything + let _ = document.network_interface.replace_inputs(node_id, network_path, &mut current_node_template); } } - - if !upgraded { - let _ = document.network_interface.replace_inputs(node_id, network_path, &mut current_node_template); - } } - // Add the "Depth" parameter to the "Instance Index" node - if reference == "Instance Index" && inputs_count == 0 { - let mut node_template = resolve_document_node_type(reference)?.default_node_template(); - document.network_interface.replace_implementation(node_id, network_path, &mut node_template); - - let mut node_path = network_path.to_vec(); - node_path.push(*node_id); - - document.network_interface.add_import(TaggedValue::None, false, 0, "Primary", "", &node_path); - document.network_interface.add_import(TaggedValue::U32(0), false, 1, "Loop Level", "TODO", &node_path); - } - - // ================================== - // PUT ALL MIGRATIONS ABOVE THIS LINE - // ================================== - // Ensure layers are positioned as stacks if they are upstream siblings of another layer document.network_interface.load_structure(); let all_layers = LayerNodeIdentifier::ROOT_PARENT.descendants(document.network_interface.document_metadata()).collect::>(); diff --git a/node-graph/gcore/src/ops.rs b/node-graph/gcore/src/ops.rs index 0ef40a86a4..d5ffd57068 100644 --- a/node-graph/gcore/src/ops.rs +++ b/node-graph/gcore/src/ops.rs @@ -1,13 +1,6 @@ use crate::Node; use std::marker::PhantomData; -// TODO: Rename to "Passthrough" -/// Passes-through the input value without changing it. This is useful for rerouting wires for organization purposes. -#[node_macro::node(skip_impl)] -fn identity<'i, T: 'i + Send>(value: T) -> T { - value -} - // Type // TODO: Document this #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Default)] diff --git a/node-graph/gcore/src/value.rs b/node-graph/gcore/src/value.rs index 90bd39b942..185aa22dd2 100644 --- a/node-graph/gcore/src/value.rs +++ b/node-graph/gcore/src/value.rs @@ -13,28 +13,28 @@ impl<'i, const N: u32, I> Node<'i, I> for IntNode { } } -// #[derive(Default, Debug, Clone, Copy)] -// pub struct ValueNode(pub T); +#[derive(Default, Debug, Clone, Copy)] +pub struct ValueNode(pub T); -// impl<'i, T: 'i, I> Node<'i, I> for ValueNode { -// type Output = &'i T; -// #[inline(always)] -// fn eval(&'i self, _input: I) -> Self::Output { -// &self.0 -// } -// } +impl<'i, T: 'i, I> Node<'i, I> for ValueNode { + type Output = &'i T; + #[inline(always)] + fn eval(&'i self, _input: I) -> Self::Output { + &self.0 + } +} -// impl ValueNode { -// pub const fn new(value: T) -> ValueNode { -// ValueNode(value) -// } -// } +impl ValueNode { + pub const fn new(value: T) -> ValueNode { + ValueNode(value) + } +} -// impl From for ValueNode { -// fn from(value: T) -> Self { -// ValueNode::new(value) -// } -// } +impl From for ValueNode { + fn from(value: T) -> Self { + ValueNode::new(value) + } +} #[derive(Default, Debug, Clone, Copy)] pub struct AsRefNode, U>(pub T, PhantomData); diff --git a/node-graph/graph-craft/src/document.rs b/node-graph/graph-craft/src/document.rs index 08679ce417..ff13a83084 100644 --- a/node-graph/graph-craft/src/document.rs +++ b/node-graph/graph-craft/src/document.rs @@ -460,7 +460,7 @@ pub enum DocumentNodeImplementation { impl Default for DocumentNodeImplementation { fn default() -> Self { - Self::ProtoNode(ProtoNodeIdentifier::new("graphene_core::ops::IdentityNode")) + Self::ProtoNode(ProtoNodeIdentifier::new("graphene_std::any::IdentityNode")) } } @@ -916,7 +916,7 @@ impl NodeNetwork { return; }; // If the node is hidden, replace it with an identity node - let identity_node = DocumentNodeImplementation::ProtoNode("graphene_core::ops::IdentityNode".into()); + let identity_node = DocumentNodeImplementation::ProtoNode("graphene_std::any::IdentityNode".into()); if !node.visible && node.implementation != identity_node { node.implementation = identity_node; @@ -1092,7 +1092,7 @@ impl NodeNetwork { fn remove_id_node(&mut self, id: NodeId) -> Result<(), String> { let node = self.nodes.get(&id).ok_or_else(|| format!("Node with id {id} does not exist"))?.clone(); if let DocumentNodeImplementation::ProtoNode(ident) = &node.implementation { - if ident.name == "graphene_core::ops::IdentityNode" { + if ident.name == "graphene_std::any::IdentityNode" { assert_eq!(node.inputs.len(), 1, "Id node has more than one input"); if let NodeInput::Node { node_id, output_index, .. } = node.inputs[0] { let node_input_output_index = output_index; @@ -1139,13 +1139,13 @@ impl NodeNetwork { Ok(()) } - /// Strips out any [`graphene_core::ops::IdentityNode`]s that are unnecessary. + /// Strips out any [`graphene_std::any::IdentityNode`]s that are unnecessary. pub fn remove_redundant_id_nodes(&mut self) { let id_nodes = self .nodes .iter() .filter(|(_, node)| { - matches!(&node.implementation, DocumentNodeImplementation::ProtoNode(ident) if ident == &ProtoNodeIdentifier::new("graphene_core::ops::IdentityNode")) + matches!(&node.implementation, DocumentNodeImplementation::ProtoNode(ident) if ident == &ProtoNodeIdentifier::new("graphene_std::any::IdentityNode")) && node.inputs.len() == 1 && matches!(node.inputs[0], NodeInput::Node { .. }) }) @@ -1333,7 +1333,7 @@ mod test { fn extract_node() { let id_node = DocumentNode { inputs: vec![], - implementation: DocumentNodeImplementation::ProtoNode("graphene_core::ops::IdentityNode".into()), + implementation: DocumentNodeImplementation::ProtoNode("graphene_std::any::IdentityNode".into()), ..Default::default() }; // TODO: Extend test cases to test nested network @@ -1535,7 +1535,13 @@ mod test { NodeId(1), DocumentNode { inputs: vec![NodeInput::network(concrete!(u32), 0)], +<<<<<<< HEAD implementation: DocumentNodeImplementation::ProtoNode(graphene_core::ops::identity::IDENTIFIER), +||||||| parent of 8e045313 (Migrate pass through and value node to identity implementation) + implementation: DocumentNodeImplementation::ProtoNode(ProtoNodeIdentifier::new("graphene_core::ops::IdentityNode")), +======= + implementation: DocumentNodeImplementation::ProtoNode(ProtoNodeIdentifier::new("graphene_std::any::IdentityNode")), +>>>>>>> 8e045313 (Migrate pass through and value node to identity implementation) ..Default::default() }, ), @@ -1543,7 +1549,13 @@ mod test { NodeId(2), DocumentNode { inputs: vec![NodeInput::network(concrete!(u32), 1)], +<<<<<<< HEAD implementation: DocumentNodeImplementation::ProtoNode(graphene_core::ops::identity::IDENTIFIER), +||||||| parent of 8e045313 (Migrate pass through and value node to identity implementation) + implementation: DocumentNodeImplementation::ProtoNode(ProtoNodeIdentifier::new("graphene_core::ops::IdentityNode")), +======= + implementation: DocumentNodeImplementation::ProtoNode(ProtoNodeIdentifier::new("graphene_std::any::IdentityNode")), +>>>>>>> 8e045313 (Migrate pass through and value node to identity implementation) ..Default::default() }, ), @@ -1570,7 +1582,13 @@ mod test { NodeId(2), DocumentNode { inputs: vec![result_node_input], +<<<<<<< HEAD implementation: DocumentNodeImplementation::ProtoNode(graphene_core::ops::identity::IDENTIFIER), +||||||| parent of 8e045313 (Migrate pass through and value node to identity implementation) + implementation: DocumentNodeImplementation::ProtoNode(ProtoNodeIdentifier::new("graphene_core::ops::IdentityNode")), +======= + implementation: DocumentNodeImplementation::ProtoNode(ProtoNodeIdentifier::new("graphene_std::any::IdentityNode")), +>>>>>>> 8e045313 (Migrate pass through and value node to identity implementation) ..Default::default() }, ), diff --git a/node-graph/graph-craft/src/proto.rs b/node-graph/graph-craft/src/proto.rs index 4330976609..dc325da75c 100644 --- a/node-graph/graph-craft/src/proto.rs +++ b/node-graph/graph-craft/src/proto.rs @@ -143,7 +143,7 @@ pub struct ProtoNode { impl Default for ProtoNode { fn default() -> Self { Self { - identifier: ProtoNodeIdentifier::new("graphene_core::ops::IdentityNode"), + identifier: ProtoNodeIdentifier::new("graphene_std::any::IdentityNode"), construction_args: ConstructionArgs::Value(value::TaggedValue::U32(0).into()), input: ProtoNodeInput::None, original_location: OriginalLocation::default(), diff --git a/node-graph/gstd/src/any.rs b/node-graph/gstd/src/any.rs index 27308a2352..0cab682491 100644 --- a/node-graph/gstd/src/any.rs +++ b/node-graph/gstd/src/any.rs @@ -47,20 +47,19 @@ pub fn downcast_node(n: SharedNodeContainer) -> Do DowncastBothNode::new(n) } -// Same idea as the identity node, but with a hidden primary input in order to have an auto generated properties widget for the value -pub struct Value { +pub struct IdentityNode { value: SharedNodeContainer, } -impl<'i> Node<'i, Any<'i>> for Value { +impl<'i> Node<'i, Any<'i>> for IdentityNode { type Output = DynFuture<'i, Any<'i>>; fn eval(&'i self, input: Any<'i>) -> Self::Output { Box::pin(async move { self.value.eval(input).await }) } } -impl Value { +impl IdentityNode { pub const fn new(value: SharedNodeContainer) -> Self { - Value { value } + IdentityNode { value } } } diff --git a/node-graph/interpreted-executor/src/lib.rs b/node-graph/interpreted-executor/src/lib.rs index 5c05ef62ba..2fdb942fad 100644 --- a/node-graph/interpreted-executor/src/lib.rs +++ b/node-graph/interpreted-executor/src/lib.rs @@ -20,7 +20,13 @@ mod tests { NodeId(0), DocumentNode { inputs: vec![NodeInput::network(concrete!(u32), 0)], +<<<<<<< HEAD implementation: DocumentNodeImplementation::ProtoNode(ops::identity::IDENTIFIER), +||||||| parent of 8e045313 (Migrate pass through and value node to identity implementation) + implementation: DocumentNodeImplementation::ProtoNode(ProtoNodeIdentifier::new("graphene_core::ops::IdentityNode")), +======= + implementation: DocumentNodeImplementation::ProtoNode(ProtoNodeIdentifier::new("graphene_std::any::IdentityNode")), +>>>>>>> 8e045313 (Migrate pass through and value node to identity implementation) ..Default::default() }, ), diff --git a/node-graph/interpreted-executor/src/node_registry.rs b/node-graph/interpreted-executor/src/node_registry.rs index bb5397a7f3..7dfee999f6 100644 --- a/node-graph/interpreted-executor/src/node_registry.rs +++ b/node-graph/interpreted-executor/src/node_registry.rs @@ -14,7 +14,7 @@ use graphene_std::Context; use graphene_std::GraphicElement; #[cfg(feature = "gpu")] use graphene_std::any::DowncastBothNode; -use graphene_std::any::{ComposeTypeErased, DynAnyNode, IntoTypeErasedNode, Value}; +use graphene_std::any::{ComposeTypeErased, DynAnyNode, IdentityNode, IntoTypeErasedNode}; use graphene_std::application_io::{ImageTexture, SurfaceFrame}; #[cfg(feature = "gpu")] use graphene_std::wasm_application_io::{WasmEditorApi, WasmSurfaceHandle}; @@ -115,10 +115,10 @@ fn node_registry() -> HashMap>>>>>> 8e045313 (Migrate pass through and value node to identity implementation) inputs: vec![NodeInput::value(TaggedValue::EditorApi(editor_api), false)], ..Default::default() }, diff --git a/node-graph/preprocessor/src/lib.rs b/node-graph/preprocessor/src/lib.rs index e0b4a01685..258b27c783 100644 --- a/node-graph/preprocessor/src/lib.rs +++ b/node-graph/preprocessor/src/lib.rs @@ -49,7 +49,13 @@ pub fn generate_node_substitutions() -> HashMap>>>>>> 8e045313 (Migrate pass through and value node to identity implementation) let into_node_registry = &interpreted_executor::node_registry::NODE_REGISTRY;