summaryrefslogtreecommitdiff
path: root/grc/base/FlowGraph.py
diff options
context:
space:
mode:
Diffstat (limited to 'grc/base/FlowGraph.py')
-rw-r--r--grc/base/FlowGraph.py552
1 files changed, 272 insertions, 280 deletions
diff --git a/grc/base/FlowGraph.py b/grc/base/FlowGraph.py
index a35afa363b..2f2d8c65e1 100644
--- a/grc/base/FlowGraph.py
+++ b/grc/base/FlowGraph.py
@@ -23,296 +23,288 @@ from .. gui import Messages
class FlowGraph(Element):
- def __init__(self, platform):
- """
- Make a flow graph from the arguments.
-
- Args:
- platform: a platforms with blocks and contrcutors
-
- Returns:
- the flow graph object
- """
- #initialize
- Element.__init__(self, platform)
- #inital blank import
- self.import_data()
+ def __init__(self, platform):
+ """
+ Make a flow graph from the arguments.
+
+ Args:
+ platform: a platforms with blocks and contrcutors
+
+ Returns:
+ the flow graph object
+ """
+ #initialize
+ Element.__init__(self, platform)
+ #inital blank import
+ self.import_data()
- def _get_unique_id(self, base_id=''):
- """
- Get a unique id starting with the base id.
-
- Args:
- base_id: the id starts with this and appends a count
-
- Returns:
- a unique id
- """
- index = 0
- while True:
- id = '%s_%d'%(base_id, index)
- index = index + 1
- #make sure that the id is not used by another block
- if not filter(lambda b: b.get_id() == id, self.get_blocks()): return id
+ def _get_unique_id(self, base_id=''):
+ """
+ Get a unique id starting with the base id.
+
+ Args:
+ base_id: the id starts with this and appends a count
+
+ Returns:
+ a unique id
+ """
+ index = 0
+ while True:
+ id = '%s_%d'%(base_id, index)
+ index = index + 1
+ #make sure that the id is not used by another block
+ if not filter(lambda b: b.get_id() == id, self.get_blocks()): return id
- def __str__(self): return 'FlowGraph - %s(%s)'%(self.get_option('title'), self.get_option('id'))
- def rewrite(self):
- def refactor_bus_structure():
-
- for block in self.get_blocks():
- for direc in ['source', 'sink']:
- if direc == 'source':
- get_p = block.get_sources;
- get_p_gui = block.get_sources_gui;
- bus_structure = block.form_bus_structure('source');
- else:
- get_p = block.get_sinks;
- get_p_gui = block.get_sinks_gui
- bus_structure = block.form_bus_structure('sink');
-
- if 'bus' in map(lambda a: a.get_type(), get_p_gui()):
-
-
-
- if len(get_p_gui()) > len(bus_structure):
- times = range(len(bus_structure), len(get_p_gui()));
- for i in times:
- for connect in get_p_gui()[-1].get_connections():
- block.get_parent().remove_element(connect);
- get_p().remove(get_p_gui()[-1]);
- elif len(get_p_gui()) < len(bus_structure):
- n = {'name':'bus','type':'bus'};
- if True in map(lambda a: isinstance(a.get_nports(), int), get_p()):
- n['nports'] = str(1);
-
- times = range(len(get_p_gui()), len(bus_structure));
-
- for i in times:
- n['key'] = str(len(get_p()));
- n = odict(n);
- port = block.get_parent().get_parent().Port(block=block, n=n, dir=direc);
- get_p().append(port);
-
-
-
- for child in self.get_children(): child.rewrite()
- refactor_bus_structure();
-
+ def __str__(self): return 'FlowGraph - %s(%s)'%(self.get_option('title'), self.get_option('id'))
+ def rewrite(self):
+ def refactor_bus_structure():
+
+ for block in self.get_blocks():
+ for direc in ['source', 'sink']:
+ if direc == 'source':
+ get_p = block.get_sources;
+ get_p_gui = block.get_sources_gui;
+ bus_structure = block.form_bus_structure('source');
+ else:
+ get_p = block.get_sinks;
+ get_p_gui = block.get_sinks_gui
+ bus_structure = block.form_bus_structure('sink');
+
+ if 'bus' in map(lambda a: a.get_type(), get_p_gui()):
+
+
+
+ if len(get_p_gui()) > len(bus_structure):
+ times = range(len(bus_structure), len(get_p_gui()));
+ for i in times:
+ for connect in get_p_gui()[-1].get_connections():
+ block.get_parent().remove_element(connect);
+ get_p().remove(get_p_gui()[-1]);
+ elif len(get_p_gui()) < len(bus_structure):
+ n = {'name':'bus','type':'bus'};
+ if True in map(lambda a: isinstance(a.get_nports(), int), get_p()):
+ n['nports'] = str(1);
+
+ times = range(len(get_p_gui()), len(bus_structure));
+
+ for i in times:
+ n['key'] = str(len(get_p()));
+ n = odict(n);
+ port = block.get_parent().get_parent().Port(block=block, n=n, dir=direc);
+ get_p().append(port);
+
+
+
+ for child in self.get_children(): child.rewrite()
+ refactor_bus_structure();
- def get_option(self, key):
- """
- Get the option for a given key.
- The option comes from the special options block.
-
- Args:
- key: the param key for the options block
-
- Returns:
- the value held by that param
- """
- return self._options_block.get_param(key).get_evaluated()
+ def get_option(self, key):
+ """
+ Get the option for a given key.
+ The option comes from the special options block.
+
+ Args:
+ key: the param key for the options block
+
+ Returns:
+ the value held by that param
+ """
+ return self._options_block.get_param(key).get_evaluated()
- def is_flow_graph(self): return True
+ def is_flow_graph(self): return True
- ##############################################
- ## Access Elements
- ##############################################
- def get_block(self, id): return filter(lambda b: b.get_id() == id, self.get_blocks())[0]
- def get_blocks_unordered(self): return filter(lambda e: e.is_block(), self.get_elements())
- def get_blocks(self):
- blocks = self.get_blocks_unordered();
- for i in range(len(blocks)):
- if blocks[i].get_key() == 'variable':
- blk = blocks[i];
- blocks.remove(blk);
- blocks.insert(1, blk);
- return blocks;
- def get_connections(self): return filter(lambda e: e.is_connection(), self.get_elements())
- def get_children(self): return self.get_elements()
- def get_elements(self):
- """
- Get a list of all the elements.
- Always ensure that the options block is in the list (only once).
-
- Returns:
- the element list
- """
- options_block_count = self._elements.count(self._options_block)
- if not options_block_count:
- self._elements.append(self._options_block)
- for i in range(options_block_count-1):
- self._elements.remove(self._options_block)
- return self._elements
+ ##############################################
+ ## Access Elements
+ ##############################################
+ def get_block(self, id): return filter(lambda b: b.get_id() == id, self.get_blocks())[0]
+ def get_blocks_unordered(self): return filter(lambda e: e.is_block(), self.get_elements())
+ def get_blocks(self):
+ blocks = self.get_blocks_unordered();
+ for i in range(len(blocks)):
+ if blocks[i].get_key() == 'variable':
+ blk = blocks[i];
+ blocks.remove(blk);
+ blocks.insert(1, blk);
+ return blocks;
+ def get_connections(self): return filter(lambda e: e.is_connection(), self.get_elements())
+ def get_children(self): return self.get_elements()
+ def get_elements(self):
+ """
+ Get a list of all the elements.
+ Always ensure that the options block is in the list (only once).
+
+ Returns:
+ the element list
+ """
+ options_block_count = self._elements.count(self._options_block)
+ if not options_block_count:
+ self._elements.append(self._options_block)
+ for i in range(options_block_count-1):
+ self._elements.remove(self._options_block)
+ return self._elements
- def get_enabled_blocks(self):
- """
- Get a list of all blocks that are enabled.
-
- Returns:
- a list of blocks
- """
- return filter(lambda b: b.get_enabled(), self.get_blocks())
+ def get_enabled_blocks(self):
+ """
+ Get a list of all blocks that are enabled.
+
+ Returns:
+ a list of blocks
+ """
+ return filter(lambda b: b.get_enabled(), self.get_blocks())
- def get_enabled_connections(self):
- """
- Get a list of all connections that are enabled.
-
- Returns:
- a list of connections
- """
- return filter(lambda c: c.get_enabled(), self.get_connections())
+ def get_enabled_connections(self):
+ """
+ Get a list of all connections that are enabled.
+
+ Returns:
+ a list of connections
+ """
+ return filter(lambda c: c.get_enabled(), self.get_connections())
- def get_new_block(self, key):
- """
- Get a new block of the specified key.
- Add the block to the list of elements.
-
- Args:
- key: the block key
-
- Returns:
- the new block or None if not found
- """
-
- if key not in self.get_parent().get_block_keys(): return None
- block = self.get_parent().get_new_block(self, key)
- self.get_elements().append(block);
- if block._bussify_sink:
- block.bussify({'name':'bus','type':'bus'}, 'sink')
- if block._bussify_source:
- block.bussify({'name':'bus','type':'bus'}, 'source')
- return block;
+ def get_new_block(self, key):
+ """
+ Get a new block of the specified key.
+ Add the block to the list of elements.
+
+ Args:
+ key: the block key
+
+ Returns:
+ the new block or None if not found
+ """
+ if key not in self.get_parent().get_block_keys(): return None
+ block = self.get_parent().get_new_block(self, key)
+ self.get_elements().append(block);
+ if block._bussify_sink:
+ block.bussify({'name':'bus','type':'bus'}, 'sink')
+ if block._bussify_source:
+ block.bussify({'name':'bus','type':'bus'}, 'source')
+ return block;
- def connect(self, porta, portb):
- """
- Create a connection between porta and portb.
-
- Args:
- porta: a port
- portb: another port
- @throw Exception bad connection
-
- Returns:
- the new connection
- """
-
- connection = self.get_parent().Connection(flow_graph=self, porta=porta, portb=portb)
-
-
- self.get_elements().append(connection)
- return connection
+ def connect(self, porta, portb):
+ """
+ Create a connection between porta and portb.
+
+ Args:
+ porta: a port
+ portb: another port
+ @throw Exception bad connection
+
+ Returns:
+ the new connection
+ """
+ connection = self.get_parent().Connection(flow_graph=self, porta=porta, portb=portb)
+ self.get_elements().append(connection)
+ return connection
- def remove_element(self, element):
- """
- Remove the element from the list of elements.
- If the element is a port, remove the whole block.
- If the element is a block, remove its connections.
- If the element is a connection, just remove the connection.
- """
+ def remove_element(self, element):
+ """
+ Remove the element from the list of elements.
+ If the element is a port, remove the whole block.
+ If the element is a block, remove its connections.
+ If the element is a connection, just remove the connection.
+ """
+ if element not in self.get_elements(): return
+ #found a port, set to parent signal block
+ if element.is_port():
+ element = element.get_parent()
+ #remove block, remove all involved connections
+ if element.is_block():
+ for port in element.get_ports():
+ map(self.remove_element, port.get_connections())
+ if element.is_connection():
+ if element.is_bus():
+ cons_list = []
+ for i in map(lambda a: a.get_connections(), element.get_source().get_associated_ports()):
+ cons_list.extend(i);
+ map(self.remove_element, cons_list);
+ self.get_elements().remove(element)
- if element not in self.get_elements(): return
- #found a port, set to parent signal block
- if element.is_port():
- element = element.get_parent()
- #remove block, remove all involved connections
- if element.is_block():
- for port in element.get_ports():
- map(self.remove_element, port.get_connections())
- if element.is_connection():
- if element.is_bus():
- cons_list = []
- for i in map(lambda a: a.get_connections(), element.get_source().get_associated_ports()):
- cons_list.extend(i);
- map(self.remove_element, cons_list);
- self.get_elements().remove(element)
-
+ def evaluate(self, expr):
+ """
+ Evaluate the expression.
+
+ Args:
+ expr: the string expression
+ @throw NotImplementedError
+ """
+ raise NotImplementedError
- def evaluate(self, expr):
- """
- Evaluate the expression.
-
- Args:
- expr: the string expression
- @throw NotImplementedError
- """
- raise NotImplementedError
+ ##############################################
+ ## Import/Export Methods
+ ##############################################
+ def export_data(self):
+ """
+ Export this flow graph to nested data.
+ Export all block and connection data.
+
+ Returns:
+ a nested data odict
+ """
+ import time
+ n = odict()
+ n['timestamp'] = time.ctime()
+ n['block'] = [block.export_data() for block in self.get_blocks()]
+ n['connection'] = [connection.export_data() for connection in self.get_connections()]
+ return odict({'flow_graph': n})
- ##############################################
- ## Import/Export Methods
- ##############################################
- def export_data(self):
- """
- Export this flow graph to nested data.
- Export all block and connection data.
-
- Returns:
- a nested data odict
- """
- import time
- n = odict()
- n['timestamp'] = time.ctime()
- n['block'] = [block.export_data() for block in self.get_blocks()]
- n['connection'] = [connection.export_data() for connection in self.get_connections()]
- return odict({'flow_graph': n})
-
- def import_data(self, n=None):
- """
- Import blocks and connections into this flow graph.
- Clear this flowgraph of all previous blocks and connections.
- Any blocks or connections in error will be ignored.
-
- Args:
- n: the nested data odict
- """
- #remove previous elements
- self._elements = list()
- #use blank data if none provided
- fg_n = n and n.find('flow_graph') or odict()
- blocks_n = fg_n.findall('block')
- connections_n = fg_n.findall('connection')
- #create option block
- self._options_block = self.get_parent().get_new_block(self, 'options')
- #build the blocks
- for block_n in blocks_n:
- key = block_n.find('key')
- if key == 'options': block = self._options_block
- else: block = self.get_new_block(key)
- #only load the block when the block key was valid
- if block: block.import_data(block_n)
- else: Messages.send_error_load('Block key "%s" not found in %s'%(key, self.get_parent()))
-
- #build the connections
- for connection_n in connections_n:
- #try to make the connection
- try:
- #get the block ids
- source_block_id = connection_n.find('source_block_id')
- sink_block_id = connection_n.find('sink_block_id')
- #get the port keys
- source_key = connection_n.find('source_key')
- sink_key = connection_n.find('sink_key')
- #verify the blocks
- block_ids = map(lambda b: b.get_id(), self.get_blocks())
- if source_block_id not in block_ids:
- raise LookupError('source block id "%s" not in block ids'%source_block_id)
- if sink_block_id not in block_ids:
- raise LookupError('sink block id "%s" not in block ids'%sink_block_id)
- #get the blocks
- source_block = self.get_block(source_block_id)
- sink_block = self.get_block(sink_block_id)
- #verify the ports
- if source_key not in source_block.get_source_keys():
- raise LookupError('source key "%s" not in source block keys'%source_key)
- if sink_key not in sink_block.get_sink_keys():
- raise LookupError('sink key "%s" not in sink block keys'%sink_key)
- #get the ports
- source = source_block.get_source(source_key)
- sink = sink_block.get_sink(sink_key)
- #build the connection
- self.connect(source, sink)
- except LookupError, e: Messages.send_error_load(
- 'Connection between %s(%s) and %s(%s) could not be made.\n\t%s'%(
- source_block_id, source_key, sink_block_id, sink_key, e
- )
- )
- self.rewrite() #global rewrite
+ def import_data(self, n=None):
+ """
+ Import blocks and connections into this flow graph.
+ Clear this flowgraph of all previous blocks and connections.
+ Any blocks or connections in error will be ignored.
+
+ Args:
+ n: the nested data odict
+ """
+ #remove previous elements
+ self._elements = list()
+ #use blank data if none provided
+ fg_n = n and n.find('flow_graph') or odict()
+ blocks_n = fg_n.findall('block')
+ connections_n = fg_n.findall('connection')
+ #create option block
+ self._options_block = self.get_parent().get_new_block(self, 'options')
+ #build the blocks
+ for block_n in blocks_n:
+ key = block_n.find('key')
+ if key == 'options': block = self._options_block
+ else: block = self.get_new_block(key)
+ #only load the block when the block key was valid
+ if block: block.import_data(block_n)
+ else: Messages.send_error_load('Block key "%s" not found in %s'%(key, self.get_parent()))
+ #build the connections
+ for connection_n in connections_n:
+ #try to make the connection
+ try:
+ #get the block ids
+ source_block_id = connection_n.find('source_block_id')
+ sink_block_id = connection_n.find('sink_block_id')
+ #get the port keys
+ source_key = connection_n.find('source_key')
+ sink_key = connection_n.find('sink_key')
+ #verify the blocks
+ block_ids = map(lambda b: b.get_id(), self.get_blocks())
+ if source_block_id not in block_ids:
+ raise LookupError('source block id "%s" not in block ids'%source_block_id)
+ if sink_block_id not in block_ids:
+ raise LookupError('sink block id "%s" not in block ids'%sink_block_id)
+ #get the blocks
+ source_block = self.get_block(source_block_id)
+ sink_block = self.get_block(sink_block_id)
+ #verify the ports
+ if source_key not in source_block.get_source_keys():
+ raise LookupError('source key "%s" not in source block keys'%source_key)
+ if sink_key not in sink_block.get_sink_keys():
+ raise LookupError('sink key "%s" not in sink block keys'%sink_key)
+ #get the ports
+ source = source_block.get_source(source_key)
+ sink = sink_block.get_sink(sink_key)
+ #build the connection
+ self.connect(source, sink)
+ except LookupError, e: Messages.send_error_load(
+ 'Connection between %s(%s) and %s(%s) could not be made.\n\t%s'%(
+ source_block_id, source_key, sink_block_id, sink_key, e
+ )
+ )
+ self.rewrite() #global rewrite