diff --git a/pyflow/blocks/executableblock.py b/pyflow/blocks/executableblock.py index 1ac8314d..c7ef34c1 100644 --- a/pyflow/blocks/executableblock.py +++ b/pyflow/blocks/executableblock.py @@ -7,7 +7,7 @@ """ -from typing import OrderedDict +from typing import TYPE_CHECKING, List, OrderedDict, Set, Union from abc import abstractmethod from PyQt5.QtCore import QTimer from PyQt5.QtWidgets import QApplication @@ -15,6 +15,9 @@ from pyflow.blocks.block import Block from pyflow.core.socket import Socket +if TYPE_CHECKING: + from pyflow.core.edge import Edge + class ExecutableBlock(Block): @@ -150,11 +153,11 @@ def custom_bfs(self, start_node, reverse=False): list: each element is a list of blocks/edges to animate in order """ # Blocks to run in topological order - blocks_to_run = [] + blocks_to_run: List["ExecutableBlock"] = [] # List of lists of blocks/edges to animate in order - to_transmit = [[start_node]] + to_transmit: List[List[Union["ExecutableBlock", "Edge"]]] = [[start_node]] - to_visit = [start_node] + to_visit: List["ExecutableBlock"] = [start_node] while to_visit: # Remove duplicates to_visit = list(set(to_visit)) @@ -166,11 +169,19 @@ def custom_bfs(self, start_node, reverse=False): if not reverse: for input_socket in block.sockets_in: for edge in input_socket.edges: - edges_to_visit.append(edge) + if ( + edge.source_socket.is_on + and edge.destination_socket.is_on + ): + edges_to_visit.append(edge) else: for output_socket in block.sockets_out: for edge in output_socket.edges: - edges_to_visit.append(edge) + if ( + edge.source_socket.is_on + and edge.destination_socket.is_on + ): + edges_to_visit.append(edge) to_transmit.append(edges_to_visit) # Gather connected blocks @@ -197,46 +208,56 @@ def right_traversal(self): list: each element is a list of blocks/edges to animate in order """ # Result - to_transmit = [[self]] + to_transmit: List[List[Union["ExecutableBlock", "Edge"]]] = [[self]] # To check if a block has been visited - visited = [] + visited: Set["ExecutableBlock"] = set([]) # We need to visit the inputs of these blocks - to_visit_input = [self] + to_visit_input: Set["ExecutableBlock"] = set([self]) # We need to visit the outputs of these blocks - to_visit_output = [self] + to_visit_output: Set["ExecutableBlock"] = set([self]) # Next stage to put in to_transmit - next_edges = [] - next_blocks = [] + next_edges: List["Edge"] = [] + next_blocks: List["ExecutableBlock"] = [] while to_visit_input or to_visit_output: for block in to_visit_input.copy(): # Check input edges and blocks for input_socket in block.sockets_in: for edge in input_socket.edges: - if edge not in visited: - next_edges.append(edge) - visited.append(edge) + if not ( + edge not in visited + and edge.source_socket.is_on + and edge.destination_socket.is_on + ): + continue + next_edges.append(edge) + visited.add(edge) input_block = edge.source_socket.block - to_visit_input.append(input_block) + to_visit_input.add(input_block) if input_block not in visited: next_blocks.append(input_block) - visited.append(input_block) + visited.add(input_block) to_visit_input.remove(block) for block in to_visit_output.copy(): # Check output edges and blocks for output_socket in block.sockets_out: for edge in output_socket.edges: - if edge not in visited: - next_edges.append(edge) - visited.append(edge) + if not ( + edge not in visited + and edge.source_socket.is_on + and edge.destination_socket.is_on + ): + continue + next_edges.append(edge) + visited.add(edge) output_block = edge.destination_socket.block - to_visit_input.append(output_block) - to_visit_output.append(output_block) + to_visit_input.add(output_block) + to_visit_output.add(output_block) if output_block not in visited: next_blocks.append(output_block) - visited.append(output_block) + visited.add(output_block) to_visit_output.remove(block) # Add the next stage to to_transmit