Merged mblock work-in-progress (eb/mb r4273:4312) into trunk.
[debian/gnuradio] / mblock / src / lib / mb_mblock.h
1 /* -*- c++ -*- */
2 /*
3  * Copyright 2006 Free Software Foundation, Inc.
4  * 
5  * This file is part of GNU Radio
6  * 
7  * GNU Radio is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2, or (at your option)
10  * any later version.
11  * 
12  * GNU Radio is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License along
18  * with this program; if not, write to the Free Software Foundation, Inc.,
19  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20  */
21 #ifndef INCLUDED_MB_MBLOCK_H
22 #define INCLUDED_MB_MBLOCK_H
23
24 #include <mb_common.h>
25 #include <mb_message.h>
26 #include <mb_port.h>
27 #include <boost/enable_shared_from_this.hpp>
28
29
30 /*!
31  * Abstract class implementing visitor pattern
32  * \ingroup internal
33  */
34 class mb_visitor
35 {
36 public:
37   virtual ~mb_visitor();
38   bool operator()(mb_mblock *mblock, const std::string &path) { return visit(mblock, path); }
39   virtual bool visit(mb_mblock *mblock, const std::string &path) = 0;
40 };
41
42 // ----------------------------------------------------------------------
43
44 /*!
45  * \brief Parent class for all message passing blocks
46  *
47  * Subclass this to define your mblocks.
48  */
49 class mb_mblock : boost::noncopyable,
50                   public boost::enable_shared_from_this<mb_mblock>
51 {
52 private:
53   mb_mblock_impl_sptr           d_impl;         // implementation details
54
55   friend class mb_runtime;
56   friend class mb_mblock_impl;
57
58 protected:
59   /*!
60    * \brief mblock constructor.
61    *
62    * Initializing all mblocks in the system is a 3 step procedure.
63    *
64    * The top level mblock's constructor is run.  That constructor (a)
65    * registers all of its ports using define_port, (b) constructs and
66    * registers any subcomponents it may have via the define_component
67    * method, and then (c) issues connect calls to wire its
68    * subcomponents together.
69    */
70   mb_mblock();
71
72   /*!
73    * \brief Called by the runtime system to execute the initial
74    * transition of the finite state machine.
75    *
76    * Override this to initialize your finite state machine.
77    */
78   virtual void init_fsm();
79
80   /*!
81    * \brief Called by the runtime system when there's a message to handle.
82    *
83    * Override this to define your behavior.
84    *
85    * Do not issue any potentially blocking calls in this method.  This
86    * includes things such reads or writes on sockets, pipes or slow
87    * i/o devices.
88    */
89   virtual void handle_message(mb_message_sptr msg);
90
91   /*!
92    * \brief Define a port.
93    *
94    * EXTERNAL and RELAY ports are part of our peer interface.
95    * INTERNAL ports are used to talk to sub-components.
96    *
97    * \param port_name    The name of the port (must be unique within this mblock).
98    * \param protocol_class_name The name of the protocol class associated with
99    *                            this port.  It must already be defined.
100    * \param conjugated   Are the incoming and outgoing message sets swapped?
101    * \param port_type    INTERNAL, EXTERNAL or RELAY.
102    */
103   mb_port_sptr
104   define_port(const std::string &port_name,
105               const std::string &protocol_class_name,
106               bool conjugated,
107               mb_port::port_type_t port_type);
108
109   /*!
110    * \brief Define a subcomponent by name.
111    *
112    * Called within the constructor to tell the system the
113    * names and identities of our sub-component mblocks.
114    *
115    * \param component_name  The name of the sub-component (must be unique with this mblock).
116    * \param component       The sub-component instance.
117    */
118   void
119   define_component(const std::string &component_name,
120                    mb_mblock_sptr component);
121
122   /*!
123    * \brief connect endpoint_1 to endpoint_2
124    *
125    * \param comp_name1  component on one end of the connection
126    * \param port_name1  the name of the port on comp1
127    * \param comp_name2  component on the other end of the connection
128    * \param port_name2  the name of the port on comp2
129    *
130    * An endpoint is specified by the component's local name (given as
131    * component_name in the call to register_component) and the name of
132    * the port on that component.
133    *
134    * To connect an internal or relay port, use "self" as the component name.
135    */
136   void
137   connect(const std::string &comp_name1, const std::string &port_name1,
138           const std::string &comp_name2, const std::string &port_name2);
139
140   /*!
141    * \brief disconnect endpoint_1 from endpoint_2
142    *
143    * \param comp_name1  component on one end of the connection
144    * \param port_name1  the name of the port on comp1
145    * \param comp_name2  component on the other end of the connection
146    * \param port_name2  the name of the port on comp2
147    *
148    * An endpoint is specified by the component's local name (given as
149    * component_name in the call to register_component) and the name of
150    * the port on that component.
151    *
152    * To disconnect an internal or relay port, use "self" as the component name.
153    */
154   void
155   disconnect(const std::string &comp_name1, const std::string &port_name1,
156              const std::string &comp_name2, const std::string &port_name2);
157
158   /*!
159    * \brief disconnect all connections to specified component
160    * \param component_name component to disconnect
161    */
162   void
163   disconnect_component(const std::string component_name);
164
165   /*!
166    * \brief disconnect all connections to all components
167    */
168   void
169   disconnect_all();
170
171   /*!
172    * \brief Return number of connections (QA mostly)
173    */
174   int
175   nconnections() const;
176
177
178 public:
179   virtual ~mb_mblock();
180
181   /*!
182    * \brief Perform a pre-order depth-first traversal of the hierarchy.
183    *
184    * The traversal stops and returns false if any call to visitor returns false.
185    */
186   bool
187   walk_tree(mb_visitor *visitor, const std::string &path="");
188
189
190   //! \implementation
191   // internal use only
192   mb_mblock_impl_sptr
193   impl() const { return d_impl; }
194
195 };
196
197
198 #endif /* INCLUDED_MB_MBLOCK_H */