Convert u64 IDs to newtypes (#1532)

This commit is contained in:
Keavon Chambers 2023-12-22 03:24:13 -08:00 committed by GitHub
parent 7bfe0ce55b
commit 34f952bad1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
38 changed files with 565 additions and 446 deletions

View file

@ -38,7 +38,7 @@ fn main() {
fn add_network() -> NodeNetwork {
NodeNetwork {
inputs: vec![],
outputs: vec![NodeOutput::new(0, 0)],
outputs: vec![NodeOutput::new(NodeId(0), 0)],
disabled: vec![],
previous_outputs: None,
nodes: [DocumentNode {
@ -66,7 +66,7 @@ fn add_network() -> NodeNetwork {
}]
.into_iter()
.enumerate()
.map(|(id, node)| (id as NodeId, node))
.map(|(id, node)| (NodeId(id as u64), node))
.collect(),
}
}

View file

@ -1,11 +1,12 @@
use core::ops::{Deref, DerefMut};
use serde::{Deserialize, Serialize};
use alloc::vec;
use alloc::vec::Vec;
use core::iter::Zip;
use core::ops::{Deref, DerefMut};
use core::slice::Iter;
use serde::{Deserialize, Serialize};
/// Brief description: A vec that allows indexing elements by both index and an assigned unique ID
/// Goals of this Data Structure:
/// Brief description: A vec that allows indexing elements by both index and an assigned unique ID.
/// Goals of this data structure:
/// - Drop-in replacement for a Vec.
/// - Provide an auto-assigned Unique ID per element upon insertion.
/// - Add elements to the start or end.
@ -16,8 +17,10 @@ use alloc::vec::Vec;
/// This data structure is somewhat similar to a linked list in terms of invariants.
/// The downside is that currently it requires a lot of iteration.
// TODO: Convert from a type alias to a newtype
pub type ElementId = u64;
#[repr(transparent)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, serde::Serialize, serde::Deserialize, specta::Type)]
pub struct ElementId(pub u64);
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize, specta::Type, Hash)]
pub struct IdBackedVec<T> {
/// Contained elements
@ -34,13 +37,13 @@ impl<T> IdBackedVec<T> {
IdBackedVec {
elements: vec![],
element_ids: vec![],
next_id: 0,
next_id: ElementId(0),
}
}
/// Push a new element to the start of the vector
pub fn push_front(&mut self, element: T) -> Option<ElementId> {
self.next_id += 1;
self.next_id = ElementId(self.next_id.0 + 1);
self.elements.insert(0, element);
self.element_ids.insert(0, self.next_id);
Some(self.next_id)
@ -48,7 +51,7 @@ impl<T> IdBackedVec<T> {
/// Push an element to the end of the vector
pub fn push_end(&mut self, element: T) -> Option<ElementId> {
self.next_id += 1;
self.next_id = ElementId(self.next_id.0 + 1);
self.elements.push(element);
self.element_ids.push(self.next_id);
Some(self.next_id)
@ -57,7 +60,7 @@ impl<T> IdBackedVec<T> {
/// Insert an element adjacent to the given ID
pub fn insert(&mut self, element: T, id: ElementId) -> Option<ElementId> {
if let Some(index) = self.index_from_id(id) {
self.next_id += 1;
self.next_id = ElementId(self.next_id.0 + 1);
self.elements.insert(index, element);
self.element_ids.insert(index, self.next_id);
return Some(self.next_id);
@ -125,7 +128,7 @@ impl<T> IdBackedVec<T> {
}
/// Enumerate the ids and elements in this container `(&ElementId, &T)`
pub fn enumerate(&self) -> core::iter::Zip<core::slice::Iter<ElementId>, core::slice::Iter<T>> {
pub fn enumerate(&self) -> Zip<Iter<ElementId>, Iter<T>> {
self.element_ids.iter().zip(self.elements.iter())
}

View file

@ -1,12 +1,14 @@
use super::id_vec::IdBackedVec;
use super::consts::ManipulatorType;
use super::id_vec::{ElementId, IdBackedVec};
use super::manipulator_group::ManipulatorGroup;
use super::manipulator_point::ManipulatorPoint;
use super::{consts::ManipulatorType, id_vec::ElementId};
use crate::uuid::ManipulatorGroupId;
use alloc::string::String;
use alloc::vec;
use alloc::vec::Vec;
use core::iter::Zip;
use core::slice::Iter;
use dyn_any::{DynAny, StaticType};
use glam::{DAffine2, DVec2};
use kurbo::{BezPath, PathEl, Shape};
@ -460,7 +462,7 @@ impl BezierId {
/// An iterator over [`bezier_rs::Bezier`] segments constructable via [`Subpath::bezier_iter`].
pub struct PathIter<'a> {
path: core::iter::Zip<core::slice::Iter<'a, u64>, core::slice::Iter<'a, ManipulatorGroup>>,
path: Zip<Iter<'a, ElementId>, Iter<'a, ManipulatorGroup>>,
last_anchor: Option<DVec2>,
last_out_handle: Option<DVec2>,
@ -482,7 +484,8 @@ impl<'a> Iterator for PathIter<'a> {
let mut result = None;
while result.is_none() {
let (&id, manipulator_group) = self.path.next()?;
let (id, manipulator_group) = self.path.next()?;
let id = id.0;
let in_handle = manipulator_group.points[ManipulatorType::InHandle].as_ref().map(|point| point.position);
let anchor = manipulator_group.points[ManipulatorType::Anchor].as_ref().map(|point| point.position);

View file

@ -12,8 +12,15 @@ use std::hash::{Hash, Hasher};
pub mod value;
// TODO: Convert from a type alias to a newtype
pub type NodeId = u64;
#[repr(transparent)]
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash, PartialOrd, Ord, serde::Serialize, serde::Deserialize, specta::Type)]
pub struct NodeId(pub u64);
impl core::fmt::Display for NodeId {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{}", self.0)
}
}
/// Hash two IDs together, returning a new ID that is always consistant for two input IDs in a specific order.
/// This is used during [`NodeNetwork::flatten`] in order to ensure consistant yet non-conflicting IDs for inner networks.
@ -21,7 +28,7 @@ fn merge_ids(a: NodeId, b: NodeId) -> NodeId {
let mut hasher = DefaultHasher::new();
a.hash(&mut hasher);
b.hash(&mut hasher);
hasher.finish()
NodeId(hasher.finish())
}
#[derive(Clone, Debug, PartialEq, Default, specta::Type, Hash, DynAny)]
@ -468,9 +475,9 @@ impl NodeNetwork {
pub fn value_network(node: DocumentNode) -> Self {
Self {
inputs: node.inputs.iter().filter(|input| matches!(input, NodeInput::Network(_))).map(|_| 0).collect(),
outputs: vec![NodeOutput::new(0, 0)],
nodes: [(0, node)].into_iter().collect(),
inputs: node.inputs.iter().filter(|input| matches!(input, NodeInput::Network(_))).map(|_| NodeId(0)).collect(),
outputs: vec![NodeOutput::new(NodeId(0), 0)],
nodes: [(NodeId(0), node)].into_iter().collect(),
disabled: vec![],
previous_outputs: None,
}
@ -479,10 +486,10 @@ impl NodeNetwork {
/// A graph with just an input node
pub fn new_network() -> Self {
Self {
inputs: vec![0],
outputs: vec![NodeOutput::new(0, 0)],
inputs: vec![NodeId(0)],
outputs: vec![NodeOutput::new(NodeId(0), 0)],
nodes: [(
0,
NodeId(0),
DocumentNode {
name: "Input Frame".into(),
manual_composition: Some(concrete!(u32)),
@ -499,7 +506,7 @@ impl NodeNetwork {
/// Appends a new node to the network after the output node and sets it as the new output
pub fn push_node(&mut self, mut node: DocumentNode) -> NodeId {
let id = self.nodes.len().try_into().expect("Too many nodes in network");
let id = NodeId(self.nodes.len().try_into().expect("Too many nodes in network"));
// Set the correct position for the new node
if node.metadata.position == IVec2::default() {
if let Some(pos) = self.original_outputs().first().and_then(|first| self.nodes.get(&first.node_id)).map(|n| n.metadata.position) {
@ -536,11 +543,11 @@ impl NodeNetwork {
name: "Cache".into(),
inputs: vec![],
implementation: DocumentNodeImplementation::Network(NodeNetwork {
inputs: vec![0],
outputs: vec![NodeOutput::new(1, 0)],
inputs: vec![NodeId(0)],
outputs: vec![NodeOutput::new(NodeId(1), 0)],
nodes: vec![
(
0,
NodeId(0),
DocumentNode {
name: "MemoNode".to_string(),
manual_composition: Some(concrete!(())),
@ -550,10 +557,10 @@ impl NodeNetwork {
},
),
(
1,
NodeId(1),
DocumentNode {
name: "CloneNode".to_string(),
inputs: vec![NodeInput::node(0, 0)],
inputs: vec![NodeInput::node(NodeId(0), 0)],
implementation: DocumentNodeImplementation::Unresolved(ProtoNodeIdentifier::new("graphene_core::ops::CloneNode<_>")),
..Default::default()
},
@ -819,7 +826,7 @@ impl NodeNetwork {
/// Remove all nodes that contain [`DocumentNodeImplementation::Network`] by moving the nested nodes into the parent network.
pub fn flatten(&mut self, node: NodeId) {
self.flatten_with_fns(node, merge_ids, generate_uuid)
self.flatten_with_fns(node, merge_ids, || NodeId(generate_uuid()))
}
/// Remove all nodes that contain [`DocumentNodeImplementation::Network`] by moving the nested nodes into the parent network.
@ -1062,7 +1069,7 @@ impl NodeNetwork {
} = input
{
if *graphic_group == GraphicGroup::EMPTY {
*input = NodeInput::node(new_id, 0);
*input = NodeInput::node(NodeId(new_id), 0);
used = true;
}
}
@ -1078,7 +1085,7 @@ impl NodeNetwork {
inputs: vec![NodeInput::value(TaggedValue::GraphicGroup(graphene_core::GraphicGroup::EMPTY), false)],
..Default::default()
};
self.nodes.insert(new_id, new_node);
self.nodes.insert(NodeId(new_id), new_node);
}
}
@ -1128,16 +1135,16 @@ mod test {
fn gen_node_id() -> NodeId {
static NODE_ID: AtomicU64 = AtomicU64::new(4);
NODE_ID.fetch_add(1, std::sync::atomic::Ordering::SeqCst)
NodeId(NODE_ID.fetch_add(1, std::sync::atomic::Ordering::SeqCst))
}
fn add_network() -> NodeNetwork {
NodeNetwork {
inputs: vec![0, 0],
outputs: vec![NodeOutput::new(1, 0)],
inputs: vec![NodeId(0), NodeId(0)],
outputs: vec![NodeOutput::new(NodeId(1), 0)],
nodes: [
(
0,
NodeId(0),
DocumentNode {
name: "Cons".into(),
inputs: vec![NodeInput::Network(concrete!(u32)), NodeInput::Network(concrete!(u32))],
@ -1146,10 +1153,10 @@ mod test {
},
),
(
1,
NodeId(1),
DocumentNode {
name: "Add".into(),
inputs: vec![NodeInput::node(0, 0)],
inputs: vec![NodeInput::node(NodeId(0), 0)],
implementation: DocumentNodeImplementation::Unresolved("graphene_core::ops::AddPairNode".into()),
..Default::default()
},
@ -1164,13 +1171,13 @@ mod test {
#[test]
fn map_ids() {
let mut network = add_network();
network.map_ids(|id| id + 1);
network.map_ids(|id| NodeId(id.0 + 1));
let mapped_add = NodeNetwork {
inputs: vec![1, 1],
outputs: vec![NodeOutput::new(2, 0)],
inputs: vec![NodeId(1), NodeId(1)],
outputs: vec![NodeOutput::new(NodeId(2), 0)],
nodes: [
(
1,
NodeId(1),
DocumentNode {
name: "Cons".into(),
inputs: vec![NodeInput::Network(concrete!(u32)), NodeInput::Network(concrete!(u32))],
@ -1179,10 +1186,10 @@ mod test {
},
),
(
2,
NodeId(2),
DocumentNode {
name: "Add".into(),
inputs: vec![NodeInput::node(1, 0)],
inputs: vec![NodeInput::node(NodeId(1), 0)],
implementation: DocumentNodeImplementation::Unresolved("graphene_core::ops::AddPairNode".into()),
..Default::default()
},
@ -1206,25 +1213,25 @@ mod test {
// TODO: Extend test cases to test nested network
let mut extraction_network = NodeNetwork {
inputs: vec![],
outputs: vec![NodeOutput::new(1, 0)],
outputs: vec![NodeOutput::new(NodeId(1), 0)],
nodes: [
id_node.clone(),
DocumentNode {
name: "Extract".into(),
inputs: vec![NodeInput::lambda(0, 0)],
inputs: vec![NodeInput::lambda(NodeId(0), 0)],
implementation: DocumentNodeImplementation::Extract,
..Default::default()
},
]
.into_iter()
.enumerate()
.map(|(id, node)| (id as NodeId, node))
.map(|(id, node)| (NodeId(id as u64), node))
.collect(),
..Default::default()
};
extraction_network.resolve_extract_nodes();
assert_eq!(extraction_network.nodes.len(), 1);
let inputs = extraction_network.nodes.get(&1).unwrap().inputs.clone();
let inputs = extraction_network.nodes.get(&NodeId(1)).unwrap().inputs.clone();
assert_eq!(inputs.len(), 1);
assert!(matches!(&inputs[0], &NodeInput::Value{ tagged_value: TaggedValue::DocumentNode(ref network), ..} if network == &id_node));
}
@ -1232,10 +1239,10 @@ mod test {
#[test]
fn flatten_add() {
let mut network = NodeNetwork {
inputs: vec![1],
outputs: vec![NodeOutput::new(1, 0)],
inputs: vec![NodeId(1)],
outputs: vec![NodeOutput::new(NodeId(1), 0)],
nodes: [(
1,
NodeId(1),
DocumentNode {
name: "Inc".into(),
inputs: vec![
@ -1254,7 +1261,7 @@ mod test {
..Default::default()
};
network.generate_node_paths(&[]);
network.flatten_with_fns(1, |self_id, inner_id| self_id * 10 + inner_id, gen_node_id);
network.flatten_with_fns(NodeId(1), |self_id, inner_id| NodeId(self_id.0 * 10 + inner_id.0), gen_node_id);
let flat_network = flat_network();
println!("{flat_network:#?}");
println!("{network:#?}");
@ -1266,7 +1273,7 @@ mod test {
fn resolve_proto_node_add() {
let document_node = DocumentNode {
name: "Cons".into(),
inputs: vec![NodeInput::Network(concrete!(u32)), NodeInput::node(0, 0)],
inputs: vec![NodeInput::Network(concrete!(u32)), NodeInput::node(NodeId(0), 0)],
implementation: DocumentNodeImplementation::Unresolved("graphene_core::structural::ConsNode".into()),
..Default::default()
};
@ -1275,7 +1282,7 @@ mod test {
let reference = ProtoNode {
identifier: "graphene_core::structural::ConsNode".into(),
input: ProtoNodeInput::ManualComposition(concrete!(u32)),
construction_args: ConstructionArgs::Nodes(vec![(0, false)]),
construction_args: ConstructionArgs::Nodes(vec![(NodeId(0), false)]),
..Default::default()
};
assert_eq!(proto_node, reference);
@ -1284,30 +1291,30 @@ mod test {
#[test]
fn resolve_flatten_add_as_proto_network() {
let construction_network = ProtoNetwork {
inputs: vec![10],
output: 11,
inputs: vec![NodeId(10)],
output: NodeId(11),
nodes: [
(
10,
NodeId(10),
ProtoNode {
identifier: "graphene_core::structural::ConsNode".into(),
input: ProtoNodeInput::ManualComposition(concrete!(u32)),
construction_args: ConstructionArgs::Nodes(vec![(14, false)]),
document_node_path: vec![1, 0],
construction_args: ConstructionArgs::Nodes(vec![(NodeId(14), false)]),
document_node_path: vec![NodeId(1), NodeId(0)],
..Default::default()
},
),
(
11,
NodeId(11),
ProtoNode {
identifier: "graphene_core::ops::AddPairNode".into(),
input: ProtoNodeInput::Node(10, false),
input: ProtoNodeInput::Node(NodeId(10), false),
construction_args: ConstructionArgs::Nodes(vec![]),
document_node_path: vec![1, 1],
document_node_path: vec![NodeId(1), NodeId(1)],
..Default::default()
},
),
(14, ProtoNode::value(ConstructionArgs::Value(TaggedValue::U32(2)), vec![1, 4])),
(NodeId(14), ProtoNode::value(ConstructionArgs::Value(TaggedValue::U32(2)), vec![NodeId(1), NodeId(4)])),
]
.into_iter()
.collect(),
@ -1322,21 +1329,21 @@ mod test {
fn flat_network() -> NodeNetwork {
NodeNetwork {
inputs: vec![10],
outputs: vec![NodeOutput::new(11, 0)],
inputs: vec![NodeId(10)],
outputs: vec![NodeOutput::new(NodeId(11), 0)],
nodes: [
(
10,
NodeId(10),
DocumentNode {
name: "Cons".into(),
inputs: vec![NodeInput::Network(concrete!(u32)), NodeInput::node(14, 0)],
inputs: vec![NodeInput::Network(concrete!(u32)), NodeInput::node(NodeId(14), 0)],
implementation: DocumentNodeImplementation::Unresolved("graphene_core::structural::ConsNode".into()),
path: Some(vec![1, 0]),
path: Some(vec![NodeId(1), NodeId(0)]),
..Default::default()
},
),
(
14,
NodeId(14),
DocumentNode {
name: "Value".into(),
inputs: vec![NodeInput::Value {
@ -1344,17 +1351,17 @@ mod test {
exposed: false,
}],
implementation: DocumentNodeImplementation::Unresolved("graphene_core::value::ClonedNode".into()),
path: Some(vec![1, 4]),
path: Some(vec![NodeId(1), NodeId(4)]),
..Default::default()
},
),
(
11,
NodeId(11),
DocumentNode {
name: "Add".into(),
inputs: vec![NodeInput::node(10, 0)],
inputs: vec![NodeInput::node(NodeId(10), 0)],
implementation: DocumentNodeImplementation::Unresolved("graphene_core::ops::AddPairNode".into()),
path: Some(vec![1, 1]),
path: Some(vec![NodeId(1), NodeId(1)]),
..Default::default()
},
),
@ -1367,11 +1374,11 @@ mod test {
fn two_node_identity() -> NodeNetwork {
NodeNetwork {
inputs: vec![1, 2],
outputs: vec![NodeOutput::new(1, 0), NodeOutput::new(2, 0)],
inputs: vec![NodeId(1), NodeId(2)],
outputs: vec![NodeOutput::new(NodeId(1), 0), NodeOutput::new(NodeId(2), 0)],
nodes: [
(
1,
NodeId(1),
DocumentNode {
name: "Identity 1".into(),
inputs: vec![NodeInput::Network(concrete!(u32))],
@ -1380,7 +1387,7 @@ mod test {
},
),
(
2,
NodeId(2),
DocumentNode {
name: "Identity 2".into(),
inputs: vec![NodeInput::Network(concrete!(u32))],
@ -1401,7 +1408,7 @@ mod test {
outputs: network_outputs,
nodes: [
(
1,
NodeId(1),
DocumentNode {
name: "Nested network".into(),
inputs: vec![NodeInput::value(TaggedValue::F32(1.), false), NodeInput::value(TaggedValue::F32(2.), false)],
@ -1410,7 +1417,7 @@ mod test {
},
),
(
2,
NodeId(2),
DocumentNode {
name: "Result".into(),
inputs: vec![result_node_input],
@ -1424,61 +1431,67 @@ mod test {
..Default::default()
};
let _new_ids = 101..;
network.flatten_with_fns(1, |self_id, inner_id| self_id * 10 + inner_id, || 10000);
network.flatten_with_fns(2, |self_id, inner_id| self_id * 10 + inner_id, || 10001);
network.flatten_with_fns(NodeId(1), |self_id, inner_id| NodeId(self_id.0 * 10 + inner_id.0), || NodeId(10000));
network.flatten_with_fns(NodeId(2), |self_id, inner_id| NodeId(self_id.0 * 10 + inner_id.0), || NodeId(10001));
network.remove_dead_nodes();
network
}
#[test]
fn simple_duplicate() {
let result = output_duplicate(vec![NodeOutput::new(1, 0)], NodeInput::node(1, 0));
let result = output_duplicate(vec![NodeOutput::new(NodeId(1), 0)], NodeInput::node(NodeId(1), 0));
println!("{result:#?}");
assert_eq!(result.outputs.len(), 1, "The number of outputs should remain as 1");
assert_eq!(result.outputs[0], NodeOutput::new(11, 0), "The outer network output should be from a duplicated inner network");
assert_eq!(result.outputs[0], NodeOutput::new(NodeId(11), 0), "The outer network output should be from a duplicated inner network");
let mut ids = result.nodes.keys().copied().collect::<Vec<_>>();
ids.sort();
assert_eq!(ids, vec![11, 10010], "Should only contain identity and values");
assert_eq!(ids, vec![NodeId(11), NodeId(10010)], "Should only contain identity and values");
}
// TODO: Write more tests
/*
#[test]
fn out_of_order_duplicate() {
let result = output_duplicate(vec![NodeOutput::new(10, 1), NodeOutput::new(10, 0)], NodeInput::node(10, 0));
assert_eq!(result.outputs[0], NodeOutput::new(101, 0), "The first network output should be from a duplicated nested network");
assert_eq!(result.outputs[1], NodeOutput::new(10, 0), "The second network output should be from the original nested network");
assert!(
result.nodes.contains_key(&10) && result.nodes.contains_key(&101) && result.nodes.len() == 2,
"Network should contain two duplicated nodes"
);
for (node_id, input_value, inner_id) in [(10, 1., 1), (101, 2., 2)] {
let nested_network_node = result.nodes.get(&node_id).unwrap();
assert_eq!(nested_network_node.name, "Nested network".to_string(), "Name should not change");
assert_eq!(nested_network_node.inputs, vec![NodeInput::value(TaggedValue::F32(input_value), false)], "Input should be stable");
let inner_network = nested_network_node.implementation.get_network().expect("Implementation should be network");
assert_eq!(inner_network.inputs, vec![inner_id], "The input should be sent to the second node");
assert_eq!(inner_network.outputs, vec![NodeOutput::new(inner_id, 0)], "The output should be node id");
assert_eq!(inner_network.nodes.get(&inner_id).unwrap().name, format!("Identity {inner_id}"), "The node should be identity");
}
}
#[test]
fn using_other_node_duplicate() {
let result = output_duplicate(vec![NodeOutput::new(11, 0)], NodeInput::node(10, 1));
assert_eq!(result.outputs, vec![NodeOutput::new(11, 0)], "The network output should be the result node");
assert!(
result.nodes.contains_key(&11) && result.nodes.contains_key(&101) && result.nodes.len() == 2,
"Network should contain a duplicated node and a result node"
);
let result_node = result.nodes.get(&11).unwrap();
assert_eq!(result_node.inputs, vec![NodeInput::node(101, 0)], "Result node should refer to duplicate node as input");
let nested_network_node = result.nodes.get(&101).unwrap();
assert_eq!(nested_network_node.name, "Nested network".to_string(), "Name should not change");
assert_eq!(nested_network_node.inputs, vec![NodeInput::value(TaggedValue::F32(2.), false)], "Input should be 2");
let inner_network = nested_network_node.implementation.get_network().expect("Implementation should be network");
assert_eq!(inner_network.inputs, vec![2], "The input should be sent to the second node");
assert_eq!(inner_network.outputs, vec![NodeOutput::new(2, 0)], "The output should be node id 2");
assert_eq!(inner_network.nodes.get(&2).unwrap().name, "Identity 2", "The node should be identity 2");
}
*/
// #[test]
// fn out_of_order_duplicate() {
// let result = output_duplicate(vec![NodeOutput::new(NodeId(10), 1), NodeOutput::new(NodeId(10), 0)], NodeInput::node(NodeId(10), 0);
// assert_eq!(
// result.outputs[0],
// NodeOutput::new(NodeId(101), 0),
// "The first network output should be from a duplicated nested network"
// );
// assert_eq!(
// result.outputs[1],
// NodeOutput::new(NodeId(10), 0),
// "The second network output should be from the original nested network"
// );
// assert!(
// result.nodes.contains_key(&NodeId(10)) && result.nodes.contains_key(&NodeId(101)) && result.nodes.len() == 2,
// "Network should contain two duplicated nodes"
// );
// for (node_id, input_value, inner_id) in [(10, 1., 1), (101, 2., 2)] {
// let nested_network_node = result.nodes.get(&NodeId(node_id)).unwrap();
// assert_eq!(nested_network_node.name, "Nested network".to_string(), "Name should not change");
// assert_eq!(nested_network_node.inputs, vec![NodeInput::value(TaggedValue::F32(input_value), false)], "Input should be stable");
// let inner_network = nested_network_node.implementation.get_network().expect("Implementation should be network");
// assert_eq!(inner_network.inputs, vec![inner_id], "The input should be sent to the second node");
// assert_eq!(inner_network.outputs, vec![NodeOutput::new(NodeId(inner_id), 0)], "The output should be node id");
// assert_eq!(inner_network.nodes.get(&NodeId(inner_id)).unwrap().name, format!("Identity {inner_id}"), "The node should be identity");
// }
// }
// #[test]
// fn using_other_node_duplicate() {
// let result = output_duplicate(vec![NodeOutput::new(NodeId(11), 0)], NodeInput::node(NodeId(10), 1);
// assert_eq!(result.outputs, vec![NodeOutput::new(NodeId(11), 0)], "The network output should be the result node");
// assert!(
// result.nodes.contains_key(&NodeId(11)) && result.nodes.contains_key(&NodeId(101)) && result.nodes.len() == 2,
// "Network should contain a duplicated node and a result node"
// );
// let result_node = result.nodes.get(&NodeId(11)).unwrap();
// assert_eq!(result_node.inputs, vec![NodeInput::node(NodeId(101), 0)], "Result node should refer to duplicate node as input");
// let nested_network_node = result.nodes.get(&NodeId(101)).unwrap();
// assert_eq!(nested_network_node.name, "Nested network".to_string(), "Name should not change");
// assert_eq!(nested_network_node.inputs, vec![NodeInput::value(TaggedValue::F32(2.), false)], "Input should be 2");
// let inner_network = nested_network_node.implementation.get_network().expect("Implementation should be network");
// assert_eq!(inner_network.inputs, vec![2], "The input should be sent to the second node");
// assert_eq!(inner_network.outputs, vec![NodeOutput::new(NodeId(2), 0)], "The output should be node id 2");
// assert_eq!(inner_network.nodes.get(&NodeId(2)).unwrap().name, "Identity 2", "The node should be identity 2");
// }
}

View file

@ -191,7 +191,7 @@ impl ConstructionArgs {
// TODO: what? Used in the gpu_compiler crate for something.
pub fn new_function_args(&self) -> Vec<String> {
match self {
ConstructionArgs::Nodes(nodes) => nodes.iter().map(|n| format!("n{:0x}", n.0)).collect(),
ConstructionArgs::Nodes(nodes) => nodes.iter().map(|(n, _)| format!("n{:0x}", n.0)).collect(),
ConstructionArgs::Value(value) => vec![value.to_primitive_string()],
ConstructionArgs::Inline(inline) => vec![inline.expr.clone()],
}
@ -277,7 +277,7 @@ impl ProtoNode {
}
ProtoNodeInput::Node(id, lambda) => (id, lambda).hash(&mut hasher),
};
Some(hasher.finish() as NodeId)
Some(NodeId(hasher.finish()))
}
/// Construct a new [`ProtoNode`] with the specified construction args and a `ClonedNode` implementation.
@ -349,8 +349,8 @@ impl ProtoNetwork {
let Some(sni) = self.nodes[index].1.stable_node_id() else {
panic!("failed to generate stable node id for node {:#?}", self.nodes[index].1);
};
self.replace_node_id(&outwards_edges, index as NodeId, sni, false);
self.nodes[index].0 = sni as NodeId;
self.replace_node_id(&outwards_edges, NodeId(index as u64), sni, false);
self.nodes[index].0 = sni;
}
}
@ -377,20 +377,26 @@ impl ProtoNetwork {
// Perform topological sort once
self.reorder_ids()?;
let max_id = self.nodes.len() as NodeId - 1;
let max_id = self.nodes.len() as u64 - 1;
// Collect outward edges once
let outwards_edges = self.collect_outwards_edges();
// Iterate over nodes in topological order
for node_id in 0..=max_id {
let node = &mut self.nodes[node_id as usize].1;
let node_id = NodeId(node_id);
let (_, node) = &mut self.nodes[node_id.0 as usize];
if let ProtoNodeInput::Node(input_node_id, false) = node.input {
// Create a new node that composes the current node and its input node
let compose_node_id = self.nodes.len() as NodeId;
let input = self.nodes[input_node_id as usize].1.input.clone();
let mut path = self.nodes[input_node_id as usize].1.document_node_path.clone();
let compose_node_id = NodeId(self.nodes.len() as u64);
let (_, input_node_id_proto) = &self.nodes[input_node_id.0 as usize];
let input = input_node_id_proto.input.clone();
let mut path = input_node_id_proto.document_node_path.clone();
path.push(node_id);
self.nodes.push((
@ -417,7 +423,7 @@ impl ProtoNetwork {
// Update references in other nodes to use the new compose node
if let Some(referring_nodes) = outwards_edges.get(&node_id) {
for &referring_node_id in referring_nodes {
let referring_node = &mut self.nodes[referring_node_id as usize].1;
let (_, referring_node) = &mut self.nodes[referring_node_id.0 as usize];
referring_node.map_ids(|id| if id == node_id { compose_node_id } else { id }, skip_lambdas)
}
}
@ -515,13 +521,13 @@ impl ProtoNetwork {
let current_positions: HashMap<_, _> = self.nodes.iter().enumerate().map(|(pos, (id, _))| (*id, pos)).collect();
// Map of node ids to their new index based on topological order
let new_positions: HashMap<_, _> = order.iter().enumerate().map(|(pos, id)| (*id, pos as NodeId)).collect();
let new_positions: HashMap<_, _> = order.iter().enumerate().map(|(pos, id)| (*id, NodeId(pos as u64))).collect();
// Create a new nodes vector based on the topological order
let mut new_nodes = Vec::with_capacity(order.len());
for (index, &id) in order.iter().enumerate() {
let current_pos = *current_positions.get(&id).unwrap();
new_nodes.push((index as NodeId, self.nodes[current_pos].1.clone()));
new_nodes.push((NodeId(index as u64), self.nodes[current_pos].1.clone()));
}
// Update node references to reflect the new order
@ -733,7 +739,7 @@ mod test {
let construction_network = test_network();
let sorted = construction_network.topological_sort().expect("Error when calling 'topological_sort' on 'construction_network.");
println!("{sorted:#?}");
assert_eq!(sorted, vec![14, 10, 11, 1]);
assert_eq!(sorted, vec![NodeId(14), NodeId(10), NodeId(11), NodeId(1)]);
}
#[test]
@ -750,12 +756,12 @@ mod test {
construction_network.reorder_ids().expect("Error when calling 'reorder_ids' on 'construction_network.");
let sorted = construction_network.topological_sort().expect("Error when calling 'topological_sort' on 'construction_network.");
println!("nodes: {:#?}", construction_network.nodes);
assert_eq!(sorted, vec![0, 1, 2, 3]);
assert_eq!(sorted, vec![NodeId(0), NodeId(1), NodeId(2), NodeId(3)]);
let ids: Vec<_> = construction_network.nodes.iter().map(|(id, _)| *id).collect();
println!("{ids:#?}");
println!("nodes: {:#?}", construction_network.nodes);
assert_eq!(construction_network.nodes[0].1.identifier.name.as_ref(), "value");
assert_eq!(ids, vec![0, 1, 2, 3]);
assert_eq!(ids, vec![NodeId(0), NodeId(1), NodeId(2), NodeId(3)]);
}
#[test]
@ -764,11 +770,11 @@ mod test {
construction_network.reorder_ids().expect("Error when calling 'reorder_ids' on 'construction_network.");
construction_network.reorder_ids().expect("Error when calling 'reorder_ids' on 'construction_network.");
let sorted = construction_network.topological_sort().expect("Error when calling 'topological_sort' on 'construction_network.");
assert_eq!(sorted, vec![0, 1, 2, 3]);
assert_eq!(sorted, vec![NodeId(0), NodeId(1), NodeId(2), NodeId(3)]);
let ids: Vec<_> = construction_network.nodes.iter().map(|(id, _)| *id).collect();
println!("{ids:#?}");
assert_eq!(construction_network.nodes[0].1.identifier.name.as_ref(), "value");
assert_eq!(ids, vec![0, 1, 2, 3]);
assert_eq!(ids, vec![NodeId(0), NodeId(1), NodeId(2), NodeId(3)]);
}
#[test]
@ -778,7 +784,7 @@ mod test {
println!("{construction_network:#?}");
assert_eq!(construction_network.nodes[0].1.identifier.name.as_ref(), "value");
assert_eq!(construction_network.nodes.len(), 6);
assert_eq!(construction_network.nodes[5].1.construction_args, ConstructionArgs::Nodes(vec![(3, false), (4, true)]));
assert_eq!(construction_network.nodes[5].1.construction_args, ConstructionArgs::Nodes(vec![(NodeId(3), false), (NodeId(4), true)]));
}
#[test]
@ -791,59 +797,59 @@ mod test {
assert_eq!(
ids,
vec![
17957338642374791135,
1303972037140595827,
15485192931817078264,
9739645351331265115,
4165308598738454684,
5557529806312473178
NodeId(17957338642374791135),
NodeId(1303972037140595827),
NodeId(15485192931817078264),
NodeId(9739645351331265115),
NodeId(4165308598738454684),
NodeId(5557529806312473178)
]
);
}
fn test_network() -> ProtoNetwork {
ProtoNetwork {
inputs: vec![10],
output: 1,
inputs: vec![NodeId(10)],
output: NodeId(1),
nodes: [
(
7,
NodeId(7),
ProtoNode {
identifier: "id".into(),
input: ProtoNodeInput::Node(11, false),
input: ProtoNodeInput::Node(NodeId(11), false),
construction_args: ConstructionArgs::Nodes(vec![]),
..Default::default()
},
),
(
1,
NodeId(1),
ProtoNode {
identifier: "id".into(),
input: ProtoNodeInput::Node(11, false),
input: ProtoNodeInput::Node(NodeId(11), false),
construction_args: ConstructionArgs::Nodes(vec![]),
..Default::default()
},
),
(
10,
NodeId(10),
ProtoNode {
identifier: "cons".into(),
input: ProtoNodeInput::ManualComposition(concrete!(u32)),
construction_args: ConstructionArgs::Nodes(vec![(14, false)]),
construction_args: ConstructionArgs::Nodes(vec![(NodeId(14), false)]),
..Default::default()
},
),
(
11,
NodeId(11),
ProtoNode {
identifier: "add".into(),
input: ProtoNodeInput::Node(10, false),
input: ProtoNodeInput::Node(NodeId(10), false),
construction_args: ConstructionArgs::Nodes(vec![]),
..Default::default()
},
),
(
14,
NodeId(14),
ProtoNode {
identifier: "value".into(),
input: ProtoNodeInput::None,
@ -859,23 +865,23 @@ mod test {
fn test_network_with_cycles() -> ProtoNetwork {
ProtoNetwork {
inputs: vec![1],
output: 1,
inputs: vec![NodeId(1)],
output: NodeId(1),
nodes: [
(
1,
NodeId(1),
ProtoNode {
identifier: "id".into(),
input: ProtoNodeInput::Node(2, false),
input: ProtoNodeInput::Node(NodeId(2), false),
construction_args: ConstructionArgs::Nodes(vec![]),
..Default::default()
},
),
(
2,
NodeId(2),
ProtoNode {
identifier: "id".into(),
input: ProtoNodeInput::Node(1, false),
input: ProtoNodeInput::Node(NodeId(1), false),
construction_args: ConstructionArgs::Nodes(vec![]),
..Default::default()
},

View file

@ -124,7 +124,7 @@ pub fn wrap_network_in_scope(mut network: NodeNetwork) -> NodeNetwork {
let inner_network = DocumentNode {
name: "Scope".to_string(),
implementation: DocumentNodeImplementation::Network(network),
inputs: core::iter::repeat(NodeInput::node(0, 1)).take(len).collect(),
inputs: core::iter::repeat(NodeInput::node(NodeId(0), 1)).take(len).collect(),
..Default::default()
};
@ -135,14 +135,14 @@ pub fn wrap_network_in_scope(mut network: NodeNetwork) -> NodeNetwork {
DocumentNode {
name: "End Scope".to_string(),
implementation: DocumentNodeImplementation::proto("graphene_core::memo::EndLetNode<_, _>"),
inputs: vec![NodeInput::node(0, 0), NodeInput::node(1, 0)],
inputs: vec![NodeInput::node(NodeId(0), 0), NodeInput::node(NodeId(1), 0)],
..Default::default()
},
];
NodeNetwork {
inputs: vec![0],
outputs: vec![NodeOutput::new(2, 0)],
nodes: nodes.into_iter().enumerate().map(|(id, node)| (id as NodeId, node)).collect(),
inputs: vec![NodeId(0)],
outputs: vec![NodeOutput::new(NodeId(2), 0)],
nodes: nodes.into_iter().enumerate().map(|(id, node)| (NodeId(id as u64), node)).collect(),
..Default::default()
}
}
@ -151,8 +151,8 @@ fn begin_scope() -> DocumentNode {
DocumentNode {
name: "Begin Scope".to_string(),
implementation: DocumentNodeImplementation::Network(NodeNetwork {
inputs: vec![0],
outputs: vec![NodeOutput::new(1, 0), NodeOutput::new(2, 0)],
inputs: vec![NodeId(0)],
outputs: vec![NodeOutput::new(NodeId(1), 0), NodeOutput::new(NodeId(2), 0)],
nodes: [
DocumentNode {
name: "SetNode".to_string(),
@ -162,21 +162,21 @@ fn begin_scope() -> DocumentNode {
},
DocumentNode {
name: "LetNode".to_string(),
inputs: vec![NodeInput::node(0, 0)],
inputs: vec![NodeInput::node(NodeId(0), 0)],
implementation: DocumentNodeImplementation::Unresolved(ProtoNodeIdentifier::new("graphene_core::memo::LetNode<_>")),
..Default::default()
},
DocumentNode {
name: "RefNode".to_string(),
manual_composition: Some(concrete!(WasmEditorApi)),
inputs: vec![NodeInput::lambda(1, 0)],
inputs: vec![NodeInput::lambda(NodeId(1), 0)],
implementation: DocumentNodeImplementation::Unresolved(ProtoNodeIdentifier::new("graphene_core::memo::RefNode<_, _>")),
..Default::default()
},
]
.into_iter()
.enumerate()
.map(|(id, node)| (id as NodeId, node))
.map(|(id, node)| (NodeId(id as u64), node))
.collect(),
..Default::default()

View file

@ -167,11 +167,11 @@ async fn create_compute_pass_descriptor<T: Clone + Pixel + StaticTypeSized>(
log::debug!("inner_network: {inner_network:?}");
let network = NodeNetwork {
inputs: vec![2, 1], //vec![0, 1],
inputs: vec![NodeId(2), NodeId(1)], //vec![0, 1],
#[cfg(feature = "quantization")]
outputs: vec![NodeOutput::new(5, 0)],
outputs: vec![NodeOutput::new(NodeId(5), 0)],
#[cfg(not(feature = "quantization"))]
outputs: vec![NodeOutput::new(3, 0)],
outputs: vec![NodeOutput::new(NodeId(3), 0)],
nodes: [
DocumentNode {
name: "Slice".into(),
@ -201,30 +201,30 @@ async fn create_compute_pass_descriptor<T: Clone + Pixel + StaticTypeSized>(
/*
DocumentNode {
name: "GetNode".into(),
inputs: vec![NodeInput::node(1, 0), NodeInput::node(0, 0)],
inputs: vec![NodeInput::node(NodeId(1), 0), NodeInput::node(NodeId(0), 0)],
implementation: DocumentNodeImplementation::Unresolved("graphene_core::storage::GetNode".into()),
..Default::default()
},*/
#[cfg(feature = "quantization")]
DocumentNode {
name: "Dequantize".into(),
inputs: vec![NodeInput::node(0, 0), NodeInput::node(1, 0)],
inputs: vec![NodeInput::node(NodeId(0), 0), NodeInput::node(NodeId(1), 0)],
implementation: DocumentNodeImplementation::proto("graphene_core::quantization::DeQuantizeNode"),
..Default::default()
},
DocumentNode {
name: "MapNode".into(),
#[cfg(feature = "quantization")]
inputs: vec![NodeInput::node(3, 0)],
inputs: vec![NodeInput::node(NodeId(3), 0)],
#[cfg(not(feature = "quantization"))]
inputs: vec![NodeInput::node(0, 0)],
inputs: vec![NodeInput::node(NodeId(0), 0)],
implementation: DocumentNodeImplementation::Network(inner_network),
..Default::default()
},
#[cfg(feature = "quantization")]
DocumentNode {
name: "Quantize".into(),
inputs: vec![NodeInput::node(4, 0), NodeInput::node(1, 0)],
inputs: vec![NodeInput::node(NodeId(4), 0), NodeInput::node(NodeId(1), 0)],
implementation: DocumentNodeImplementation::proto("graphene_core::quantization::QuantizeNode"),
..Default::default()
},
@ -232,7 +232,7 @@ async fn create_compute_pass_descriptor<T: Clone + Pixel + StaticTypeSized>(
DocumentNode {
name: "SaveNode".into(),
inputs: vec![
NodeInput::node(5, 0),
NodeInput::node(NodeId(5), 0),
NodeInput::Inline(InlineRust::new(
"|x| o0[(_global_index.y * i1 + _global_index.x) as usize] = x".into(),
//"|x|()".into(),
@ -246,7 +246,7 @@ async fn create_compute_pass_descriptor<T: Clone + Pixel + StaticTypeSized>(
]
.into_iter()
.enumerate()
.map(|(id, node)| (id as NodeId, node))
.map(|(id, node)| (NodeId(id as u64), node))
.collect(),
..Default::default()
};
@ -386,12 +386,12 @@ fn map_gpu_single_image(input: Image<Color>, node: String) -> Image<Color> {
let identifier = ProtoNodeIdentifier { name: std::borrow::Cow::Owned(node) };
let network = NodeNetwork {
inputs: vec![0],
inputs: vec![NodeId(0)],
disabled: vec![],
previous_outputs: None,
outputs: vec![NodeOutput::new(0, 0)],
outputs: vec![NodeOutput::new(NodeId(0), 0)],
nodes: [(
0,
NodeId(0),
DocumentNode {
name: "Image Filter".into(),
inputs: vec![NodeInput::Network(concrete!(Color))],
@ -433,7 +433,7 @@ async fn blend_gpu_image(foreground: ImageFrame<Color>, background: ImageFrame<C
let network = NodeNetwork {
inputs: vec![],
outputs: vec![NodeOutput::new(0, 0)],
outputs: vec![NodeOutput::new(NodeId(0), 0)],
nodes: [DocumentNode {
name: "BlendOp".into(),
inputs: vec![NodeInput::Inline(InlineRust::new(
@ -464,7 +464,7 @@ async fn blend_gpu_image(foreground: ImageFrame<Color>, background: ImageFrame<C
}]
.into_iter()
.enumerate()
.map(|(id, node)| (id as NodeId, node))
.map(|(id, node)| (NodeId(id as u64), node))
.collect(),
..Default::default()
};

View file

@ -193,10 +193,10 @@ mod test {
let mut tree = BorrowTree::default();
let val_1_protonode = ProtoNode::value(ConstructionArgs::Value(TaggedValue::U32(2u32)), vec![]);
let context = TypingContext::default();
let future = tree.push_node(0, val_1_protonode, &context); //.await.unwrap();
let future = tree.push_node(NodeId(0), val_1_protonode, &context); //.await.unwrap();
futures::executor::block_on(future).unwrap();
let _node = tree.get(0).unwrap();
let result = futures::executor::block_on(tree.eval(0, ()));
let _node = tree.get(NodeId(0)).unwrap();
let result = futures::executor::block_on(tree.eval(NodeId(0), ()));
assert_eq!(result, Some(2u32));
}
}

View file

@ -16,11 +16,11 @@ mod tests {
fn add_network() -> NodeNetwork {
NodeNetwork {
inputs: vec![0, 0],
outputs: vec![NodeOutput::new(1, 0)],
inputs: vec![NodeId(0), NodeId(0)],
outputs: vec![NodeOutput::new(NodeId(1), 0)],
nodes: [
(
0,
NodeId(0),
DocumentNode {
name: "Cons".into(),
inputs: vec![NodeInput::Network(concrete!(u32)), NodeInput::Network(concrete!(&u32))],
@ -29,10 +29,10 @@ mod tests {
},
),
(
1,
NodeId(1),
DocumentNode {
name: "Add".into(),
inputs: vec![NodeInput::node(0, 0)],
inputs: vec![NodeInput::node(NodeId(0), 0)],
implementation: DocumentNodeImplementation::Unresolved(ProtoNodeIdentifier::new("graphene_core::ops::AddPairNode")),
..Default::default()
},
@ -45,10 +45,10 @@ mod tests {
}
let network = NodeNetwork {
inputs: vec![0],
outputs: vec![NodeOutput::new(0, 0)],
inputs: vec![NodeId(0)],
outputs: vec![NodeOutput::new(NodeId(0), 0)],
nodes: [(
0,
NodeId(0),
DocumentNode {
name: "Inc".into(),
inputs: vec![
@ -86,12 +86,12 @@ mod tests {
use graph_craft::*;
let network = NodeNetwork {
inputs: vec![0],
outputs: vec![NodeOutput::new(1, 0)],
inputs: vec![NodeId(0)],
outputs: vec![NodeOutput::new(NodeId(1), 0)],
nodes: [
// Simple identity node taking a number as input from outside the graph
(
0,
NodeId(0),
DocumentNode {
name: "id".into(),
inputs: vec![NodeInput::Network(concrete!(u32))],
@ -101,10 +101,10 @@ mod tests {
),
// An add node adding the result of the id node to its self
(
1,
NodeId(1),
DocumentNode {
name: "Add".into(),
inputs: vec![NodeInput::node(0, 0), NodeInput::node(0, 0)],
inputs: vec![NodeInput::node(NodeId(0), 0), NodeInput::node(NodeId(0), 0)],
implementation: DocumentNodeImplementation::Unresolved(ProtoNodeIdentifier::new("graphene_core::ops::AddNode<_>")),
..Default::default()
},

View file

@ -121,11 +121,11 @@ fn create_buffer<T: Pod + Send + Sync>(data: Vec<T>, alloc: &StandardMemoryAlloc
// fn inc_network() -> ProtoNetwork {
// let mut construction_network = ProtoNetwork {
// inputs: vec![10],
// output: 1,
// inputs: vec![NodeId(10)],
// output: NodeId(1),
// nodes: [
// (
// 1,
// NodeId(1),
// ProtoNode {
// identifier: ProtoNodeIdentifier::new("graphene_core::ops::IdentityNode", &[generic!("u32")]),
// input: ProtoNodeInput::Node(11),
@ -133,7 +133,7 @@ fn create_buffer<T: Pod + Send + Sync>(data: Vec<T>, alloc: &StandardMemoryAlloc
// },
// ),
// (
// 10,
// NodeId(10),
// ProtoNode {
// identifier: ProtoNodeIdentifier::new("graphene_core::structural::ConsNode", &[generic!("&ValueNode<u32>"), generic!("()")]),
// input: ProtoNodeInput::Network,
@ -141,7 +141,7 @@ fn create_buffer<T: Pod + Send + Sync>(data: Vec<T>, alloc: &StandardMemoryAlloc
// },
// ),
// (
// 11,
// NodeId(11),
// ProtoNode {
// identifier: ProtoNodeIdentifier::new("graphene_core::ops::AddPairNode", &[generic!("u32"), generic!("u32")]),
// input: ProtoNodeInput::Node(10),
@ -149,7 +149,7 @@ fn create_buffer<T: Pod + Send + Sync>(data: Vec<T>, alloc: &StandardMemoryAlloc
// },
// ),
// (
// 14,
// NodeId(14),
// ProtoNode {
// identifier: ProtoNodeIdentifier::new("graphene_core::value::ValueNode", &[concrete!("u32")]),
// input: ProtoNodeInput::None,

View file

@ -203,11 +203,11 @@ async fn execute_shader<I: Pod + Send + Sync, O: Pod + Send + Sync>(device: Arc<
// fn inc_network() -> ProtoNetwork {
// let mut construction_network = ProtoNetwork {
// inputs: vec![10],
// output: 1,
// inputs: vec![NodeId(10)],
// output: NodeId(1),
// nodes: [
// (
// 1,
// NodeId(1),
// ProtoNode {
// identifier: ProtoNodeIdentifier::new("graphene_core::ops::IdentityNode", &[generic!("u32")]),
// input: ProtoNodeInput::Node(11),
@ -215,7 +215,7 @@ async fn execute_shader<I: Pod + Send + Sync, O: Pod + Send + Sync>(device: Arc<
// },
// ),
// (
// 10,
// NodeId(10),
// ProtoNode {
// identifier: ProtoNodeIdentifier::new("graphene_core::structural::ConsNode", &[generic!("&ValueNode<u32>"), generic!("()")]),
// input: ProtoNodeInput::Network,
@ -223,7 +223,7 @@ async fn execute_shader<I: Pod + Send + Sync, O: Pod + Send + Sync>(device: Arc<
// },
// ),
// (
// 11,
// NodeId(11),
// ProtoNode {
// identifier: ProtoNodeIdentifier::new("graphene_core::ops::AddPairNode", &[generic!("u32"), generic!("u32")]),
// input: ProtoNodeInput::Node(10),
@ -231,7 +231,7 @@ async fn execute_shader<I: Pod + Send + Sync, O: Pod + Send + Sync>(device: Arc<
// },
// ),
// (
// 14,
// NodeId(14),
// ProtoNode {
// identifier: ProtoNodeIdentifier::new("graphene_core::value::ValueNode", &[concrete!("u32")]),
// input: ProtoNodeInput::None,