From b128b5bb94a93060cdd347dd4d6dc7f8fc2cd293 Mon Sep 17 00:00:00 2001
From: angloth <angus.lothian@hotmail.com>
Date: Thu, 9 Apr 2020 13:50:49 +0200
Subject: [PATCH] Add creation of a dfs traversal list that can be used for
 printing

---
 b_asic/signal_flow_graph.py | 71 +++++++++++++++++++++++++++----------
 1 file changed, 52 insertions(+), 19 deletions(-)

diff --git a/b_asic/signal_flow_graph.py b/b_asic/signal_flow_graph.py
index 345b438c..46c900a1 100644
--- a/b_asic/signal_flow_graph.py
+++ b/b_asic/signal_flow_graph.py
@@ -58,6 +58,7 @@ class SFG(AbstractOperation):
 
         self._components_by_id = dict()
         self._components_by_name = defaultdict(list)
+        self._components_in_dfs_order = []
         self._graph_id_generator = GraphIDGenerator(id_number_offset)
         self._input_operations = []
         self._output_operations = []
@@ -125,28 +126,34 @@ class SFG(AbstractOperation):
 
             self._output_operations.append(new_out)
 
-        output_operations_set = set(outputs)
+        output_operations_set = set(self._output_operations)
 
         # Search the graph inwards from each input signal.
         for sig, input_index in self._original_input_signals_indexes.items():
             # Check if already added destination.
-            if self._added_components_mapping[sig].destination is None:
-                if sig.destination is None:
-                    raise ValueError(
-                        f"Input signal #{input_index} is missing destination in SFG")
-                if sig.destination.operation not in self._added_components_mapping:
-                    self._copy_structure_from_operation_bfs(
-                        sig.destination.operation)
+            new_sig = self._added_components_mapping[sig]
+            if new_sig.destination is not None and new_sig.destination.operation in output_operations_set:
+                # Add directly connected input to output to dfs order list
+                self._components_in_dfs_order.extend([
+                    new_sig.source.operation, new_sig, new_sig.destination.operation])
+            elif sig.destination is None:
+                raise ValueError(
+                    f"Input signal #{input_index} is missing destination in SFG")
+            elif sig.destination.operation not in self._added_components_mapping:
+                print("MEME")
+                self._copy_structure_from_operation_dfs(
+                    sig.destination.operation)
 
         # Search the graph inwards from each output signal.
         for sig, output_index in self._original_output_signals_indexes.items():
             # Check if already added source.
-            if self._added_components_mapping[sig].source is None:
+            mew_sig = self._added_components_mapping[sig]
+            if new_sig.source is None:
                 if sig.source is None:
                     raise ValueError(
                         f"Output signal #{output_index} is missing source in SFG")
                 if sig.source.operation not in self._added_components_mapping:
-                    self._copy_structure_from_operation_bfs(
+                    self._copy_structure_from_operation_dfs(
                         sig.source.operation)
 
     @property
@@ -179,8 +186,8 @@ class SFG(AbstractOperation):
 
     @property
     def components(self) -> Iterable[GraphComponent]:
-        """Get all components of this graph."""
-        return self._components_by_id.values()
+        """Get all components of this graph in the dfs-traversal order."""
+        return self._components_in_dfs_order
 
     def find_by_id(self, graph_id: GraphID) -> Optional[GraphComponent]:
         """Find a graph object based on the entered Graph ID and return it. If no graph
@@ -214,15 +221,17 @@ class SFG(AbstractOperation):
 
         return new_comp
 
-    def _copy_structure_from_operation_bfs(self, start_op: Operation):
-        op_queue = deque([start_op])
+    def _copy_structure_from_operation_dfs(self, start_op: Operation):
+        op_stack = deque([start_op])
 
-        while op_queue:
-            original_op = op_queue.popleft()
-            # Add a copy of the operation without any connections.
+        while op_stack:
+            original_op = op_stack.pop()
+            # Add or get the new copy of the operation..
             new_op = None
             if original_op not in self._added_components_mapping:
                 new_op = self._add_component_copy_unconnected(original_op)
+                print("NEW_OP from traversal")
+                self._components_in_dfs_order.append(new_op)
             else:
                 new_op = self._added_components_mapping[original_op]
 
@@ -242,6 +251,9 @@ class SFG(AbstractOperation):
                         new_signal.set_destination(
                             new_op.input(original_input_port.index))
 
+                        self._components_in_dfs_order.extend(
+                            [new_signal, new_signal.source.operation])
+
                     # Check if the signal has not been added before
                     elif original_signal not in self._added_components_mapping:
                         if original_signal.source is None:
@@ -253,6 +265,10 @@ class SFG(AbstractOperation):
                         new_signal.set_destination(
                             new_op.input(original_input_port.index))
 
+                        print("new sig:", original_signal.name,
+                              "from input, curr:", new_op.name)
+                        self._components_in_dfs_order.append(new_signal)
+
                         original_connected_op = original_signal.source.operation
                         # Check if connected Operation has been added before
                         if original_connected_op in self._added_components_mapping:
@@ -267,8 +283,13 @@ class SFG(AbstractOperation):
                             new_signal.set_source(new_connected_op.output(
                                 original_signal.source.index))
 
+                            print("new op:", original_connected_op.name,
+                                  "from input, curr:", new_op.name)
+                            self._components_in_dfs_order.append(
+                                new_connected_op)
+
                             # Add connected operation to queue of operations to visit
-                            op_queue.append(original_connected_op)
+                            op_stack.append(original_connected_op)
 
             # Connect output ports
             for original_output_port in original_op.outputs:
@@ -283,6 +304,9 @@ class SFG(AbstractOperation):
                         new_signal.set_source(
                             new_op.output(original_output_port.index))
 
+                        self._components_in_dfs_order.extend(
+                            [new_signal, new_signal.destination.operation])
+
                     # Check if signal has not been added before.
                     elif original_signal not in self._added_components_mapping:
                         if original_signal.source is None:
@@ -294,6 +318,10 @@ class SFG(AbstractOperation):
                         new_signal.set_source(
                             new_op.output(original_output_port.index))
 
+                        print("New sig:", original_signal.name,
+                              "from output, curr:", new_op.name)
+                        self._components_in_dfs_order.append(new_signal)
+
                         original_connected_op = original_signal.destination.operation
                         # Check if connected operation has been added.
                         if original_connected_op in self._added_components_mapping:
@@ -309,8 +337,13 @@ class SFG(AbstractOperation):
                             new_signal.set_destination(new_connected_op.input(
                                 original_signal.destination.index))
 
+                            print("New op:", original_connected_op.name,
+                                  "from output, curr:", new_op.name)
+                            self._components_in_dfs_order.append(
+                                new_connected_op)
+
                             # Add connected operation to the queue of operations to visist
-                            op_queue.append(original_connected_op)
+                            op_stack.append(original_connected_op)
 
     def _evaluate_source(self, src: OutputPort) -> Number:
         input_values = []
-- 
GitLab