diff options
Diffstat (limited to 'grc')
-rw-r--r-- | grc/base/Block.py | 41 | ||||
-rw-r--r-- | grc/base/Param.py | 2 | ||||
-rw-r--r-- | grc/blocks/Makefile.am | 2 | ||||
-rw-r--r-- | grc/blocks/block_tree.xml | 2 | ||||
-rw-r--r-- | grc/blocks/gr_message_sink.xml | 72 | ||||
-rw-r--r-- | grc/blocks/gr_message_source.xml | 58 | ||||
-rw-r--r-- | grc/gui/Block.py | 8 | ||||
-rw-r--r-- | grc/python/Block.py | 26 | ||||
-rw-r--r-- | grc/python/Connection.py | 3 | ||||
-rw-r--r-- | grc/python/Constants.py | 1 | ||||
-rw-r--r-- | grc/python/Generator.py | 4 | ||||
-rw-r--r-- | grc/python/Platform.py | 3 | ||||
-rw-r--r-- | grc/python/Port.py | 43 | ||||
-rw-r--r-- | grc/python/flow_graph.tmpl | 13 | ||||
-rw-r--r-- | grc/todo.txt | 1 |
15 files changed, 222 insertions, 57 deletions
diff --git a/grc/base/Block.py b/grc/base/Block.py index 867a14f57..d5e104785 100644 --- a/grc/base/Block.py +++ b/grc/base/Block.py @@ -46,6 +46,9 @@ class TemplateArg(UserDict): def __call__(self): return self._param.get_evaluated() +def _get_keys(lst): return [elem.get_key() for elem in lst] +def _get_elem(lst, key): return lst[_get_keys(lst).index(key)] + class Block(Element): def __init__(self, flow_graph, n): @@ -66,17 +69,17 @@ class Block(Element): self._category = n.find('category') or '' self._block_wrapper_path = n.find('block_wrapper_path') #create the param objects - self._params = odict() + self._params = list() #add the id param - self._params['id'] = self.get_parent().get_parent().Param( + self.get_params().append(self.get_parent().get_parent().Param( self, odict({ 'name': 'ID', 'key': 'id', 'type': 'id', }) - ) - self._params['_enabled'] = self.get_parent().get_parent().Param( + )) + self.get_params().append(self.get_parent().get_parent().Param( self, odict({ 'name': 'Enabled', @@ -85,32 +88,32 @@ class Block(Element): 'value': 'True', 'hide': 'all', }) - ) + )) for param in map(lambda n: self.get_parent().get_parent().Param(self, n), params): key = param.get_key() #test against repeated keys try: assert key not in self.get_param_keys() except AssertionError: raise Exception, 'Key "%s" already exists in params'%key #store the param - self._params[key] = param + self.get_params().append(param) #create the source objects - self._sources = odict() + self._sources = list() for source in map(lambda n: self.get_parent().get_parent().Source(self, n), sources): key = source.get_key() #test against repeated keys try: assert key not in self.get_source_keys() except AssertionError: raise Exception, 'Key "%s" already exists in sources'%key #store the port - self._sources[key] = source + self.get_sources().append(source) #create the sink objects - self._sinks = odict() + self._sinks = list() for sink in map(lambda n: self.get_parent().get_parent().Sink(self, n), sinks): key = sink.get_key() #test against repeated keys try: assert key not in self.get_sink_keys() except AssertionError: raise Exception, 'Key "%s" already exists in sinks'%key #store the port - self._sinks[key] = sink + self.get_sinks().append(sink) #begin the testing self.test() @@ -164,23 +167,23 @@ class Block(Element): ############################################## # Access Params ############################################## - def get_param_keys(self): return self._params.keys() - def get_param(self, key): return self._params[key] - def get_params(self): return self._params.values() + def get_param_keys(self): return _get_keys(self._params) + def get_param(self, key): return _get_elem(self._params, key) + def get_params(self): return self._params ############################################## # Access Sinks ############################################## - def get_sink_keys(self): return self._sinks.keys() - def get_sink(self, key): return self._sinks[key] - def get_sinks(self): return self._sinks.values() + def get_sink_keys(self): return _get_keys(self._sinks) + def get_sink(self, key): return _get_elem(self._sinks, key) + def get_sinks(self): return self._sinks ############################################## # Access Sources ############################################## - def get_source_keys(self): return self._sources.keys() - def get_source(self, key): return self._sources[key] - def get_sources(self): return self._sources.values() + def get_source_keys(self): return _get_keys(self._sources) + def get_source(self, key): return _get_elem(self._sources, key) + def get_sources(self): return self._sources def get_connections(self): return sum([port.get_connections() for port in self.get_ports()], []) diff --git a/grc/base/Param.py b/grc/base/Param.py index 8166d54ec..93c1c52bd 100644 --- a/grc/base/Param.py +++ b/grc/base/Param.py @@ -165,6 +165,8 @@ class Param(Element): try: assert self.get_value() in self.get_option_keys() except AssertionError: raise Exception, 'The value "%s" is not in the possible values of "%s".'%(self.get_value(), self.get_option_keys()) else: self._value = value or '' + #begin the testing + self.test() def test(self): """ diff --git a/grc/blocks/Makefile.am b/grc/blocks/Makefile.am index 025c261f4..fbd8f4bb4 100644 --- a/grc/blocks/Makefile.am +++ b/grc/blocks/Makefile.am @@ -123,6 +123,8 @@ dist_ourdata_DATA = \ gr_kludge_copy.xml \ gr_map_bb.xml \ gr_max_xx.xml \ + gr_message_sink.xml \ + gr_message_source.xml \ gr_moving_average_xx.xml \ gr_mpsk_receiver_cc.xml \ gr_mpsk_sync_cc.xml \ diff --git a/grc/blocks/block_tree.xml b/grc/blocks/block_tree.xml index 9eda2fdcf..2cedb45a2 100644 --- a/grc/blocks/block_tree.xml +++ b/grc/blocks/block_tree.xml @@ -20,6 +20,7 @@ <block>gr_udp_source</block> <block>audio_source</block> <block>gr_wavfile_source</block> + <block>gr_message_source</block> <block>pad_source</block> </cat> <cat> @@ -32,6 +33,7 @@ <block>gr_udp_sink</block> <block>audio_sink</block> <block>gr_wavfile_sink</block> + <block>gr_message_sink</block> <block>pad_sink</block> </cat> <cat> diff --git a/grc/blocks/gr_message_sink.xml b/grc/blocks/gr_message_sink.xml new file mode 100644 index 000000000..76537f283 --- /dev/null +++ b/grc/blocks/gr_message_sink.xml @@ -0,0 +1,72 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Message Sink (the source port is a message) +################################################### + --> +<block> + <name>Message Sink</name> + <key>gr_message_sink</key> + <import>from gnuradio import gr</import> + <make>gr.message_sink($type.size*$vlen, $(id)_msgq, $dont_block)</make> + <param> + <name>Input Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>size:gr.sizeof_gr_complex</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>size:gr.sizeof_float</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>size:gr.sizeof_int</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>size:gr.sizeof_short</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>size:gr.sizeof_char</opt> + </option> + </param> + <param> + <name>Don't Block</name> + <key>dont_block</key> + <value>False</value> + <type>enum</type> + <option> + <name>Don't Block</name> + <key>True</key> + </option> + <option> + <name>Block</name> + <key>False</key> + </option> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$vlen > 0</check> + <sink> + <name>in</name> + <type>$type</type> + <vlen>$vlen</vlen> + </sink> + <source> + <name>out</name> + <type>msg</type> + </source> +</block> diff --git a/grc/blocks/gr_message_source.xml b/grc/blocks/gr_message_source.xml new file mode 100644 index 000000000..44378ae83 --- /dev/null +++ b/grc/blocks/gr_message_source.xml @@ -0,0 +1,58 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Message Source (the sink port is a message) +################################################### + --> +<block> + <name>Message Source</name> + <key>gr_message_source</key> + <import>from gnuradio import gr</import> + <make>gr.message_source($type.size*$vlen, $(id)_msgq)</make> + <param> + <name>Output Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>size:gr.sizeof_gr_complex</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>size:gr.sizeof_float</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>size:gr.sizeof_int</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>size:gr.sizeof_short</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>size:gr.sizeof_char</opt> + </option> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$vlen > 0</check> + <sink> + <name>in</name> + <type>msg</type> + </sink> + <source> + <name>out</name> + <type>$type</type> + <vlen>$vlen</vlen> + </source> +</block> diff --git a/grc/gui/Block.py b/grc/gui/Block.py index 0496f0a28..4add3aa19 100644 --- a/grc/gui/Block.py +++ b/grc/gui/Block.py @@ -43,7 +43,7 @@ class Block(Element): Add graphics related params to the block. """ #add the position param - self._params['_coordinate'] = self.get_parent().get_parent().Param( + self.get_params().append(self.get_parent().get_parent().Param( self, odict({ 'name': 'GUI Coordinate', @@ -52,8 +52,8 @@ class Block(Element): 'value': '(0, 0)', 'hide': 'all', }) - ) - self._params['_rotation'] = self.get_parent().get_parent().Param( + )) + self.get_params().append(self.get_parent().get_parent().Param( self, odict({ 'name': 'GUI Rotation', @@ -62,7 +62,7 @@ class Block(Element): 'value': '0', 'hide': 'all', }) - ) + )) Element.__init__(self) def get_coordinate(self): diff --git a/grc/python/Block.py b/grc/python/Block.py index 957fee18e..47fe13a3c 100644 --- a/grc/python/Block.py +++ b/grc/python/Block.py @@ -66,16 +66,16 @@ class Block(_Block): except AssertionError: self.add_error_message('Check "%s" failed.'%check) except: self.add_error_message('Check "%s" did not evaluate.'%check) #adjust nports - for ports, Port in ( - (self._sources, self.get_parent().get_parent().Source), - (self._sinks, self.get_parent().get_parent().Sink), + for get_ports, get_port in ( + (self.get_sources, self.get_source), + (self.get_sinks, self.get_sink), ): - #how many ports? - num_ports = len(ports) + #how many streaming (non-message) ports? + num_ports = len(filter(lambda p: p.get_type() != 'msg', get_ports())) #do nothing for 0 ports if not num_ports: continue #get the nports setting - port0 = ports[str(0)] + port0 = get_port(str(0)) nports = port0.get_nports() #do nothing for no nports if not nports: continue @@ -85,19 +85,21 @@ class Block(_Block): if nports < num_ports: #remove the connections for key in map(str, range(nports, num_ports)): - port = ports[key] + port = get_port(key) for connection in port.get_connections(): self.get_parent().remove_element(connection) #remove the ports - for key in map(str, range(nports, num_ports)): ports.pop(key) + for key in map(str, range(nports, num_ports)): + get_ports().remove(get_port(key)) continue #add more ports if nports > num_ports: for key in map(str, range(num_ports, nports)): - n = port0._n - n['key'] = key - port = Port(self, n) - ports[key] = port + prev_port = get_port(str(int(key)-1)) + get_ports().insert( + get_ports().index(prev_port)+1, + prev_port.copy(new_key=key), + ) continue def port_controller_modify(self, direction): diff --git a/grc/python/Connection.py b/grc/python/Connection.py index d8a894bb1..5eba9f24d 100644 --- a/grc/python/Connection.py +++ b/grc/python/Connection.py @@ -21,6 +21,9 @@ from .. base.Connection import Connection as _Connection class Connection(_Connection): + def is_msg(self): + return self.get_source().get_type() == self.get_sink().get_type() == 'msg' + def validate(self): """ Validate the connections. diff --git a/grc/python/Constants.py b/grc/python/Constants.py index 5f203237f..439a52420 100644 --- a/grc/python/Constants.py +++ b/grc/python/Constants.py @@ -61,3 +61,4 @@ SHORT_VECTOR_COLOR_SPEC = '#CCCC33' BYTE_VECTOR_COLOR_SPEC = '#CC66CC' ID_COLOR_SPEC = '#DDDDDD' WILDCARD_COLOR_SPEC = '#FFFFFF' +MSG_COLOR_SPEC = '#777777' diff --git a/grc/python/Generator.py b/grc/python/Generator.py index 33be4a726..ed7995716 100644 --- a/grc/python/Generator.py +++ b/grc/python/Generator.py @@ -98,7 +98,8 @@ Add a Misc->Throttle block to your flow graph to avoid CPU congestion.''') #list of regular blocks (all blocks minus the special ones) blocks = filter(lambda b: b not in (imports + parameters + variables + probes + notebooks), blocks) + probes #list of connections where each endpoint is enabled - connections = self._flow_graph.get_enabled_connections() + connections = filter(lambda c: not c.is_msg(), self._flow_graph.get_enabled_connections()) + messages = filter(lambda c: c.is_msg(), self._flow_graph.get_enabled_connections()) #list of variable names var_ids = [var.get_id() for var in parameters + variables] #prepend self. @@ -124,6 +125,7 @@ Add a Misc->Throttle block to your flow graph to avoid CPU congestion.''') 'parameters': parameters, 'blocks': blocks, 'connections': connections, + 'messages': messages, 'generate_options': self._generate_options, 'var_id2cbs': var_id2cbs, } diff --git a/grc/python/Platform.py b/grc/python/Platform.py index f56e3fb2d..d55dbf4ce 100644 --- a/grc/python/Platform.py +++ b/grc/python/Platform.py @@ -42,7 +42,8 @@ COLORS = (#title, #color spec ('Integer Vector', Constants.INT_VECTOR_COLOR_SPEC), ('Short Vector', Constants.SHORT_VECTOR_COLOR_SPEC), ('Byte Vector', Constants.BYTE_VECTOR_COLOR_SPEC), - ('Wildcard Type', Constants.WILDCARD_COLOR_SPEC), + ('Wildcard', Constants.WILDCARD_COLOR_SPEC), + ('Message', Constants.MSG_COLOR_SPEC), ) class Platform(_Platform): diff --git a/grc/python/Port.py b/grc/python/Port.py index 5a2b047f0..daf8f9ca3 100644 --- a/grc/python/Port.py +++ b/grc/python/Port.py @@ -23,27 +23,23 @@ import Constants class Port(_Port): ##possible port types - TYPES = ['complex', 'float', 'int', 'short', 'byte'] + TYPES = ['complex', 'float', 'int', 'short', 'byte', 'msg'] def __init__(self, block, n): """ Make a new port from nested data. @param block the parent element @param n the nested odict - @return a new port """ - vlen = n.find('vlen') or '1' - nports = n.find('nports') or '' - optional = n.find('optional') or '' #build the port _Port.__init__( self, block=block, n=n, ) - self._nports = nports - self._vlen = vlen - self._optional = bool(optional) + self._nports = n.find('nports') or '' + self._vlen = n.find('vlen') or '' + self._optional = bool(n.find('optional')) def validate(self): _Port.validate(self) @@ -51,6 +47,11 @@ class Port(_Port): except AssertionError: self.add_error_message('Port is not connected.') try: assert self.is_source() or len(self.get_enabled_connections()) <= 1 except AssertionError: self.add_error_message('Port has too many connections.') + if self.get_type() == 'msg': + try: assert not self.get_nports() + except AssertionError: self.add_error_message('A port of type "msg" cannot have "nports" set.') + try: assert self.get_vlen() == 1 + except AssertionError: self.add_error_message('A port of type "msg" must have a "vlen" of 1.') def get_vlen(self): """ @@ -94,6 +95,7 @@ class Port(_Port): 'int': Constants.INT_COLOR_SPEC, 'short': Constants.SHORT_COLOR_SPEC, 'byte': Constants.BYTE_COLOR_SPEC, + 'msg': Constants.MSG_COLOR_SPEC, }[self.get_type()] return {#vlen is non 1 'complex': Constants.COMPLEX_VECTOR_COLOR_SPEC, @@ -104,26 +106,27 @@ class Port(_Port): }[self.get_type()] except: return _Port.get_color(self) + def copy(self, new_key=None): + n = self._n.copy() + if new_key: n['key'] = new_key + return self.__class__(self.get_parent(), n) + class Source(Port): def __init__(self, block, n): self._n = n #save n - #key is port index - n['key'] = str(block._source_count) - block._source_count = block._source_count + 1 + if n['type'] == 'msg': n['key'] = 'msg' + if not n.find('key'): + n['key'] = str(block._source_count) + block._source_count = block._source_count + 1 Port.__init__(self, block, n) - def __del__(self): - self.get_parent()._source_count = self.get_parent()._source_count - 1 - class Sink(Port): def __init__(self, block, n): self._n = n #save n - #key is port index - n['key'] = str(block._sink_count) - block._sink_count = block._sink_count + 1 + if n['type'] == 'msg': n['key'] = 'msg' + if not n.find('key'): + n['key'] = str(block._sink_count) + block._sink_count = block._sink_count + 1 Port.__init__(self, block, n) - - def __del__(self): - self.get_parent()._sink_count = self.get_parent()._sink_count - 1 diff --git a/grc/python/flow_graph.tmpl b/grc/python/flow_graph.tmpl index b537c43e2..df346dd16 100644 --- a/grc/python/flow_graph.tmpl +++ b/grc/python/flow_graph.tmpl @@ -10,6 +10,7 @@ ##@param parameters the paramater blocks ##@param blocks the signal blocks ##@param connections the connections +##@param messages the msg type connections ##@param generate_options the type of flow graph ##@param var_id2cbs variable id map to callback strings ######################################################## @@ -125,6 +126,18 @@ class $(class_name)(gr.hier_block2): $indent($ctrl.get_make()) #end for ######################################################## +##Create Message Queues +######################################################## +#if $messages + + $DIVIDER + # Message Queues + $DIVIDER +#end if +#for $msg in $messages + $(msg.get_source().get_parent().get_id())_msgq = $(msg.get_sink().get_parent().get_id())_msgq = gr.msg_queue(2) +#end for +######################################################## ##Create Blocks ######################################################## #if $blocks diff --git a/grc/todo.txt b/grc/todo.txt index f8c8021b6..bb40e1f16 100644 --- a/grc/todo.txt +++ b/grc/todo.txt @@ -26,6 +26,7 @@ * callbacks for set average on fft, waterfall, number sinks * add units to params: Sps, Hz, dB... * command line options should replace _ with - for the --option + * add bool type to command line option store_true or store_false ################################################## # Features |