diff --git a/editor/src/messages/portfolio/document/utility_types/network_interface.rs b/editor/src/messages/portfolio/document/utility_types/network_interface.rs index 9007c8c72a..cd918a7979 100644 --- a/editor/src/messages/portfolio/document/utility_types/network_interface.rs +++ b/editor/src/messages/portfolio/document/utility_types/network_interface.rs @@ -3421,10 +3421,7 @@ impl NodeNetworkInterface { pub fn create_wire(&mut self, output_connector: &OutputConnector, input_connector: &InputConnector, network_path: &[NodeId]) { let input = match output_connector { OutputConnector::Node { node_id, output_index } => NodeInput::node(*node_id, *output_index), - OutputConnector::Import(import_index) => NodeInput::Network { - import_type: graph_craft::generic!(T), - import_index: *import_index, - }, + OutputConnector::Import(import_index) => NodeInput::Network { import_index: *import_index }, }; self.set_input(input_connector, input, network_path); diff --git a/editor/src/node_graph_executor.rs b/editor/src/node_graph_executor.rs index 1dd24236e3..50dc913db5 100644 --- a/editor/src/node_graph_executor.rs +++ b/editor/src/node_graph_executor.rs @@ -229,7 +229,7 @@ impl NodeRuntime { // We assume only one output assert_eq!(scoped_network.exports.len(), 1, "Graph with multiple outputs not yet handled"); let c = Compiler {}; - let proto_network = match c.compile_single(scoped_network) { + let proto_network = match c.compile_single(scoped_network, &[concrete!(RenderConfig)]) { Ok(network) => network, Err(e) => return Err(e), }; diff --git a/frontend/src/components/widgets/inputs/NumberInput.svelte b/frontend/src/components/widgets/inputs/NumberInput.svelte index bec4d11369..5738518027 100644 --- a/frontend/src/components/widgets/inputs/NumberInput.svelte +++ b/frontend/src/components/widgets/inputs/NumberInput.svelte @@ -30,6 +30,7 @@ // Number presentation export let displayDecimalPlaces = 2; export let unit = ""; + $: console.info("new unit", unit); export let unitIsHiddenWhenEditing = true; // Mode behavior diff --git a/node-graph/compilation-client/src/main.rs b/node-graph/compilation-client/src/main.rs index 7d1dc662a2..64ee42a4bd 100644 --- a/node-graph/compilation-client/src/main.rs +++ b/node-graph/compilation-client/src/main.rs @@ -13,7 +13,8 @@ fn main() { let network = add_network(); let compiler = graph_craft::graphene_compiler::Compiler {}; - let proto_network = compiler.compile_single(network).unwrap(); + let input_types = vec![concrete!(Color), concrete!(Color), concrete!(u32)]; + let proto_network = compiler.compile_single(network, &input_types).unwrap(); let io = ShaderIO { inputs: vec![ @@ -25,7 +26,7 @@ fn main() { output: ShaderInput::OutputBuffer((), concrete!(Color)), }; - let compile_request = CompileRequest::new(vec![proto_network], vec![concrete!(Color), concrete!(Color), concrete!(u32)], vec![concrete!(Color)], io); + let compile_request = CompileRequest::new(vec![proto_network], input_types, vec![concrete!(Color)], io); let response = client .post("http://localhost:3000/compile/spirv") .timeout(Duration::from_secs(30)) diff --git a/node-graph/graph-craft/benches/compile_demo_art_criterion.rs b/node-graph/graph-craft/benches/compile_demo_art_criterion.rs index 5e3264cd52..e432f329fd 100644 --- a/node-graph/graph-craft/benches/compile_demo_art_criterion.rs +++ b/node-graph/graph-craft/benches/compile_demo_art_criterion.rs @@ -1,12 +1,14 @@ use criterion::{black_box, criterion_group, criterion_main, Criterion}; use graph_craft::util::DEMO_ART; fn compile_to_proto(c: &mut Criterion) { - use graph_craft::util::{compile, load_from_name}; + use graph_craft::util::{compile_with_render_config, load_from_name}; let mut c = c.benchmark_group("Compile Network cold"); for name in DEMO_ART { let network = load_from_name(name); - c.bench_function(name, |b| b.iter_batched(|| network.clone(), |network| compile(black_box(network)), criterion::BatchSize::SmallInput)); + c.bench_function(name, |b| { + b.iter_batched(|| network.clone(), |network| compile_with_render_config(black_box(network)), criterion::BatchSize::SmallInput) + }); } } diff --git a/node-graph/graph-craft/benches/compile_demo_art_iai.rs b/node-graph/graph-craft/benches/compile_demo_art_iai.rs index 4ff9893ad7..2b66d668cd 100644 --- a/node-graph/graph-craft/benches/compile_demo_art_iai.rs +++ b/node-graph/graph-craft/benches/compile_demo_art_iai.rs @@ -5,7 +5,7 @@ use iai_callgrind::{black_box, library_benchmark, library_benchmark_group, main} #[library_benchmark] #[benches::with_setup(args = ["isometric-fountain", "painted-dreams", "procedural-string-lights", "red-dress", "valley-of-spires"], setup = load_from_name)] pub fn compile_to_proto(_input: NodeNetwork) { - black_box(compile(_input)); + black_box(compile_with_render_config(_input)); } library_benchmark_group!(name = compile_group; benchmarks = compile_to_proto); diff --git a/node-graph/graph-craft/src/document.rs b/node-graph/graph-craft/src/document.rs index b0a0f64c58..13da84cfe1 100644 --- a/node-graph/graph-craft/src/document.rs +++ b/node-graph/graph-craft/src/document.rs @@ -286,7 +286,7 @@ impl DocumentNode { } } - fn resolve_proto_node(mut self) -> ProtoNode { + fn resolve_proto_node(mut self, global_import_types: &[Type]) -> ProtoNode { assert!(!self.inputs.is_empty() || self.manual_composition.is_some(), "Resolving document node {self:#?} with no inputs"); let DocumentNodeImplementation::ProtoNode(fqn) = self.implementation else { unreachable!("tried to resolve not flattened node on resolved node {self:?}"); @@ -311,7 +311,10 @@ impl DocumentNode { let node = if lambda { ProtoNodeInput::NodeLambda(node_id) } else { ProtoNodeInput::Node(node_id) }; (node, ConstructionArgs::Nodes(vec![])) } - NodeInput::Network { import_type, .. } => (ProtoNodeInput::ManualComposition(import_type), ConstructionArgs::Nodes(vec![])), + NodeInput::Network { import_index } => { + let ty = global_import_types.get(import_index).expect("import index in global_import_types").clone(); + (ProtoNodeInput::ManualComposition(ty), ConstructionArgs::Nodes(vec![])) + } NodeInput::Inline(inline) => (ProtoNodeInput::None, ConstructionArgs::Inline(inline)), NodeInput::Scope(_) => unreachable!("Scope input was not resolved"), NodeInput::Reflection(_) => unreachable!("Reflection input was not resolved"), @@ -355,9 +358,8 @@ pub enum NodeInput { /// A hardcoded value that can't change after the graph is compiled. Gets converted into a value node during graph compilation. Value { tagged_value: MemoHash, exposed: bool }, - // TODO: Remove import_type and get type from parent node input /// Input that is provided by the parent network to this document node, instead of from a hardcoded value or another node within the same network. - Network { import_type: Type, import_index: usize }, + Network { import_index: usize }, /// Input that is extracted from the parent scopes the node resides in. The string argument is the key. Scope(Cow<'static, str>), @@ -403,8 +405,8 @@ impl NodeInput { Self::Value { tagged_value, exposed } } - pub const fn network(import_type: Type, import_index: usize) -> Self { - Self::Network { import_type, import_index } + pub fn network(_import_type: Type, import_index: usize) -> Self { + Self::Network { import_index } } pub fn scope(key: impl Into>) -> Self { @@ -447,7 +449,7 @@ impl NodeInput { match self { NodeInput::Node { .. } => unreachable!("ty() called on NodeInput::Node"), NodeInput::Value { tagged_value, .. } => tagged_value.ty(), - NodeInput::Network { import_type, .. } => import_type.clone(), + NodeInput::Network { .. } => unreachable!("ty() called on NodeInput::Network"), NodeInput::Inline(_) => panic!("ty() called on NodeInput::Inline"), NodeInput::Scope(_) => unreachable!("ty() called on NodeInput::Scope"), NodeInput::Reflection(_) => concrete!(Metadata), @@ -1312,8 +1314,8 @@ impl NodeNetwork { } /// Creates a proto network for evaluating each output of this network. - pub fn into_proto_networks(self) -> impl Iterator { - let nodes: Vec<_> = self.nodes.into_iter().map(|(id, node)| (id, node.resolve_proto_node())).collect(); + pub fn into_proto_networks(self, global_import_types: &[Type]) -> impl Iterator { + let nodes: Vec<_> = self.nodes.into_iter().map(|(id, node)| (id, node.resolve_proto_node(global_import_types))).collect(); // Create a network to evaluate each output if self.exports.len() == 1 { @@ -1507,7 +1509,7 @@ mod test { ..Default::default() }; - let proto_node = document_node.resolve_proto_node(); + let proto_node = document_node.resolve_proto_node(&[concrete!(u32)]); let reference = ProtoNode { identifier: "graphene_core::structural::ConsNode".into(), input: ProtoNodeInput::ManualComposition(concrete!(u32)), @@ -1577,7 +1579,7 @@ mod test { .collect(), }; let network = flat_network(); - let mut resolved_network = network.into_proto_networks().collect::>(); + let mut resolved_network = network.into_proto_networks(&[concrete!(u32)]).collect::>(); resolved_network[0].nodes.sort_unstable_by_key(|(id, _)| *id); println!("{:#?}", resolved_network[0]); diff --git a/node-graph/graph-craft/src/graphene_compiler.rs b/node-graph/graph-craft/src/graphene_compiler.rs index 41a8182017..f5b5ce1b0d 100644 --- a/node-graph/graph-craft/src/graphene_compiler.rs +++ b/node-graph/graph-craft/src/graphene_compiler.rs @@ -6,7 +6,7 @@ use crate::proto::{LocalFuture, ProtoNetwork}; pub struct Compiler {} impl Compiler { - pub fn compile(&self, mut network: NodeNetwork) -> impl Iterator> { + pub fn compile(&self, mut network: NodeNetwork, global_import_types: &[crate::Type]) -> impl Iterator> { let node_ids = network.nodes.keys().copied().collect::>(); network.populate_dependants(); for id in node_ids { @@ -15,7 +15,7 @@ impl Compiler { network.resolve_scope_inputs(); network.remove_redundant_id_nodes(); // network.remove_dead_nodes(0); - let proto_networks = network.into_proto_networks(); + let proto_networks = network.into_proto_networks(global_import_types); proto_networks.map(move |mut proto_network| { proto_network.resolve_inputs()?; @@ -23,9 +23,9 @@ impl Compiler { Ok(proto_network) }) } - pub fn compile_single(&self, network: NodeNetwork) -> Result { + pub fn compile_single(&self, network: NodeNetwork, global_import_types: &[crate::Type]) -> Result { assert_eq!(network.exports.len(), 1, "Graph with multiple outputs not yet handled"); - let Some(proto_network) = self.compile(network).next() else { + let Some(proto_network) = self.compile(network, global_import_types).next() else { return Err("Failed to convert graph into proto graph".to_string()); }; proto_network diff --git a/node-graph/graph-craft/src/util.rs b/node-graph/graph-craft/src/util.rs index 3eb78d5a84..4ea1d65385 100644 --- a/node-graph/graph-craft/src/util.rs +++ b/node-graph/graph-craft/src/util.rs @@ -7,9 +7,9 @@ pub fn load_network(document_string: &str) -> NodeNetwork { serde_json::from_value::(document["network_interface"]["network"].clone()).expect("Failed to parse document") } -pub fn compile(network: NodeNetwork) -> ProtoNetwork { +pub fn compile_with_render_config(network: NodeNetwork) -> ProtoNetwork { let compiler = Compiler {}; - compiler.compile_single(network).unwrap() + compiler.compile_single(network, &[concrete!(graphene_core::application_io::RenderConfig)]).unwrap() } pub fn load_from_name(name: &str) -> NodeNetwork { diff --git a/node-graph/graphene-cli/src/main.rs b/node-graph/graphene-cli/src/main.rs index 2ac5bc3927..d3d07a8774 100644 --- a/node-graph/graphene-cli/src/main.rs +++ b/node-graph/graphene-cli/src/main.rs @@ -1,7 +1,7 @@ -use graph_craft::document::*; use graph_craft::graphene_compiler::{Compiler, Executor}; use graph_craft::util::load_network; use graph_craft::wasm_application_io::EditorPreferences; +use graph_craft::{concrete, document::*}; use graphene_core::application_io::{ApplicationIo, NodeGraphUpdateSender}; use graphene_core::text::FontCache; use graphene_std::wasm_application_io::{WasmApplicationIo, WasmEditorApi}; @@ -105,7 +105,7 @@ fn create_executor(document_string: String, editor_api: Arc) -> R let wrapped_network = wrap_network_in_scope(network.clone(), editor_api); let compiler = Compiler {}; - let protograph = compiler.compile_single(wrapped_network)?; + let protograph = compiler.compile_single(wrapped_network, &[concrete!(graphene_core::application_io::RenderConfig)])?; let executor = block_on(DynamicExecutor::new(protograph)).unwrap(); Ok(executor) } diff --git a/node-graph/gstd/src/gpu_nodes.rs b/node-graph/gstd/src/gpu_nodes.rs index d3d9534e99..f45800836e 100644 --- a/node-graph/gstd/src/gpu_nodes.rs +++ b/node-graph/gstd/src/gpu_nodes.rs @@ -18,23 +18,17 @@ use crate::wasm_application_io::WasmApplicationIo; // TODO: Move to graph-craft #[node_macro::node(category("Debug: GPU"))] -async fn compile_gpu<'a: 'n>(_: (), node: &'a DocumentNode, typing_context: TypingContext, io: ShaderIO) -> Result { +async fn compile_gpu<'a: 'n>(_: (), node: &'a DocumentNode, typing_context: TypingContext, input_types: Vec, io: ShaderIO) -> Result { let mut typing_context = typing_context; let compiler = graph_craft::graphene_compiler::Compiler {}; let DocumentNodeImplementation::Network(ref network) = node.implementation else { panic!() }; - let proto_networks: Result, _> = compiler.compile(network.clone()).collect(); + let proto_networks: Result, _> = compiler.compile(network.clone(), &input_types).collect(); let proto_networks = proto_networks?; for network in proto_networks.iter() { typing_context.update(network).expect("Failed to type check network"); } // TODO: do a proper union - let input_types = proto_networks[0] - .inputs - .iter() - .map(|id| typing_context.type_of(*id).unwrap()) - .map(|node_io| node_io.return_value.clone()) - .collect(); let output_types = proto_networks.iter().map(|network| typing_context.type_of(network.output).unwrap().return_value.clone()).collect(); Ok(compilation_client::compile(proto_networks, input_types, output_types, io).await.unwrap()) @@ -187,11 +181,12 @@ async fn create_compute_pass_descriptor(node ..Default::default() }; log::debug!("compiling network"); - let proto_networks: Result, _> = compiler.compile(network.clone()).collect(); + let global_input_types = vec![concrete!(u32), concrete!(Color)]; + let proto_networks: Result, _> = compiler.compile(network.clone(), &global_input_types).collect(); log::debug!("compiling shader"); let shader = compilation_client::compile( proto_networks?, - vec![concrete!(u32), concrete!(Color)], + global_input_types, vec![concrete!(Color)], ShaderIO { inputs: vec![ @@ -317,7 +312,15 @@ async fn blend_gpu_image(_: (), foreground: ImageFrame, background: Image ..Default::default() }; log::debug!("compiling network"); - let proto_networks: Result, _> = compiler.compile(network.clone()).collect(); + let global_input_types = vec![ + concrete!(u32), + concrete!(Color), + concrete!(Color), + concrete!(u32), + concrete_with_name!(Mat2, "Mat2"), + concrete_with_name!(Vec2, "Vec2"), + ]; + let proto_networks: Result, _> = compiler.compile(network.clone(), &global_input_types).collect(); let Ok(proto_networks_result) = proto_networks else { log::error!("Error compiling network in 'blend_gpu_image()"); return ImageFrame::empty(); @@ -327,14 +330,7 @@ async fn blend_gpu_image(_: (), foreground: ImageFrame, background: Image let shader = compilation_client::compile( proto_networks, - vec![ - concrete!(u32), - concrete!(Color), - concrete!(Color), - concrete!(u32), - concrete_with_name!(Mat2, "Mat2"), - concrete_with_name!(Vec2, "Vec2"), - ], + global_input_types, vec![concrete!(Color)], ShaderIO { inputs: vec![ diff --git a/node-graph/interpreted-executor/benches/benchmark_util.rs b/node-graph/interpreted-executor/benches/benchmark_util.rs index 1d4ef43307..b690622450 100644 --- a/node-graph/interpreted-executor/benches/benchmark_util.rs +++ b/node-graph/interpreted-executor/benches/benchmark_util.rs @@ -2,13 +2,13 @@ use criterion::{measurement::Measurement, BenchmarkGroup}; use futures::executor::block_on; use graph_craft::{ proto::ProtoNetwork, - util::{compile, load_from_name, DEMO_ART}, + util::{compile_with_render_config, load_from_name, DEMO_ART}, }; use interpreted_executor::dynamic_executor::DynamicExecutor; pub fn setup_network(name: &str) -> (DynamicExecutor, ProtoNetwork) { let network = load_from_name(name); - let proto_network = compile(network); + let proto_network = compile_with_render_config(network); let executor = block_on(DynamicExecutor::new(proto_network.clone())).unwrap(); (executor, proto_network) } diff --git a/node-graph/interpreted-executor/benches/run_demo_art_criterion.rs b/node-graph/interpreted-executor/benches/run_demo_art_criterion.rs index 76789ae5d5..e84fcbf576 100644 --- a/node-graph/interpreted-executor/benches/run_demo_art_criterion.rs +++ b/node-graph/interpreted-executor/benches/run_demo_art_criterion.rs @@ -2,14 +2,14 @@ use criterion::{black_box, criterion_group, criterion_main, measurement::Measure use graph_craft::{ graphene_compiler::Executor, proto::ProtoNetwork, - util::{compile, load_from_name, DEMO_ART}, + util::{compile_with_render_config, load_from_name, DEMO_ART}, }; use graphene_std::transform::Footprint; use interpreted_executor::dynamic_executor::DynamicExecutor; fn update_executor(name: &str, c: &mut BenchmarkGroup) { let network = load_from_name(name); - let proto_network = compile(network); + let proto_network = compile_with_render_config(network); let empty = ProtoNetwork::default(); let executor = futures::executor::block_on(DynamicExecutor::new(empty)).unwrap(); @@ -32,7 +32,7 @@ fn update_executor_demo(c: &mut Criterion) { fn run_once(name: &str, c: &mut BenchmarkGroup) { let network = load_from_name(name); - let proto_network = compile(network); + let proto_network = compile_with_render_config(network); let executor = futures::executor::block_on(DynamicExecutor::new(proto_network)).unwrap(); let footprint = Footprint::default(); diff --git a/node-graph/interpreted-executor/src/lib.rs b/node-graph/interpreted-executor/src/lib.rs index 5a87a995fe..a62c5fa96b 100644 --- a/node-graph/interpreted-executor/src/lib.rs +++ b/node-graph/interpreted-executor/src/lib.rs @@ -44,7 +44,7 @@ mod tests { use graph_craft::graphene_compiler::Compiler; let compiler = Compiler {}; - let protograph = compiler.compile_single(network).expect("Graph should be generated"); + let protograph = compiler.compile_single(network, &[concrete!(u32)]).expect("Graph should be generated"); let _exec = block_on(DynamicExecutor::new(protograph)).map(|_e| panic!("The network should not type check ")).unwrap_err(); }