Skip to content
Snippets Groups Projects
signal_flow_graph.py 3.2 KiB
Newer Older
  • Learn to ignore specific revisions
  • """@package docstring
    
    B-ASIC Signal Flow Graph Module.
    TODO: More info.
    """
    
    
    from typing import List, Dict, Optional, DefaultDict
    from collections import defaultdict
    
    from b_asic.abstract_operation import AbstractOperation
    
    Kevin Scott's avatar
    Kevin Scott committed
    from b_asic.signal import Signal
    
    from b_asic.graph_id import GraphIDGenerator, GraphID
    
    from b_asic.graph_component import GraphComponent, Name, TypeName
    
    Jacob Wahlman's avatar
    Jacob Wahlman committed
        """Signal flow graph.
        TODO: More info.
        """
    
        _graph_components_by_id: Dict[GraphID, GraphComponent]
        _graph_components_by_name: DefaultDict[Name, List[GraphComponent]]
        _graph_id_generator: GraphIDGenerator
    
        def __init__(self, input_signals: List[Signal] = None, output_signals: List[Signal] = None, \
                    ops: List[Operation] = None, **kwds):
            super().__init__(**kwds)
            if input_signals is None:
                input_signals = []
            if output_signals is None:
                output_signals = []
            if ops is None:
                ops = []
    
            self._graph_components_by_id = dict() # Maps Graph ID to objects
            self._graph_components_by_name = defaultdict(list) # Maps Name to objects
            self._graph_id_generator = GraphIDGenerator()
    
            for operation in ops:
                self._add_graph_component(operation)
    
            for input_signal in input_signals:
                self._add_graph_component(input_signal)
    
            # TODO: Construct SFG based on what inputs that were given
            # TODO: Traverse the graph between the inputs/outputs and add to self._operations.
            # TODO: Connect ports with signals with appropriate IDs.
    
        def evaluate(self, inputs: list) -> list:
            return [] # TODO: Implement
    
        def _add_graph_component(self, graph_component: GraphComponent) -> GraphID:
            """Adds the entered graph component to the SFG's dictionary of graph objects and
             returns a generated GraphID for it.
    
            Keyword arguments:
            graph_component: Graph component to add to the graph.
            """
            # Add to name dict
            self._graph_components_by_name[graph_component.name].append(graph_component)
    
            # Add to ID dict
            graph_id: GraphID = self._graph_id_generator.get_next_id(graph_component.type_name)
            self._graph_components_by_id[graph_id] = graph_component
            return graph_id
    
        def find_by_id(self, graph_id: GraphID) -> Optional[GraphComponent]:
            """Finds a graph object based on the entered Graph ID and returns it. If no graph
            object with the entered ID was found then returns None.
    
            Keyword arguments:
            graph_id: Graph ID of the wanted object.
            """
            if graph_id in self._graph_components_by_id:
                return self._graph_components_by_id[graph_id]
    
            return None
    
        def find_by_name(self, name: Name) -> List[GraphComponent]:
            """Finds all graph objects that have the entered name and returns them
            in a list. If no graph object with the entered name was found then returns an
            empty list.
    
            Keyword arguments:
            name: Name of the wanted object.
            """
            return self._graph_components_by_name[name]
    
        @property
        def type_name(self) -> TypeName:
            return "sfg"