@@ -177,26 +177,13 @@ impl NodeNetworkInterface {
177177 let mut last_chain_node_distance = 0u32 ;
178178 // Iterate upstream from the layer, and get the number of nodes distance to the last node with Position::Chain
179179 for ( index, node_id) in self
180- . upstream_flow_back_from_nodes ( vec ! [ * node_id] , network_path, FlowType :: HorizontalFlow )
180+ . upstream_flow_back_from_nodes ( vec ! [ * node_id] , network_path, FlowType :: HorizontalPrimaryOutputFlow )
181181 . skip ( 1 )
182182 . enumerate ( )
183183 . collect :: < Vec < _ > > ( )
184184 {
185- let Some ( network_metadata) = self . network_metadata ( network_path) else {
186- log:: error!( "Could not get nested network_metadata in chain_width" ) ;
187- return 0 ;
188- } ;
189185 // Check if the node is positioned as a chain
190- let is_chain = network_metadata
191- . persistent_metadata
192- . node_metadata
193- . get ( & node_id)
194- . map ( |node_metadata| & node_metadata. persistent_metadata . node_type_metadata )
195- . is_some_and ( |node_type_metadata| match node_type_metadata {
196- NodeTypePersistentMetadata :: Node ( node_persistent_metadata) => matches ! ( node_persistent_metadata. position, NodePosition :: Chain ) ,
197- _ => false ,
198- } ) ;
199- if is_chain {
186+ if self . is_chain ( & node_id, network_path) {
200187 last_chain_node_distance = ( index as u32 ) + 1 ;
201188 } else {
202189 return last_chain_node_distance * 7 + 1 ;
@@ -326,7 +313,7 @@ impl NodeNetworkInterface {
326313 /// Creates a copy for each node by disconnecting nodes which are not connected to other copied nodes.
327314 /// Returns an iterator of all persistent metadata for a node and their ids
328315 pub fn copy_nodes < ' a > ( & ' a mut self , new_ids : & ' a HashMap < NodeId , NodeId > , network_path : & ' a [ NodeId ] ) -> impl Iterator < Item = ( NodeId , NodeTemplate ) > + ' a {
329- new_ids
316+ let mut new_nodes = new_ids
330317 . iter ( )
331318 . filter_map ( |( node_id, & new) | {
332319 self . create_node_template ( node_id, network_path) . and_then ( |mut node_template| {
@@ -354,7 +341,7 @@ impl NodeNetworkInterface {
354341 } ;
355342 }
356343
357- // Ensure a chain node has a selected downstream layer, and set absolute nodes to a chain if there is a downstream layer
344+ // If a chain node does not have a selected downstream layer, then set the position to absolute
358345 let downstream_layer = self . downstream_layer ( node_id, network_path) ;
359346 if downstream_layer. map_or ( true , |downstream_layer| new_ids. keys ( ) . all ( |key| * key != downstream_layer. to_node ( ) ) ) {
360347 let Some ( position) = self . position ( node_id, network_path) else {
@@ -364,20 +351,6 @@ impl NodeNetworkInterface {
364351 node_template. persistent_node_metadata . node_type_metadata = NodeTypePersistentMetadata :: Node ( NodePersistentMetadata {
365352 position : NodePosition :: Absolute ( position) ,
366353 } ) ;
367- } else if !self . is_layer ( node_id, network_path) {
368- if let Some ( downstream_layer) = downstream_layer {
369- if self
370- . upstream_flow_back_from_nodes ( vec ! [ downstream_layer. to_node( ) ] , network_path, FlowType :: HorizontalFlow )
371- . skip ( 1 )
372- . take_while ( |node_id| !self . is_layer ( node_id, network_path) )
373- . any ( |upstream_node| upstream_node == * node_id)
374- {
375- match & mut node_template. persistent_node_metadata . node_type_metadata {
376- NodeTypePersistentMetadata :: Node ( node_metadata) => node_metadata. position = NodePosition :: Chain ,
377- NodeTypePersistentMetadata :: Layer ( _) => log:: error!( "Node is not be a layer" ) ,
378- } ;
379- }
380- }
381354 }
382355
383356 // Shift all absolute nodes 2 to the right and 2 down
@@ -395,12 +368,25 @@ impl NodeNetworkInterface {
395368 }
396369 }
397370
398- Some ( ( new, node_id, node_template) )
371+ Some ( ( new, * node_id, node_template) )
399372 } )
400373 } )
401- . collect :: < Vec < _ > > ( )
402- . into_iter ( )
403- . map ( move |( new, node_id, node) | ( new, self . map_ids ( node, node_id, new_ids, network_path) ) )
374+ . collect :: < Vec < _ > > ( ) ;
375+
376+ for old_id in new_nodes. iter ( ) . map ( |( _, old_id, _) | * old_id) . collect :: < Vec < _ > > ( ) {
377+ // Try set all selected nodes upstream of a layer to be chain nodes
378+ if self . is_layer ( & old_id, network_path) {
379+ for valid_upstream_chain_node in self . valid_upstream_chain_nodes ( & InputConnector :: node ( old_id, 1 ) , network_path) {
380+ if let Some ( node_template) = new_nodes. iter_mut ( ) . find_map ( |( _, old_id, template) | ( * old_id == valid_upstream_chain_node) . then_some ( template) ) {
381+ match & mut node_template. persistent_node_metadata . node_type_metadata {
382+ NodeTypePersistentMetadata :: Node ( node_metadata) => node_metadata. position = NodePosition :: Chain ,
383+ NodeTypePersistentMetadata :: Layer ( _) => log:: error!( "Node cannot be a layer" ) ,
384+ } ;
385+ }
386+ }
387+ }
388+ }
389+ new_nodes. into_iter ( ) . map ( move |( new, node_id, node) | ( new, self . map_ids ( node, & node_id, new_ids, network_path) ) )
404390 }
405391
406392 /// Create a node template from an existing node.
@@ -2060,7 +2046,6 @@ impl NodeNetworkInterface {
20602046 log:: error!( "Could not get nested network in load_outward_wires" ) ;
20612047 return ;
20622048 } ;
2063- log:: debug!( "network: {network:?}" ) ;
20642049 // Initialize all output connectors for nodes
20652050 for ( node_id, _) in network. nodes . iter ( ) {
20662051 let number_of_outputs = self . number_of_outputs ( node_id, network_path) ;
@@ -2072,12 +2057,9 @@ impl NodeNetworkInterface {
20722057 for import_index in 0 ..self . number_of_imports ( network_path) {
20732058 outward_wires. insert ( OutputConnector :: Import ( import_index) , Vec :: new ( ) ) ;
20742059 }
2075- log:: debug!( "Initialized outward_wires: {:?}" , outward_wires) ;
20762060 // Collect wires between all nodes and the Imports
20772061 for ( current_node_id, node) in network. nodes . iter ( ) {
2078- log:: debug!( "node: {node:?}, id: {current_node_id:?}" ) ;
20792062 for ( input_index, input) in node. inputs . iter ( ) . enumerate ( ) {
2080- log:: debug!( "input: {input:?}" ) ;
20812063 if let NodeInput :: Node { node_id, output_index, .. } = input {
20822064 // If this errors then there is an input to a node that does not exist
20832065 let outward_wires_entry = outward_wires. get_mut ( & OutputConnector :: node ( * node_id, * output_index) ) . expect ( & format ! (
@@ -2095,7 +2077,6 @@ impl NodeNetworkInterface {
20952077 }
20962078 }
20972079 for ( export_index, export) in network. exports . iter ( ) . enumerate ( ) {
2098- log:: debug!( "export: {export:?}" ) ;
20992080 if let NodeInput :: Node { node_id, output_index, .. } = export {
21002081 let outward_wires_entry = outward_wires. get_mut ( & OutputConnector :: node ( * node_id, * output_index) ) . expect ( & format ! (
21012082 "Output connector {:?} should be initialized for each node input from exports" ,
@@ -4103,74 +4084,84 @@ impl NodeNetworkInterface {
41034084 self . unload_all_nodes_bounding_box ( network_path) ;
41044085 }
41054086
4106- /// Input connector is the input to the layer
4107- pub fn try_set_upstream_to_chain ( & mut self , input_connector : & InputConnector , network_path : & [ NodeId ] ) {
4108- // If the new input is to a non layer node on the same y position as the input connector, or the input connector is the side input of a layer, then set it to chain position
4109- if let InputConnector :: Node {
4087+ fn valid_upstream_chain_nodes ( & mut self , input_connector : & InputConnector , network_path : & [ NodeId ] ) -> Vec < NodeId > {
4088+ let InputConnector :: Node {
41104089 node_id : input_connector_node_id,
41114090 input_index,
41124091 } = input_connector
4113- {
4114- let mut set_position_to_chain = false ;
4115- if self . is_layer ( input_connector_node_id, network_path) && * input_index == 1 || self . is_chain ( input_connector_node_id, network_path) && * input_index == 0 {
4116- let mut downstream_id = * input_connector_node_id;
4117- for upstream_node in self
4118- . upstream_flow_back_from_nodes ( vec ! [ * input_connector_node_id] , network_path, FlowType :: HorizontalFlow )
4119- . skip ( 1 )
4120- . collect :: < Vec < _ > > ( )
4121- {
4122- if self . is_layer ( & upstream_node, network_path) {
4123- break ;
4124- }
4125- if !self . has_primary_output ( & upstream_node, network_path) {
4126- break ;
4127- }
4128- let Some ( outward_wires) = self . outward_wires ( network_path) . and_then ( |outward_wires| outward_wires. get ( & OutputConnector :: node ( upstream_node, 0 ) ) ) else {
4129- log:: error!( "Could not get outward wires in try_set_upstream_to_chain" ) ;
4130- break ;
4131- } ;
4132- if outward_wires. len ( ) != 1 {
4133- break ;
4134- }
4135- let downstream_position = self . position ( & downstream_id, network_path) ;
4136- let upstream_node_position = self . position ( & upstream_node, network_path) ;
4137- if let ( Some ( input_connector_position) , Some ( new_upstream_node_position) ) = ( downstream_position, upstream_node_position) {
4138- if input_connector_position. y == new_upstream_node_position. y
4139- && new_upstream_node_position. x >= input_connector_position. x - 9
4140- && new_upstream_node_position. x <= input_connector_position. x
4141- {
4142- set_position_to_chain = true ;
4143- self . set_chain_position ( & upstream_node, network_path) ;
4144- } else {
4145- break ;
4146- }
4092+ else {
4093+ return Vec :: new ( ) ;
4094+ } ;
4095+ let mut set_position_to_chain = Vec :: new ( ) ;
4096+ if self . is_layer ( input_connector_node_id, network_path) && * input_index == 1 || self . is_chain ( input_connector_node_id, network_path) && * input_index == 0 {
4097+ let mut downstream_id = * input_connector_node_id;
4098+ for upstream_node in self
4099+ . upstream_flow_back_from_nodes ( vec ! [ * input_connector_node_id] , network_path, FlowType :: HorizontalFlow )
4100+ . skip ( 1 )
4101+ . collect :: < Vec < _ > > ( )
4102+ {
4103+ if self . is_layer ( & upstream_node, network_path) {
4104+ break ;
4105+ }
4106+ if !self . has_primary_output ( & upstream_node, network_path) {
4107+ break ;
4108+ }
4109+ let Some ( outward_wires) = self . outward_wires ( network_path) . and_then ( |outward_wires| outward_wires. get ( & OutputConnector :: node ( upstream_node, 0 ) ) ) else {
4110+ log:: error!( "Could not get outward wires in try_set_upstream_to_chain" ) ;
4111+ break ;
4112+ } ;
4113+ if outward_wires. len ( ) != 1 {
4114+ break ;
4115+ }
4116+ let downstream_position = self . position ( & downstream_id, network_path) ;
4117+ let upstream_node_position = self . position ( & upstream_node, network_path) ;
4118+ if let ( Some ( input_connector_position) , Some ( new_upstream_node_position) ) = ( downstream_position, upstream_node_position) {
4119+ if input_connector_position. y == new_upstream_node_position. y
4120+ && new_upstream_node_position. x >= input_connector_position. x - 9
4121+ && new_upstream_node_position. x <= input_connector_position. x
4122+ {
4123+ set_position_to_chain. push ( upstream_node) ;
41474124 } else {
41484125 break ;
41494126 }
4150- downstream_id = upstream_node;
4127+ } else {
4128+ break ;
41514129 }
4130+ downstream_id = upstream_node;
41524131 }
4153- // Reload click target of the layer which used to encapsulate the node
4154- if set_position_to_chain {
4155- let mut downstream_layer = Some ( * input_connector_node_id) ;
4156- while let Some ( downstream_layer_id) = downstream_layer {
4157- if downstream_layer_id == * input_connector_node_id || !self . is_layer ( & downstream_layer_id, network_path) {
4158- let Some ( outward_wires) = self . outward_wires ( network_path) else {
4159- log:: error!( "Could not get outward wires in try_set_upstream_to_chain" ) ;
4160- downstream_layer = None ;
4161- break ;
4162- } ;
4163- downstream_layer = outward_wires
4164- . get ( & OutputConnector :: node ( downstream_layer_id, 0 ) )
4165- . and_then ( |outward_wires| if outward_wires. len ( ) == 1 { outward_wires[ 0 ] . node_id ( ) } else { None } ) ;
4166- } else {
4132+ }
4133+ set_position_to_chain
4134+ }
4135+
4136+ /// Input connector is the input to the layer
4137+ pub fn try_set_upstream_to_chain ( & mut self , input_connector : & InputConnector , network_path : & [ NodeId ] ) {
4138+ // If the new input is to a non layer node on the same y position as the input connector, or the input connector is the side input of a layer, then set it to chain position
4139+
4140+ let valid_upstream_chain_nodes = self . valid_upstream_chain_nodes ( input_connector, network_path) ;
4141+
4142+ for node_id in & valid_upstream_chain_nodes {
4143+ self . set_chain_position ( & node_id, network_path) ;
4144+ }
4145+ // Reload click target of the layer which used to encapsulate the node
4146+ if !valid_upstream_chain_nodes. is_empty ( ) {
4147+ let mut downstream_layer = Some ( input_connector. node_id ( ) . unwrap ( ) ) ;
4148+ while let Some ( downstream_layer_id) = downstream_layer {
4149+ if downstream_layer_id == input_connector. node_id ( ) . unwrap ( ) || !self . is_layer ( & downstream_layer_id, network_path) {
4150+ let Some ( outward_wires) = self . outward_wires ( network_path) else {
4151+ log:: error!( "Could not get outward wires in try_set_upstream_to_chain" ) ;
4152+ downstream_layer = None ;
41674153 break ;
4168- }
4169- }
4170- if let Some ( downstream_layer) = downstream_layer {
4171- self . unload_node_click_targets ( & downstream_layer, network_path) ;
4154+ } ;
4155+ downstream_layer = outward_wires
4156+ . get ( & OutputConnector :: node ( downstream_layer_id, 0 ) )
4157+ . and_then ( |outward_wires| if outward_wires. len ( ) == 1 { outward_wires[ 0 ] . node_id ( ) } else { None } ) ;
4158+ } else {
4159+ break ;
41724160 }
41734161 }
4162+ if let Some ( downstream_layer) = downstream_layer {
4163+ self . unload_node_click_targets ( & downstream_layer, network_path) ;
4164+ }
41744165 }
41754166 }
41764167
@@ -4987,6 +4978,8 @@ pub enum FlowType {
49874978 PrimaryFlow ,
49884979 /// Iterate over the secondary input (inclusive) for layer nodes and primary input for non layer nodes.
49894980 HorizontalFlow ,
4981+ /// Same as horizontal flow, but only iterates over connections to primary outputs
4982+ HorizontalPrimaryOutputFlow ,
49904983 /// Upstream flow starting from the either the node (inclusive) or secondary input of the layer (not inclusive).
49914984 LayerChildrenUpstreamFlow ,
49924985}
@@ -5009,15 +5002,19 @@ impl<'a> Iterator for FlowIter<'a> {
50095002 let node_id = self . stack . pop ( ) ?;
50105003
50115004 if let ( Some ( document_node) , Some ( node_metadata) ) = ( self . network . nodes . get ( & node_id) , self . network_metadata . persistent_metadata . node_metadata . get ( & node_id) ) {
5012- let skip = if self . flow_type == FlowType :: HorizontalFlow && node_metadata. persistent_metadata . is_layer ( ) {
5005+ let skip = if matches ! ( self . flow_type, FlowType :: HorizontalFlow | FlowType :: HorizontalPrimaryOutputFlow ) && node_metadata. persistent_metadata . is_layer ( ) {
50135006 1
50145007 } else {
50155008 0
50165009 } ;
50175010 let take = if self . flow_type == FlowType :: UpstreamFlow { usize:: MAX } else { 1 } ;
50185011 let inputs = document_node. inputs . iter ( ) . skip ( skip) . take ( take) ;
50195012
5020- let node_ids = inputs. filter_map ( |input| if let NodeInput :: Node { node_id, .. } = input { Some ( node_id) } else { None } ) ;
5013+ let node_ids = inputs. filter_map ( |input| match input {
5014+ NodeInput :: Node { output_index, .. } if self . flow_type == FlowType :: HorizontalPrimaryOutputFlow && * output_index != 0 => None ,
5015+ NodeInput :: Node { node_id, .. } => Some ( node_id) ,
5016+ _ => None ,
5017+ } ) ;
50215018
50225019 self . stack . extend ( node_ids) ;
50235020
0 commit comments