Introduce scopes (#1053)

* Implement let binding

* Add lambda inputs

* Fix tests

* Fix proto network formatting

* Generate a template Scoped network by default

* Add comment to explain the lambda parameter

* Move binding wrapping out of the template

* Fix errors cause by image frames
This commit is contained in:
Dennis Kobert
2023-03-02 17:13:28 +01:00
committed by Keavon Chambers
parent 0b813805d2
commit 7254c008f9
12 changed files with 366 additions and 118 deletions

View File

@@ -1,4 +1,5 @@
use crate::messages::frontend::utility_types::FrontendImageData;
use crate::messages::portfolio::document::node_graph::wrap_network_in_scope;
use crate::messages::portfolio::document::utility_types::misc::DocumentRenderMode;
use crate::messages::portfolio::utility_types::PersistentData;
use crate::messages::prelude::*;
@@ -20,16 +21,18 @@ pub struct NodeGraphExecutor {
impl NodeGraphExecutor {
/// Execute the network by flattening it and creating a borrow stack. Casts the output to the generic `T`.
fn execute_network<T: dyn_any::StaticType>(&mut self, mut network: NodeNetwork, image_frame: ImageFrame) -> Result<T, String> {
network.duplicate_outputs(&mut generate_uuid);
network.remove_dead_nodes();
fn execute_network<T: dyn_any::StaticType>(&mut self, network: NodeNetwork, image_frame: ImageFrame) -> Result<T, String> {
let mut scoped_network = wrap_network_in_scope(network);
debug!("Execute document network:\n{network:#?}");
scoped_network.duplicate_outputs(&mut generate_uuid);
scoped_network.remove_dead_nodes();
debug!("Execute document network:\n{scoped_network:#?}");
// We assume only one output
assert_eq!(network.outputs.len(), 1, "Graph with multiple outputs not yet handled");
assert_eq!(scoped_network.outputs.len(), 1, "Graph with multiple outputs not yet handled");
let c = Compiler {};
let proto_network = c.compile_single(network, true)?;
let proto_network = c.compile_single(scoped_network, true)?;
debug!("Execute proto network:\n{proto_network}");
assert_ne!(proto_network.nodes.len(), 0, "No protonodes exist?");
if let Err(e) = self.executor.update(proto_network) {
@@ -74,7 +77,7 @@ impl NodeGraphExecutor {
// If the input is just a value, return that value
NodeInput::Value { tagged_value, .. } => return dyn_any::downcast::<T>(tagged_value.clone().to_any()).map(|v| *v),
// If the input is from a node, set the node to be the output (so that is what is evaluated)
NodeInput::Node { node_id, output_index } => {
NodeInput::Node { node_id, output_index, .. } => {
inner_network.outputs[0] = NodeOutput::new(*node_id, *output_index);
break 'outer;
}