Migrate pass through and value node to identity implementation

This commit is contained in:
Adam
2025-07-26 13:56:57 -07:00
parent 007812077b
commit 7ecd1d0054
11 changed files with 83 additions and 68 deletions
@@ -85,11 +85,17 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
let custom = vec![ let custom = vec![
// TODO: Auto-generate this from its proto node macro // TODO: Auto-generate this from its proto node macro
DocumentNodeDefinition { DocumentNodeDefinition {
identifier: "Identity", identifier: "Pass Through",
category: "General", category: "General",
node_template: NodeTemplate { node_template: NodeTemplate {
document_node: DocumentNode { document_node: DocumentNode {
<<<<<<< HEAD
implementation: DocumentNodeImplementation::ProtoNode(ops::identity::IDENTIFIER), 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)], inputs: vec![NodeInput::value(TaggedValue::None, true)],
..Default::default() ..Default::default()
}, },
@@ -100,14 +106,14 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
}, },
}, },
description: Cow::Borrowed("Passes-through the input value without changing it. This is useful for rerouting wires for organization purposes."), 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 { DocumentNodeDefinition {
identifier: "Value", identifier: "Value",
category: "General", category: "General",
node_template: NodeTemplate { node_template: NodeTemplate {
document_node: DocumentNode { document_node: DocumentNode {
implementation: DocumentNodeImplementation::proto("graphene_core::any::ValueNode"), implementation: DocumentNodeImplementation::proto("graphene_std::any::IdentityNode"),
manual_composition: Some(generic!(T)), manual_composition: Some(generic!(T)),
inputs: vec![NodeInput::value(TaggedValue::None, false)], inputs: vec![NodeInput::value(TaggedValue::None, false)],
..Default::default() ..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("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("sample_polyline_properties".to_string(), Box::new(node_properties::sample_polyline_properties));
map.insert( map.insert(
"identity_properties".to_string(), "pass_through_properties".to_string(),
Box::new(|_node_id, _context| node_properties::string_properties("The identity node passes its data through.")), Box::new(|_node_id, _context| node_properties::string_properties("The Pass Through node can be used to organize wires.")),
); );
map.insert( map.insert(
"monitor_properties".to_string(), "monitor_properties".to_string(),
@@ -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, 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, 4), old_inputs[5].clone(), network_path);
document.network_interface.set_input(&InputConnector::node(*node_id, 5), old_inputs[3].clone(), network_path); document.network_interface.set_input(&InputConnector::node(*node_id, 5), old_inputs[3].clone(), network_path);
} else {
upgraded = true; // 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 // Ensure layers are positioned as stacks if they are upstream siblings of another layer
document.network_interface.load_structure(); document.network_interface.load_structure();
let all_layers = LayerNodeIdentifier::ROOT_PARENT.descendants(document.network_interface.document_metadata()).collect::<Vec<_>>(); let all_layers = LayerNodeIdentifier::ROOT_PARENT.descendants(document.network_interface.document_metadata()).collect::<Vec<_>>();
-7
View File
@@ -1,13 +1,6 @@
use crate::Node; use crate::Node;
use std::marker::PhantomData; 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 // Type
// TODO: Document this // TODO: Document this
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Default)] #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
+19 -19
View File
@@ -13,28 +13,28 @@ impl<'i, const N: u32, I> Node<'i, I> for IntNode<N> {
} }
} }
// #[derive(Default, Debug, Clone, Copy)] #[derive(Default, Debug, Clone, Copy)]
// pub struct ValueNode<T>(pub T); pub struct ValueNode<T>(pub T);
// impl<'i, T: 'i, I> Node<'i, I> for ValueNode<T> { impl<'i, T: 'i, I> Node<'i, I> for ValueNode<T> {
// type Output = &'i T; type Output = &'i T;
// #[inline(always)] #[inline(always)]
// fn eval(&'i self, _input: I) -> Self::Output { fn eval(&'i self, _input: I) -> Self::Output {
// &self.0 &self.0
// } }
// } }
// impl<T> ValueNode<T> { impl<T> ValueNode<T> {
// pub const fn new(value: T) -> ValueNode<T> { pub const fn new(value: T) -> ValueNode<T> {
// ValueNode(value) ValueNode(value)
// } }
// } }
// impl<T> From<T> for ValueNode<T> { impl<T> From<T> for ValueNode<T> {
// fn from(value: T) -> Self { fn from(value: T) -> Self {
// ValueNode::new(value) ValueNode::new(value)
// } }
// } }
#[derive(Default, Debug, Clone, Copy)] #[derive(Default, Debug, Clone, Copy)]
pub struct AsRefNode<T: AsRef<U>, U>(pub T, PhantomData<U>); pub struct AsRefNode<T: AsRef<U>, U>(pub T, PhantomData<U>);
+24 -6
View File
@@ -460,7 +460,7 @@ pub enum DocumentNodeImplementation {
impl Default for DocumentNodeImplementation { impl Default for DocumentNodeImplementation {
fn default() -> Self { 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; return;
}; };
// If the node is hidden, replace it with an identity node // 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 { if !node.visible && node.implementation != identity_node {
node.implementation = identity_node; node.implementation = identity_node;
@@ -1092,7 +1092,7 @@ impl NodeNetwork {
fn remove_id_node(&mut self, id: NodeId) -> Result<(), String> { 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(); 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 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"); assert_eq!(node.inputs.len(), 1, "Id node has more than one input");
if let NodeInput::Node { node_id, output_index, .. } = node.inputs[0] { if let NodeInput::Node { node_id, output_index, .. } = node.inputs[0] {
let node_input_output_index = output_index; let node_input_output_index = output_index;
@@ -1139,13 +1139,13 @@ impl NodeNetwork {
Ok(()) 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) { pub fn remove_redundant_id_nodes(&mut self) {
let id_nodes = self let id_nodes = self
.nodes .nodes
.iter() .iter()
.filter(|(_, node)| { .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 && node.inputs.len() == 1
&& matches!(node.inputs[0], NodeInput::Node { .. }) && matches!(node.inputs[0], NodeInput::Node { .. })
}) })
@@ -1333,7 +1333,7 @@ mod test {
fn extract_node() { fn extract_node() {
let id_node = DocumentNode { let id_node = DocumentNode {
inputs: vec![], inputs: vec![],
implementation: DocumentNodeImplementation::ProtoNode("graphene_core::ops::IdentityNode".into()), implementation: DocumentNodeImplementation::ProtoNode("graphene_std::any::IdentityNode".into()),
..Default::default() ..Default::default()
}; };
// TODO: Extend test cases to test nested network // TODO: Extend test cases to test nested network
@@ -1535,7 +1535,13 @@ mod test {
NodeId(1), NodeId(1),
DocumentNode { DocumentNode {
inputs: vec![NodeInput::network(concrete!(u32), 0)], inputs: vec![NodeInput::network(concrete!(u32), 0)],
<<<<<<< HEAD
implementation: DocumentNodeImplementation::ProtoNode(graphene_core::ops::identity::IDENTIFIER), 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() ..Default::default()
}, },
), ),
@@ -1543,7 +1549,13 @@ mod test {
NodeId(2), NodeId(2),
DocumentNode { DocumentNode {
inputs: vec![NodeInput::network(concrete!(u32), 1)], inputs: vec![NodeInput::network(concrete!(u32), 1)],
<<<<<<< HEAD
implementation: DocumentNodeImplementation::ProtoNode(graphene_core::ops::identity::IDENTIFIER), 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() ..Default::default()
}, },
), ),
@@ -1570,7 +1582,13 @@ mod test {
NodeId(2), NodeId(2),
DocumentNode { DocumentNode {
inputs: vec![result_node_input], inputs: vec![result_node_input],
<<<<<<< HEAD
implementation: DocumentNodeImplementation::ProtoNode(graphene_core::ops::identity::IDENTIFIER), 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() ..Default::default()
}, },
), ),
+1 -1
View File
@@ -143,7 +143,7 @@ pub struct ProtoNode {
impl Default for ProtoNode { impl Default for ProtoNode {
fn default() -> Self { fn default() -> Self {
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()), construction_args: ConstructionArgs::Value(value::TaggedValue::U32(0).into()),
input: ProtoNodeInput::None, input: ProtoNodeInput::None,
original_location: OriginalLocation::default(), original_location: OriginalLocation::default(),
+4 -5
View File
@@ -47,20 +47,19 @@ pub fn downcast_node<I: StaticType, O: StaticType>(n: SharedNodeContainer) -> Do
DowncastBothNode::new(n) 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 IdentityNode {
pub struct Value {
value: SharedNodeContainer, value: SharedNodeContainer,
} }
impl<'i> Node<'i, Any<'i>> for Value { impl<'i> Node<'i, Any<'i>> for IdentityNode {
type Output = DynFuture<'i, Any<'i>>; type Output = DynFuture<'i, Any<'i>>;
fn eval(&'i self, input: Any<'i>) -> Self::Output { fn eval(&'i self, input: Any<'i>) -> Self::Output {
Box::pin(async move { self.value.eval(input).await }) Box::pin(async move { self.value.eval(input).await })
} }
} }
impl Value { impl IdentityNode {
pub const fn new(value: SharedNodeContainer) -> Self { pub const fn new(value: SharedNodeContainer) -> Self {
Value { value } IdentityNode { value }
} }
} }
@@ -20,7 +20,13 @@ mod tests {
NodeId(0), NodeId(0),
DocumentNode { DocumentNode {
inputs: vec![NodeInput::network(concrete!(u32), 0)], inputs: vec![NodeInput::network(concrete!(u32), 0)],
<<<<<<< HEAD
implementation: DocumentNodeImplementation::ProtoNode(ops::identity::IDENTIFIER), 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() ..Default::default()
}, },
), ),
@@ -14,7 +14,7 @@ use graphene_std::Context;
use graphene_std::GraphicElement; use graphene_std::GraphicElement;
#[cfg(feature = "gpu")] #[cfg(feature = "gpu")]
use graphene_std::any::DowncastBothNode; 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}; use graphene_std::application_io::{ImageTexture, SurfaceFrame};
#[cfg(feature = "gpu")] #[cfg(feature = "gpu")]
use graphene_std::wasm_application_io::{WasmEditorApi, WasmSurfaceHandle}; use graphene_std::wasm_application_io::{WasmEditorApi, WasmSurfaceHandle};
@@ -115,10 +115,10 @@ fn node_registry() -> HashMap<ProtoNodeIdentifier, HashMap<NodeIOTypes, NodeCons
), ),
), ),
( (
ProtoNodeIdentifier::new("graphene_core::any::ValueNode"), ProtoNodeIdentifier::new("graphene_std::any::IdentityNode"),
|args| { |args| {
Box::pin(async move { Box::pin(async move {
let node = Value::new(args[0].clone()); let node = IdentityNode::new(args[0].clone());
node.into_type_erased() node.into_type_erased()
}) })
}, },
@@ -68,7 +68,13 @@ pub fn wrap_network_in_scope(mut network: NodeNetwork, editor_api: Arc<WasmEdito
inner_network, inner_network,
render_node, render_node,
DocumentNode { DocumentNode {
<<<<<<< HEAD
implementation: DocumentNodeImplementation::ProtoNode(graphene_std::ops::identity::IDENTIFIER), implementation: DocumentNodeImplementation::ProtoNode(graphene_std::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::EditorApi(editor_api), false)], inputs: vec![NodeInput::value(TaggedValue::EditorApi(editor_api), false)],
..Default::default() ..Default::default()
}, },
+6
View File
@@ -49,7 +49,13 @@ pub fn generate_node_substitutions() -> HashMap<ProtoNodeIdentifier, DocumentNod
let input_count = inputs.len(); let input_count = inputs.len();
let network_inputs = (0..input_count).map(|i| NodeInput::node(NodeId(i as u64), 0)).collect(); let network_inputs = (0..input_count).map(|i| NodeInput::node(NodeId(i as u64), 0)).collect();
<<<<<<< HEAD
let identity_node = ops::identity::IDENTIFIER; let identity_node = ops::identity::IDENTIFIER;
||||||| parent of 8e045313 (Migrate pass through and value node to identity implementation)
let identity_node = ProtoNodeIdentifier::new("graphene_core::ops::IdentityNode");
=======
let identity_node = ProtoNodeIdentifier::new("graphene_std::any::IdentityNode");
>>>>>>> 8e045313 (Migrate pass through and value node to identity implementation)
let into_node_registry = &interpreted_executor::node_registry::NODE_REGISTRY; let into_node_registry = &interpreted_executor::node_registry::NODE_REGISTRY;