commit-gnuradio
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Commit-gnuradio] r11601 - in gnuradio/trunk: . gnuradio-core/src/lib/ru


From: git
Subject: [Commit-gnuradio] r11601 - in gnuradio/trunk: . gnuradio-core/src/lib/runtime grc grc/base grc/blocks grc/gui grc/python gruel/src/include/gruel gruel/src/lib/pmt
Date: Sat, 15 Aug 2009 19:03:39 -0600 (MDT)

Author: git
Date: 2009-08-15 19:03:39 -0600 (Sat, 15 Aug 2009)
New Revision: 11601

Added:
   gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_msg_accepter.cc
   gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_msg_accepter.h
   gnuradio/trunk/grc/blocks/gr_message_sink.xml
   gnuradio/trunk/grc/blocks/gr_message_source.xml
   gnuradio/trunk/gruel/src/include/gruel/send.h
Modified:
   gnuradio/trunk/Makefile.am
   gnuradio/trunk/gnuradio-core/src/lib/runtime/Makefile.am
   gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_basic_block.cc
   gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_basic_block.h
   gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_block_detail.cc
   gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_block_detail.h
   gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_tpb_detail.cc
   gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_tpb_detail.h
   gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_tpb_thread_body.cc
   gnuradio/trunk/grc/base/Block.py
   gnuradio/trunk/grc/base/Param.py
   gnuradio/trunk/grc/blocks/Makefile.am
   gnuradio/trunk/grc/blocks/block_tree.xml
   gnuradio/trunk/grc/gui/Block.py
   gnuradio/trunk/grc/python/Block.py
   gnuradio/trunk/grc/python/Connection.py
   gnuradio/trunk/grc/python/Constants.py
   gnuradio/trunk/grc/python/Generator.py
   gnuradio/trunk/grc/python/Platform.py
   gnuradio/trunk/grc/python/Port.py
   gnuradio/trunk/grc/python/flow_graph.tmpl
   gnuradio/trunk/grc/todo.txt
   gnuradio/trunk/gruel/src/include/gruel/Makefile.am
   gnuradio/trunk/gruel/src/include/gruel/msg_accepter.h
   gnuradio/trunk/gruel/src/include/gruel/msg_accepter_msgq.h
   gnuradio/trunk/gruel/src/include/gruel/pmt.h
   gnuradio/trunk/gruel/src/lib/pmt/pmt.cc
   gnuradio/trunk/gruel/src/lib/pmt/pmt_int.h
   gnuradio/trunk/gruel/src/lib/pmt/pmt_io.cc
   gnuradio/trunk/gruel/src/lib/pmt/qa_pmt_prims.cc
   gnuradio/trunk/gruel/src/lib/pmt/qa_pmt_prims.h
Log:
Merged branch 'master' of http://gnuradio.org/git/gnuradio.git in git-svn 
gateway.

Modified: gnuradio/trunk/Makefile.am
===================================================================
--- gnuradio/trunk/Makefile.am  2009-08-15 18:34:45 UTC (rev 11600)
+++ gnuradio/trunk/Makefile.am  2009-08-16 01:03:39 UTC (rev 11601)
@@ -37,3 +37,16 @@
 
 SUBDIRS = @build_dirs@
 DIST_SUBDIRS = @build_dirs@ @skipped_dirs@ @with_dirs@
+
+if PYTHON
+
+export pythondir
+
+install-data-hook:
+       @if ! python -c "import gnuradio" > /dev/null 2>&1; then\
+               printf "\n*** Post-Install Message ***\
+               \nWarning: python could not find the gnuradio module.\
+               \nMake sure that $${pythondir} is in your PYTHONPATH\n\n";\
+       fi
+
+endif

Modified: gnuradio/trunk/gnuradio-core/src/lib/runtime/Makefile.am
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/runtime/Makefile.am    2009-08-15 
18:34:45 UTC (rev 11600)
+++ gnuradio/trunk/gnuradio-core/src/lib/runtime/Makefile.am    2009-08-16 
01:03:39 UTC (rev 11601)
@@ -44,6 +44,7 @@
        gr_io_signature.cc                      \
        gr_local_sighandler.cc                  \
        gr_message.cc                           \
+       gr_msg_accepter.cc                      \
        gr_msg_handler.cc                       \
        gr_msg_queue.cc                         \
        gr_pagesize.cc                          \
@@ -96,6 +97,7 @@
        gr_io_signature.h                       \
        gr_local_sighandler.h                   \
        gr_message.h                            \
+       gr_msg_accepter.h                       \
        gr_msg_handler.h                        \
        gr_msg_queue.h                          \
        gr_pagesize.h                           \

Modified: gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_basic_block.cc
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_basic_block.cc      
2009-08-15 18:34:45 UTC (rev 11600)
+++ gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_basic_block.cc      
2009-08-16 01:03:39 UTC (rev 11601)
@@ -41,8 +41,7 @@
 gr_basic_block::gr_basic_block(const std::string &name,
                                gr_io_signature_sptr input_signature,
                                gr_io_signature_sptr output_signature) 
-  : gruel::msg_accepter_msgq(gruel::make_msg_queue(0)),
-    d_name(name),
+  : d_name(name),
     d_input_signature(input_signature),
     d_output_signature(output_signature),
     d_unique_id(s_next_id++),

Modified: gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_basic_block.h
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_basic_block.h       
2009-08-15 18:34:45 UTC (rev 11600)
+++ gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_basic_block.h       
2009-08-16 01:03:39 UTC (rev 11601)
@@ -26,7 +26,7 @@
 #include <gr_runtime_types.h>
 #include <gr_sptr_magic.h>
 #include <boost/enable_shared_from_this.hpp>
-#include <gruel/msg_accepter_msgq.h>
+#include <gr_msg_accepter.h>
 #include <string>
 
 /*!
@@ -40,7 +40,7 @@
  * signal processing functions.
  */
 
-class gr_basic_block : gruel::msg_accepter_msgq, public 
boost::enable_shared_from_this<gr_basic_block>
+class gr_basic_block : public gr_msg_accepter, public 
boost::enable_shared_from_this<gr_basic_block>
 {
 protected:
     friend class gr_flowgraph;

Modified: gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_block_detail.cc
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_block_detail.cc     
2009-08-15 18:34:45 UTC (rev 11600)
+++ gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_block_detail.cc     
2009-08-16 01:03:39 UTC (rev 11601)
@@ -118,3 +118,10 @@
     d_produce_or |= how_many_items;
   }
 }
+
+
+void
+gr_block_detail::_post(pmt::pmt_t msg)
+{
+  d_tpb.insert_tail(msg);
+}

Modified: gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_block_detail.h
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_block_detail.h      
2009-08-15 18:34:45 UTC (rev 11600)
+++ gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_block_detail.h      
2009-08-16 01:03:39 UTC (rev 11601)
@@ -83,8 +83,11 @@
    */
   void produce_each (int how_many_items);
 
+  /*!
+   * Accept msg, place in queue, arrange for thread to be awakened if it's not 
already.
+   */
+  void _post(pmt::pmt_t msg);
 
-
   gr_tpb_detail                             d_tpb;     // used by 
thread-per-block scheduler
   int                               d_produce_or;
 

Copied: gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_msg_accepter.cc (from 
rev 11600, gnuradio/trunk/gruel/src/include/gruel/msg_accepter_msgq.h)
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_msg_accepter.cc             
                (rev 0)
+++ gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_msg_accepter.cc     
2009-08-16 01:03:39 UTC (rev 11601)
@@ -0,0 +1,59 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gr_msg_accepter.h>
+#include <gr_block.h>
+#include <gr_block_detail.h>
+#include <gr_hier_block2.h>
+#include <stdexcept>
+
+using namespace pmt;
+
+gr_msg_accepter::gr_msg_accepter()
+{
+}
+
+gr_msg_accepter::~gr_msg_accepter()
+{
+  // NOP, required as virtual destructor
+}
+
+void
+gr_msg_accepter::post(pmt_t msg)
+{
+  // Notify derived class, handled case by case
+  gr_block *p = dynamic_cast<gr_block *>(this);
+  if (p) { 
+    p->detail()->_post(msg);
+    return;
+  }
+  gr_hier_block2 *p2 = dynamic_cast<gr_hier_block2 *>(this);
+  if (p2){
+    // FIXME do the right thing
+    return;
+  }
+
+  throw std::runtime_error("unknown derived class");
+}

Copied: gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_msg_accepter.h (from 
rev 11600, gnuradio/trunk/gruel/src/include/gruel/msg_accepter.h)
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_msg_accepter.h              
                (rev 0)
+++ gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_msg_accepter.h      
2009-08-16 01:03:39 UTC (rev 11601)
@@ -0,0 +1,42 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef INCLUDED_GR_MSG_ACCEPTER_H
+#define INCLUDED_GR_MSG_ACCEPTER_H
+
+#include <gruel/msg_accepter.h>
+#include <gruel/pmt.h>
+
+/*!
+ * \brief Accepts messages and inserts them into a message queue, then notifies
+ * subclass gr_basic_block there is a message pending.
+ */
+class gr_msg_accepter : public gruel::msg_accepter
+{
+public:
+  gr_msg_accepter();
+  ~gr_msg_accepter();
+
+  void post(pmt::pmt_t msg);
+
+};
+
+#endif /* INCLUDED_GR_MSG_ACCEPTER_H */

Modified: gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_tpb_detail.cc
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_tpb_detail.cc       
2009-08-15 18:34:45 UTC (rev 11600)
+++ gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_tpb_detail.cc       
2009-08-16 01:03:39 UTC (rev 11601)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2008 Free Software Foundation, Inc.
+ * Copyright 2008,2009 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -27,6 +27,8 @@
 #include <gr_block_detail.h>
 #include <gr_buffer.h>
 
+using namespace pmt;
+
 /*
  * We assume that no worker threads are ever running when the
  * graph structure is being manipulated, thus it's safe for us to poke
@@ -65,3 +67,44 @@
   notify_downstream(d);
   notify_upstream(d);
 }
+
+void
+gr_tpb_detail::insert_tail(pmt::pmt_t msg)
+{
+  gruel::scoped_lock guard(mutex);
+
+  msg_queue.push_back(msg);
+
+  // wake up thread if BLKD_IN or BLKD_OUT
+  input_cond.notify_one();
+  output_cond.notify_one();
+}
+
+pmt_t 
+gr_tpb_detail::delete_head_nowait()
+{
+  gruel::scoped_lock guard(mutex);
+
+  if (empty_p())
+    return pmt_t();
+
+  pmt_t m(msg_queue.front());
+  msg_queue.pop_front();
+
+  return m;
+}
+
+/*
+ * Caller must already be holding the mutex
+ */
+pmt_t 
+gr_tpb_detail::delete_head_nowait_already_holding_mutex()
+{
+  if (empty_p())
+    return pmt_t();
+
+  pmt_t m(msg_queue.front());
+  msg_queue.pop_front();
+
+  return m;
+}

Modified: gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_tpb_detail.h
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_tpb_detail.h        
2009-08-15 18:34:45 UTC (rev 11600)
+++ gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_tpb_detail.h        
2009-08-16 01:03:39 UTC (rev 11601)
@@ -22,6 +22,8 @@
 #define INCLUDED_GR_TPB_DETAIL_H
 
 #include <gruel/thread.h>
+#include <deque>
+#include <gruel/pmt.h>
 
 class gr_block_detail;
 
@@ -36,10 +38,13 @@
   bool                         output_changed;
   gruel::condition_variable    output_cond;
 
+private:
+  std::deque<pmt::pmt_t>       msg_queue;
+
+public:
   gr_tpb_detail()
-    : input_changed(false), output_changed(false) {}
+    : input_changed(false), output_changed(false) { }
 
-
   //! Called by us to tell all our upstream blocks that their output may have 
changed.
   void notify_upstream(gr_block_detail *d);
 
@@ -56,7 +61,24 @@
     input_changed = false;
     output_changed = false;
   }
+  
+  //! is the queue empty?
+  bool empty_p() const { return msg_queue.empty(); }
 
+  //| Acquires and release the mutex   
+  void insert_tail(pmt::pmt_t msg);
+
+  /*!
+   * \returns returns pmt at head of queue or pmt_t() if empty.
+   */
+  pmt::pmt_t delete_head_nowait();
+
+  /*!
+   * \returns returns pmt at head of queue or pmt_t() if empty.
+   * Caller must already be holding the mutex
+   */
+  pmt::pmt_t delete_head_nowait_already_holding_mutex();
+
 private:
 
   //! Used by notify_downstream

Modified: gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_tpb_thread_body.cc
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_tpb_thread_body.cc  
2009-08-15 18:34:45 UTC (rev 11600)
+++ gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_tpb_thread_body.cc  
2009-08-16 01:03:39 UTC (rev 11601)
@@ -24,17 +24,26 @@
 #include <gr_tpb_thread_body.h>
 #include <iostream>
 #include <boost/thread.hpp>
+#include <gruel/pmt.h>
 
+using namespace pmt;
+
 gr_tpb_thread_body::gr_tpb_thread_body(gr_block_sptr block)
   : d_exec(block)
 {
   // std::cerr << "gr_tpb_thread_body: " << block << std::endl;
 
-  gr_block_detail      *d = block->detail().get();
+  gr_block_detail *d = block->detail().get();
   gr_block_executor::state s;
+  pmt_t msg;
 
+
   while (1){
     boost::this_thread::interruption_point();
+ 
+    // handle any queued up messages
+    while ((msg = d->d_tpb.delete_head_nowait()))
+      block->handle_msg(msg);
 
     d->d_tpb.clear_changed();
     s = d_exec.run_one_iteration();
@@ -55,16 +64,39 @@
     case gr_block_executor::BLKD_IN:           // Wait for input.
       {
        gruel::scoped_lock guard(d->d_tpb.mutex);
-       while(!d->d_tpb.input_changed)
-         d->d_tpb.input_cond.wait(guard);
+       while (!d->d_tpb.input_changed){
+         
+         // wait for input or message
+         while(!d->d_tpb.input_changed && d->d_tpb.empty_p())
+           d->d_tpb.input_cond.wait(guard);
+
+         // handle all pending messages
+         while ((msg = d->d_tpb.delete_head_nowait_already_holding_mutex())){
+           guard.unlock();                     // release lock while 
processing msg
+           block->handle_msg(msg);
+           guard.lock();
+         }
+       }
       }
       break;
+
       
     case gr_block_executor::BLKD_OUT:          // Wait for output buffer space.
       {
        gruel::scoped_lock guard(d->d_tpb.mutex);
-       while(!d->d_tpb.output_changed)
-         d->d_tpb.output_cond.wait(guard);
+       while (!d->d_tpb.output_changed){
+         
+         // wait for output room or message
+         while(!d->d_tpb.output_changed && d->d_tpb.empty_p())
+           d->d_tpb.output_cond.wait(guard);
+
+         // handle all pending messages
+         while ((msg = d->d_tpb.delete_head_nowait_already_holding_mutex())){
+           guard.unlock();                     // release lock while 
processing msg
+           block->handle_msg(msg);
+           guard.lock();
+         }
+       }
       }
       break;
 

Modified: gnuradio/trunk/grc/base/Block.py
===================================================================
--- gnuradio/trunk/grc/base/Block.py    2009-08-15 18:34:45 UTC (rev 11600)
+++ gnuradio/trunk/grc/base/Block.py    2009-08-16 01:03:39 UTC (rev 11601)
@@ -46,6 +46,9 @@
        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 @@
                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 @@
                                '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 @@
        ##############################################
        # 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()], [])

Modified: gnuradio/trunk/grc/base/Param.py
===================================================================
--- gnuradio/trunk/grc/base/Param.py    2009-08-15 18:34:45 UTC (rev 11600)
+++ gnuradio/trunk/grc/base/Param.py    2009-08-16 01:03:39 UTC (rev 11601)
@@ -165,6 +165,8 @@
                        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):
                """

Modified: gnuradio/trunk/grc/blocks/Makefile.am
===================================================================
--- gnuradio/trunk/grc/blocks/Makefile.am       2009-08-15 18:34:45 UTC (rev 
11600)
+++ gnuradio/trunk/grc/blocks/Makefile.am       2009-08-16 01:03:39 UTC (rev 
11601)
@@ -123,6 +123,8 @@
        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 \

Modified: gnuradio/trunk/grc/blocks/block_tree.xml
===================================================================
--- gnuradio/trunk/grc/blocks/block_tree.xml    2009-08-15 18:34:45 UTC (rev 
11600)
+++ gnuradio/trunk/grc/blocks/block_tree.xml    2009-08-16 01:03:39 UTC (rev 
11601)
@@ -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>

Added: gnuradio/trunk/grc/blocks/gr_message_sink.xml
===================================================================
--- gnuradio/trunk/grc/blocks/gr_message_sink.xml                               
(rev 0)
+++ gnuradio/trunk/grc/blocks/gr_message_sink.xml       2009-08-16 01:03:39 UTC 
(rev 11601)
@@ -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 &gt; 0</check>
+       <sink>
+               <name>in</name>
+               <type>$type</type>
+               <vlen>$vlen</vlen>
+       </sink>
+       <source>
+               <name>out</name>
+               <type>msg</type>
+       </source>
+</block>

Added: gnuradio/trunk/grc/blocks/gr_message_source.xml
===================================================================
--- gnuradio/trunk/grc/blocks/gr_message_source.xml                             
(rev 0)
+++ gnuradio/trunk/grc/blocks/gr_message_source.xml     2009-08-16 01:03:39 UTC 
(rev 11601)
@@ -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 &gt; 0</check>
+       <sink>
+               <name>in</name>
+               <type>msg</type>
+       </sink>
+       <source>
+               <name>out</name>
+               <type>$type</type>
+               <vlen>$vlen</vlen>
+       </source>
+</block>

Modified: gnuradio/trunk/grc/gui/Block.py
===================================================================
--- gnuradio/trunk/grc/gui/Block.py     2009-08-15 18:34:45 UTC (rev 11600)
+++ gnuradio/trunk/grc/gui/Block.py     2009-08-16 01:03:39 UTC (rev 11601)
@@ -43,7 +43,7 @@
                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 @@
                                '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 @@
                                'value': '0',
                                'hide': 'all',
                        })
-               )
+               ))
                Element.__init__(self)
 
        def get_coordinate(self):

Modified: gnuradio/trunk/grc/python/Block.py
===================================================================
--- gnuradio/trunk/grc/python/Block.py  2009-08-15 18:34:45 UTC (rev 11600)
+++ gnuradio/trunk/grc/python/Block.py  2009-08-16 01:03:39 UTC (rev 11601)
@@ -66,16 +66,16 @@
                                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 @@
                        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):

Modified: gnuradio/trunk/grc/python/Connection.py
===================================================================
--- gnuradio/trunk/grc/python/Connection.py     2009-08-15 18:34:45 UTC (rev 
11600)
+++ gnuradio/trunk/grc/python/Connection.py     2009-08-16 01:03:39 UTC (rev 
11601)
@@ -21,6 +21,9 @@
 
 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.

Modified: gnuradio/trunk/grc/python/Constants.py
===================================================================
--- gnuradio/trunk/grc/python/Constants.py      2009-08-15 18:34:45 UTC (rev 
11600)
+++ gnuradio/trunk/grc/python/Constants.py      2009-08-16 01:03:39 UTC (rev 
11601)
@@ -61,3 +61,4 @@
 BYTE_VECTOR_COLOR_SPEC = '#CC66CC'
 ID_COLOR_SPEC = '#DDDDDD'
 WILDCARD_COLOR_SPEC = '#FFFFFF'
+MSG_COLOR_SPEC = '#777777'

Modified: gnuradio/trunk/grc/python/Generator.py
===================================================================
--- gnuradio/trunk/grc/python/Generator.py      2009-08-15 18:34:45 UTC (rev 
11600)
+++ gnuradio/trunk/grc/python/Generator.py      2009-08-16 01:03:39 UTC (rev 
11601)
@@ -98,7 +98,8 @@
                #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 @@
                        'parameters': parameters,
                        'blocks': blocks,
                        'connections': connections,
+                       'messages': messages,
                        'generate_options': self._generate_options,
                        'var_id2cbs': var_id2cbs,
                }

Modified: gnuradio/trunk/grc/python/Platform.py
===================================================================
--- gnuradio/trunk/grc/python/Platform.py       2009-08-15 18:34:45 UTC (rev 
11600)
+++ gnuradio/trunk/grc/python/Platform.py       2009-08-16 01:03:39 UTC (rev 
11601)
@@ -42,7 +42,8 @@
        ('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):

Modified: gnuradio/trunk/grc/python/Port.py
===================================================================
--- gnuradio/trunk/grc/python/Port.py   2009-08-15 18:34:45 UTC (rev 11600)
+++ gnuradio/trunk/grc/python/Port.py   2009-08-16 01:03:39 UTC (rev 11601)
@@ -23,27 +23,23 @@
 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 @@
                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 @@
                                        '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 @@
                        }[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

Modified: gnuradio/trunk/grc/python/flow_graph.tmpl
===================================================================
--- gnuradio/trunk/grc/python/flow_graph.tmpl   2009-08-15 18:34:45 UTC (rev 
11600)
+++ gnuradio/trunk/grc/python/flow_graph.tmpl   2009-08-16 01:03:39 UTC (rev 
11601)
@@ -10,6 +10,7 @@
 address@hidden parameters the paramater blocks
 address@hidden blocks the signal blocks
 address@hidden connections the connections
address@hidden messages the msg type connections
 address@hidden generate_options the type of flow graph
 address@hidden var_id2cbs variable id map to callback strings
 ########################################################
@@ -125,6 +126,18 @@
                $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

Modified: gnuradio/trunk/grc/todo.txt
===================================================================
--- gnuradio/trunk/grc/todo.txt 2009-08-15 18:34:45 UTC (rev 11600)
+++ gnuradio/trunk/grc/todo.txt 2009-08-16 01:03:39 UTC (rev 11601)
@@ -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

Modified: gnuradio/trunk/gruel/src/include/gruel/Makefile.am
===================================================================
--- gnuradio/trunk/gruel/src/include/gruel/Makefile.am  2009-08-15 18:34:45 UTC 
(rev 11600)
+++ gnuradio/trunk/gruel/src/include/gruel/Makefile.am  2009-08-16 01:03:39 UTC 
(rev 11601)
@@ -35,6 +35,7 @@
        pmt_pool.h \
        pmt_serial_tags.h \
        realtime.h \
+       send.h \
        sys_pri.h \
        thread_body_wrapper.h \
        thread_group.h \

Modified: gnuradio/trunk/gruel/src/include/gruel/msg_accepter.h
===================================================================
--- gnuradio/trunk/gruel/src/include/gruel/msg_accepter.h       2009-08-15 
18:34:45 UTC (rev 11600)
+++ gnuradio/trunk/gruel/src/include/gruel/msg_accepter.h       2009-08-16 
01:03:39 UTC (rev 11601)
@@ -18,8 +18,8 @@
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
-#ifndef INCLUDED_MSG_ACCEPTER_H
-#define INCLUDED_MSG_ACCEPTER_H
+#ifndef INCLUDED_GRUEL_MSG_ACCEPTER_H
+#define INCLUDED_GRUEL_MSG_ACCEPTER_H
 
 #include <gruel/pmt.h>
 
@@ -34,9 +34,16 @@
     msg_accepter() {};
     virtual ~msg_accepter();
 
+    /*!
+     * \brief send \p msg to \p msg_accepter
+     *
+     * Sending a message is an asynchronous operation.  The \p post
+     * call will not wait for the message either to arrive at the
+     * destination or to be received.
+     */
     virtual void post(pmt::pmt_t msg) = 0;
   };
 
 } /* namespace gruel */
 
-#endif /* INCLUDED_MSG_ACCEPTER_H */
+#endif /* INCLUDED_GRUEL_MSG_ACCEPTER_H */

Modified: gnuradio/trunk/gruel/src/include/gruel/msg_accepter_msgq.h
===================================================================
--- gnuradio/trunk/gruel/src/include/gruel/msg_accepter_msgq.h  2009-08-15 
18:34:45 UTC (rev 11600)
+++ gnuradio/trunk/gruel/src/include/gruel/msg_accepter_msgq.h  2009-08-16 
01:03:39 UTC (rev 11601)
@@ -32,13 +32,14 @@
    */
   class msg_accepter_msgq : public msg_accepter 
   {
+  protected:
     msg_queue_sptr d_msg_queue;
     
   public:
     msg_accepter_msgq(msg_queue_sptr msgq);
     ~msg_accepter_msgq();
 
-    void post(pmt::pmt_t msg);
+    virtual void post(pmt::pmt_t msg);
 
     msg_queue_sptr msg_queue() const { return d_msg_queue; }
   };

Modified: gnuradio/trunk/gruel/src/include/gruel/pmt.h
===================================================================
--- gnuradio/trunk/gruel/src/include/gruel/pmt.h        2009-08-15 18:34:45 UTC 
(rev 11600)
+++ gnuradio/trunk/gruel/src/include/gruel/pmt.h        2009-08-16 01:03:39 UTC 
(rev 11601)
@@ -239,6 +239,42 @@
 
 /*
  * ------------------------------------------------------------------------
+ *                               Tuples
+ *
+ * Store a fixed number of objects.  Tuples are not modifiable, and thus
+ * are excellent for use as messages.  Indexing is zero based.
+ * Access time to an element is O(1).
+ * ------------------------------------------------------------------------
+ */
+
+//! Return true if \p x is a tuple, othewise false.
+bool pmt_is_tuple(pmt_t x);
+
+pmt_t pmt_make_tuple();
+pmt_t pmt_make_tuple(const pmt_t &e0);
+pmt_t pmt_make_tuple(const pmt_t &e0, const pmt_t &e1);
+pmt_t pmt_make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2);
+pmt_t pmt_make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const 
pmt_t &e3);
+pmt_t pmt_make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const 
pmt_t &e3, const pmt_t &e4);
+pmt_t pmt_make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const 
pmt_t &e3, const pmt_t &e4, const pmt_t &e5);
+pmt_t pmt_make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const 
pmt_t &e3, const pmt_t &e4, const pmt_t &e5, const pmt_t &e6);
+pmt_t pmt_make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const 
pmt_t &e3, const pmt_t &e4, const pmt_t &e5, const pmt_t &e6, const pmt_t &e7);
+pmt_t pmt_make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const 
pmt_t &e3, const pmt_t &e4, const pmt_t &e5, const pmt_t &e6, const pmt_t &e7, 
const pmt_t &e8);
+pmt_t pmt_make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const 
pmt_t &e3, const pmt_t &e4, const pmt_t &e5, const pmt_t &e6, const pmt_t &e7, 
const pmt_t &e8, const pmt_t &e9);
+
+/*!
+ * If \p x is a vector or proper list, return a tuple containing the elements 
of x
+ */
+pmt_t pmt_to_tuple(const pmt_t &x);
+
+/*!
+ * Return the contents of position \p k of \p tuple.
+ * \p k must be a valid index of \p tuple.
+ */
+pmt_t pmt_tuple_ref(const pmt_t &tuple, size_t k);
+
+/*
+ * ------------------------------------------------------------------------
  *                            Vectors
  *
  * These vectors can hold any kind of objects.  Indexing is zero based.

Copied: gnuradio/trunk/gruel/src/include/gruel/send.h (from rev 11600, 
gnuradio/trunk/gruel/src/include/gruel/msg_accepter.h)
===================================================================
--- gnuradio/trunk/gruel/src/include/gruel/send.h                               
(rev 0)
+++ gnuradio/trunk/gruel/src/include/gruel/send.h       2009-08-16 01:03:39 UTC 
(rev 11601)
@@ -0,0 +1,49 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef INCLUDED_GRUEL_SEND_H
+#define INCLUDED_GRUEL_SEND_H
+
+#include <gruel/msg_accepter.h>
+
+namespace gruel {
+
+
+  /*!
+   * \brief send \p msg to \p msg_accepter
+   *
+   * Sending a message is an asynchronous operation.  The \p send
+   * call will not wait for the message either to arrive at the
+   * destination or to be received.
+   *
+   * \returns msg
+   */
+  static inline pmt::pmt_t
+  send(msg_accepter &acc, pmt::pmt_t msg)
+  {
+    return acc.post(msg);
+  }
+
+
+
+} /* namespace gruel */
+
+
+#endif /* INCLUDED_SEND_H */

Modified: gnuradio/trunk/gruel/src/lib/pmt/pmt.cc
===================================================================
--- gnuradio/trunk/gruel/src/lib/pmt/pmt.cc     2009-08-15 18:34:45 UTC (rev 
11600)
+++ gnuradio/trunk/gruel/src/lib/pmt/pmt.cc     2009-08-16 01:03:39 UTC (rev 
11601)
@@ -128,6 +128,12 @@
   return dynamic_cast<pmt_vector*>(x.get());
 }
 
+static pmt_tuple *
+_tuple(pmt_t x)
+{
+  return dynamic_cast<pmt_tuple*>(x.get());
+}
+
 static pmt_uniform_vector *
 _uniform_vector(pmt_t x)
 {
@@ -497,6 +503,201 @@
 }
 
 ////////////////////////////////////////////////////////////////////////////
+//                             Tuples
+////////////////////////////////////////////////////////////////////////////
+
+pmt_tuple::pmt_tuple(size_t len)
+  : d_v(len)
+{
+}
+
+pmt_t
+pmt_tuple::ref(size_t k) const
+{
+  if (k >= length())
+    throw pmt_out_of_range("pmt_tuple_ref", pmt_from_long(k));
+  return d_v[k];
+}
+
+bool
+pmt_is_tuple(pmt_t obj)
+{
+  return obj->is_tuple();
+}
+
+pmt_t
+pmt_tuple_ref(const pmt_t &tuple, size_t k)
+{
+  if (!tuple->is_tuple())
+    throw pmt_wrong_type("pmt_tuple_ref", tuple);
+  return _tuple(tuple)->ref(k);
+}
+
+// for (i=0; i < 10; i++)
+//   make_constructor()
+
+pmt_t
+pmt_make_tuple()
+{
+  return pmt_t(new pmt_tuple(0));
+}
+
+pmt_t
+pmt_make_tuple(const pmt_t &e0)
+{
+  pmt_tuple *t = new pmt_tuple(1);
+  t->_set(0, e0);
+  return pmt_t(t);
+}
+
+pmt_t
+pmt_make_tuple(const pmt_t &e0, const pmt_t &e1)
+{
+  pmt_tuple *t = new pmt_tuple(2);
+  t->_set(0, e0);
+  t->_set(1, e1);
+  return pmt_t(t);
+}
+
+pmt_t
+pmt_make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2)
+{
+  pmt_tuple *t = new pmt_tuple(3);
+  t->_set(0, e0);
+  t->_set(1, e1);
+  t->_set(2, e2);
+  return pmt_t(t);
+}
+
+pmt_t
+pmt_make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t 
&e3)
+{
+  pmt_tuple *t = new pmt_tuple(4);
+  t->_set(0, e0);
+  t->_set(1, e1);
+  t->_set(2, e2);
+  t->_set(3, e3);
+  return pmt_t(t);
+}
+
+pmt_t
+pmt_make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t 
&e3, const pmt_t &e4)
+{
+  pmt_tuple *t = new pmt_tuple(5);
+  t->_set(0, e0);
+  t->_set(1, e1);
+  t->_set(2, e2);
+  t->_set(3, e3);
+  t->_set(4, e4);
+  return pmt_t(t);
+}
+
+pmt_t
+pmt_make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t 
&e3, const pmt_t &e4, const pmt_t &e5)
+{
+  pmt_tuple *t = new pmt_tuple(6);
+  t->_set(0, e0);
+  t->_set(1, e1);
+  t->_set(2, e2);
+  t->_set(3, e3);
+  t->_set(4, e4);
+  t->_set(5, e5);
+  return pmt_t(t);
+}
+
+pmt_t
+pmt_make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t 
&e3, const pmt_t &e4, const pmt_t &e5, const pmt_t &e6)
+{
+  pmt_tuple *t = new pmt_tuple(7);
+  t->_set(0, e0);
+  t->_set(1, e1);
+  t->_set(2, e2);
+  t->_set(3, e3);
+  t->_set(4, e4);
+  t->_set(5, e5);
+  t->_set(6, e6);
+  return pmt_t(t);
+}
+
+pmt_t
+pmt_make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t 
&e3, const pmt_t &e4, const pmt_t &e5, const pmt_t &e6, const pmt_t &e7)
+{
+  pmt_tuple *t = new pmt_tuple(8);
+  t->_set(0, e0);
+  t->_set(1, e1);
+  t->_set(2, e2);
+  t->_set(3, e3);
+  t->_set(4, e4);
+  t->_set(5, e5);
+  t->_set(6, e6);
+  t->_set(7, e7);
+  return pmt_t(t);
+}
+
+pmt_t
+pmt_make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t 
&e3, const pmt_t &e4, const pmt_t &e5, const pmt_t &e6, const pmt_t &e7, const 
pmt_t &e8)
+{
+  pmt_tuple *t = new pmt_tuple(9);
+  t->_set(0, e0);
+  t->_set(1, e1);
+  t->_set(2, e2);
+  t->_set(3, e3);
+  t->_set(4, e4);
+  t->_set(5, e5);
+  t->_set(6, e6);
+  t->_set(7, e7);
+  t->_set(8, e8);
+  return pmt_t(t);
+}
+
+pmt_t
+pmt_make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t 
&e3, const pmt_t &e4, const pmt_t &e5, const pmt_t &e6, const pmt_t &e7, const 
pmt_t &e8, const pmt_t &e9)
+{
+  pmt_tuple *t = new pmt_tuple(10);
+  t->_set(0, e0);
+  t->_set(1, e1);
+  t->_set(2, e2);
+  t->_set(3, e3);
+  t->_set(4, e4);
+  t->_set(5, e5);
+  t->_set(6, e6);
+  t->_set(7, e7);
+  t->_set(8, e8);
+  t->_set(9, e9);
+  return pmt_t(t);
+}
+
+pmt_t
+pmt_to_tuple(const pmt_t &x)
+{
+  if (x->is_tuple())           // already one
+    return x;
+
+  size_t len = pmt_length(x);
+  pmt_tuple *t = new pmt_tuple(len);
+  pmt_t r = pmt_t(t);
+
+  if (x->is_vector()){
+    for (size_t i = 0; i < len; i++)
+      t->_set(i, _vector(x)->ref(i));
+    return r;
+  }
+
+  if (x->is_pair()){
+    pmt_t y = x;
+    for (size_t i = 0; i < len; i++){
+      t->_set(i, pmt_car(y));
+      y = pmt_cdr(y);
+    }
+    return r;
+  }
+
+  throw pmt_wrong_type("pmt_to_tuple", x);
+}
+
+
+
+////////////////////////////////////////////////////////////////////////////
 //                       Uniform Numeric Vectors
 ////////////////////////////////////////////////////////////////////////////
 
@@ -730,6 +931,19 @@
     return true;
   }
 
+  if (x->is_tuple() && y->is_tuple()){
+    pmt_tuple *xv = _tuple(x);
+    pmt_tuple *yv = _tuple(y);
+    if (xv->length() != yv->length())
+      return false;
+
+    for (unsigned i = 0; i < xv->length(); i++)
+      if (!pmt_equal(xv->_ref(i), yv->_ref(i)))
+       return false;
+
+    return true;
+  }
+
   if (x->is_uniform_vector() && y->is_uniform_vector()){
     pmt_uniform_vector *xv = _uniform_vector(x);
     pmt_uniform_vector *yv = _uniform_vector(y);
@@ -759,11 +973,15 @@
   if (x->is_uniform_vector())
     return _uniform_vector(x)->length();
 
-  if (x->is_null()) return 0;
+  if (x->is_tuple())
+    return _tuple(x)->length();
 
+  if (x->is_null())
+    return 0;
+
   if (x->is_pair()) {
     size_t length=1;
-       pmt_t it = pmt_cdr(x);
+    pmt_t it = pmt_cdr(x);
     while (pmt_is_pair(it)){
       length++;
       it = pmt_cdr(it);

Modified: gnuradio/trunk/gruel/src/lib/pmt/pmt_int.h
===================================================================
--- gnuradio/trunk/gruel/src/lib/pmt/pmt_int.h  2009-08-15 18:34:45 UTC (rev 
11600)
+++ gnuradio/trunk/gruel/src/lib/pmt/pmt_int.h  2009-08-16 01:03:39 UTC (rev 
11601)
@@ -51,6 +51,7 @@
   virtual bool is_complex() const { return false; }
   virtual bool is_null()    const { return false; }
   virtual bool is_pair()    const { return false; }
+  virtual bool is_tuple()   const { return false; }
   virtual bool is_vector()  const { return false; }
   virtual bool is_dict()    const { return false; }
   virtual bool is_any()     const { return false; }
@@ -186,6 +187,22 @@
   pmt_t _ref(size_t k) const { return d_v[k]; }
 };
 
+class pmt_tuple : public pmt_base
+{
+  std::vector<pmt_t>   d_v;
+
+public:
+  pmt_tuple(size_t len);
+  //~pmt_tuple();
+
+  bool is_tuple() const { return true; }
+  pmt_t ref(size_t k) const;
+  size_t length() const { return d_v.size(); }
+
+  pmt_t _ref(size_t k) const { return d_v[k]; }
+  void _set(size_t k, pmt_t v) { d_v[k] = v; }
+};
+
 class pmt_dict : public pmt_base
 {
   pmt_t                d_alist;        // list of (key . value) pairs

Modified: gnuradio/trunk/gruel/src/lib/pmt/pmt_io.cc
===================================================================
--- gnuradio/trunk/gruel/src/lib/pmt/pmt_io.cc  2009-08-15 18:34:45 UTC (rev 
11600)
+++ gnuradio/trunk/gruel/src/lib/pmt/pmt_io.cc  2009-08-16 01:03:39 UTC (rev 
11601)
@@ -80,16 +80,31 @@
     port << "(";
     pmt_write_list_tail(obj, port);
   }
+  else if (pmt_is_tuple(obj)){
+    port << "{";
+    size_t len = pmt_length(obj);
+    if (len > 0){
+      port << pmt_tuple_ref(obj, 0);
+      for (size_t i = 1; i < len; i++)
+       port << " " << pmt_tuple_ref(obj, i);
+    }
+    port << "}";
+  }
+  else if (pmt_is_vector(obj)){
+    port << "#(";
+    size_t len = pmt_length(obj);
+    if (len > 0){
+      port << pmt_vector_ref(obj, 0);
+      for (size_t i = 1; i < len; i++)
+       port << " " << pmt_vector_ref(obj, i);
+    }
+    port << ")";
+  }
   else if (pmt_is_dict(obj)){
     // FIXME
     // port << "#<dict " << obj << ">";
     port << "#<dict>";
   }
-  else if (pmt_is_vector(obj)){
-    // FIXME
-    // port << "#<vector " << obj << ">";
-    port << "#<vector>";
-  }
   else if (pmt_is_uniform_vector(obj)){
     // FIXME
     // port << "#<uniform-vector " << obj << ">";

Modified: gnuradio/trunk/gruel/src/lib/pmt/qa_pmt_prims.cc
===================================================================
--- gnuradio/trunk/gruel/src/lib/pmt/qa_pmt_prims.cc    2009-08-15 18:34:45 UTC 
(rev 11600)
+++ gnuradio/trunk/gruel/src/lib/pmt/qa_pmt_prims.cc    2009-08-16 01:03:39 UTC 
(rev 11601)
@@ -193,7 +193,92 @@
     CPPUNIT_ASSERT_EQUAL(s0, pmt_vector_ref(v1, i));
 }
 
+static void
+check_tuple(size_t len, const std::vector<pmt_t> &s, pmt_t t)
+{
+  CPPUNIT_ASSERT_EQUAL(true, pmt_is_tuple(t));
+  CPPUNIT_ASSERT_EQUAL(len, pmt_length(t));
+
+  for (size_t i = 0; i < len; i++)
+    CPPUNIT_ASSERT_EQUAL(s[i], pmt_tuple_ref(t, i));
+
+}
+
 void
+qa_pmt_prims::test_tuples()
+{
+  pmt_t v = pmt_make_vector(10, PMT_NIL);
+  std::vector<pmt_t> s(10);
+  for (size_t i = 0; i < 10; i++){
+    std::ostringstream os;
+    os << "s" << i;
+    s[i] = pmt_string_to_symbol(os.str());
+    pmt_vector_set(v, i, s[i]);
+  }
+
+
+  pmt_t t;
+
+  t = pmt_make_tuple();
+  check_tuple(0, s, t);
+
+  t = pmt_make_tuple(s[0]);
+  check_tuple(1, s, t);
+
+  CPPUNIT_ASSERT(pmt_is_vector(v));
+  CPPUNIT_ASSERT(!pmt_is_tuple(v));
+  CPPUNIT_ASSERT(pmt_is_tuple(t));
+  CPPUNIT_ASSERT(!pmt_is_vector(t));
+
+  t = pmt_make_tuple(s[0], s[1]);
+  check_tuple(2, s, t);
+
+  t = pmt_make_tuple(s[0], s[1], s[2]);
+  check_tuple(3, s, t);
+
+  t = pmt_make_tuple(s[0], s[1], s[2], s[3]);
+  check_tuple(4, s, t);
+
+  t = pmt_make_tuple(s[0], s[1], s[2], s[3], s[4]);
+  check_tuple(5, s, t);
+
+  t = pmt_make_tuple(s[0], s[1], s[2], s[3], s[4], s[5]);
+  check_tuple(6, s, t);
+
+  t = pmt_make_tuple(s[0], s[1], s[2], s[3], s[4], s[5], s[6]);
+  check_tuple(7, s, t);
+
+  t = pmt_make_tuple(s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7]);
+  check_tuple(8, s, t);
+
+  t = pmt_make_tuple(s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7], s[8]);
+  check_tuple(9, s, t);
+
+  t = pmt_make_tuple(s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7], s[8], 
s[9]);
+  check_tuple(10, s, t);
+
+  t = pmt_make_tuple(s[0], s[1], s[2]);
+  CPPUNIT_ASSERT_THROW(pmt_tuple_ref(t, 3), pmt_out_of_range);
+  CPPUNIT_ASSERT_THROW(pmt_vector_ref(t, 0), pmt_wrong_type);
+  CPPUNIT_ASSERT_THROW(pmt_tuple_ref(v, 0), pmt_wrong_type);
+
+  t = pmt_make_tuple(s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7], s[8], 
s[9]);
+  pmt_t t2 = pmt_to_tuple(v);
+  CPPUNIT_ASSERT_EQUAL(size_t(10), pmt_length(v));
+  CPPUNIT_ASSERT(pmt_equal(t, t2));
+  //std::cout << v << std::endl;
+  //std::cout << t2 << std::endl;
+
+  
+  t = pmt_make_tuple(s[0], s[1], s[2]);
+  pmt_t list0 = pmt_list3(s[0], s[1], s[2]);
+  CPPUNIT_ASSERT_EQUAL(size_t(3), pmt_length(list0));
+  t2 = pmt_to_tuple(list0);
+  CPPUNIT_ASSERT_EQUAL(size_t(3), pmt_length(t2));
+  CPPUNIT_ASSERT(pmt_equal(t, t2));
+}
+
+void
 qa_pmt_prims::test_equivalence()
 {
   pmt_t s0 = pmt_string_to_symbol("s0");
@@ -436,3 +521,4 @@
   CPPUNIT_ASSERT(!pmt_subsetp(l2,l1));
   CPPUNIT_ASSERT(!pmt_subsetp(l3,l2));
 }
+

Modified: gnuradio/trunk/gruel/src/lib/pmt/qa_pmt_prims.h
===================================================================
--- gnuradio/trunk/gruel/src/lib/pmt/qa_pmt_prims.h     2009-08-15 18:34:45 UTC 
(rev 11600)
+++ gnuradio/trunk/gruel/src/lib/pmt/qa_pmt_prims.h     2009-08-16 01:03:39 UTC 
(rev 11601)
@@ -35,6 +35,7 @@
   CPPUNIT_TEST(test_complexes);
   CPPUNIT_TEST(test_pairs);
   CPPUNIT_TEST(test_vectors);
+  CPPUNIT_TEST(test_tuples);
   CPPUNIT_TEST(test_equivalence);
   CPPUNIT_TEST(test_misc);
   CPPUNIT_TEST(test_dict);
@@ -53,6 +54,7 @@
   void test_complexes();
   void test_pairs();
   void test_vectors();
+  void test_tuples();
   void test_equivalence();
   void test_misc();
   void test_dict();





reply via email to

[Prev in Thread] Current Thread [Next in Thread]