Fawkes API  Fawkes Development Version
interface_dispatcher.cpp
1 
2 /***************************************************************************
3  * interface_dispatcher.cpp - BlackBoard listener and dispatcher
4  *
5  * Created: Thu Oct 09 23:07:16 2008
6  * Copyright 2008 Tim Niemueller [www.niemueller.de]
7  *
8  ****************************************************************************/
9 
10 /* This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version. A runtime exception applies to
14  * this software (see LICENSE.GPL_WRE file mentioned below for details).
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU Library General Public License for more details.
20  *
21  * Read the full text in the LICENSE.GPL_WRE file in the doc directory.
22  */
23 
24 #include <gui_utils/interface_dispatcher.h>
25 #include <interface/interface.h>
26 
27 namespace fawkes {
28 
29 /** @class InterfaceDispatcher <gui_utils/interface_dispatcher.h>
30  * Interface listener with dispatcher.
31  * An instance is used to react to a data changed event by triggering a
32  * signal dispatcher (which is thread-safe and can be used across thread borders
33  * in Glib/Gtk apps.
34  * You have to register this listener with BlackBoard::BBIL_FLAGS_DATA flag by
35  * yourself. Do not forget to unregister.
36  * @author Tim Niemueller
37  */
38 
39 /** Constructor.
40  * @param listener_name name of the listener
41  * @param iface interface to watch for data changes. Register this dispatcher as
42  * listener by yourself!
43  * @param message_enqueueing true to enqueue messages after the message received
44  * event handler has been called, false to drop the message afterwards.
45  */
46 InterfaceDispatcher::InterfaceDispatcher(const char *listener_name,
47  Interface *iface,
48  bool message_enqueueing)
49  : BlackBoardInterfaceListener(listener_name)
50 {
51  __message_enqueueing = message_enqueueing;
52 
54  if ( iface->is_writer() ) {
56  }
59 
60  setup_signals();
61 }
62 
63 /** Multi interface constructor.
64  * @param listener_name name of the listener
65  * @param ifaces list of interfaces to watch for data
66  * changes. Register this dispatcher as listener by yourself!
67  * @param message_enqueueing true to enqueue messages after the
68  * message received event handler has been called, false to drop the
69  * message afterwards.
70  */
71 InterfaceDispatcher::InterfaceDispatcher(const char *listener_name,
72  std::list<Interface *> ifaces,
73  bool message_enqueueing)
74  : BlackBoardInterfaceListener(listener_name)
75 {
76  __message_enqueueing = message_enqueueing;
77 
78  std::list<Interface *>::iterator i;
79  for (i = ifaces.begin(); i != ifaces.end(); ++i) {
81  if ( (*i)->is_writer() ) {
83  }
86  }
87 
88  setup_signals();
89 }
90 
91 
92 void
93 InterfaceDispatcher::setup_signals()
94 {
95  __dispatcher_data_changed.connect(sigc::mem_fun(*this, &InterfaceDispatcher::on_data_changed));
96  __dispatcher_message_received.connect(sigc::mem_fun(*this, &InterfaceDispatcher::on_message_received));
97  __dispatcher_writer_added.connect(sigc::mem_fun(*this, &InterfaceDispatcher::on_writer_added));
98  __dispatcher_writer_removed.connect(sigc::mem_fun(*this, &InterfaceDispatcher::on_writer_removed));
99  __dispatcher_reader_added.connect(sigc::mem_fun(*this, &InterfaceDispatcher::on_reader_added));
100  __dispatcher_reader_removed.connect(sigc::mem_fun(*this, &InterfaceDispatcher::on_writer_removed));
101 }
102 
103 /** Set if received messages should be enqueued or not.
104  * The message received event handler can cause the message to be enqueued or not.
105  * The default is to enqueue the messages.
106  * @param enqueue true to cause messages to be enqueued, false to cause the
107  * messages not to be enqueued after they have been processed
108  */
109 void
111 {
112  __message_enqueueing = enqueue;
113 }
114 
115 
116 /** Internal event handler.
117  * Called by dispatcher to emit signal.
118  */
119 void
121 {
122  __queue_data_changed.lock();
123  while (! __queue_data_changed.empty()) {
124  Interface *iface = __queue_data_changed.front();
125  __signal_data_changed.emit(iface);
126  __queue_data_changed.pop();
127  }
128  __queue_data_changed.unlock();
129 }
130 
131 
132 /** Internal event handler.
133  * Called by dispatcher to emit signal.
134  */
135 void
137 {
138  __queue_message_received.lock();
139  while (! __queue_message_received.empty()) {
140  std::pair<Interface *, Message *> p = __queue_message_received.front();
141  __signal_message_received.emit(p.first, p.second);
142  p.second->unref();
143  __queue_message_received.pop();
144  }
145  __queue_message_received.unlock();
146 }
147 
148 
149 /** Internal event handler.
150  * Called by dispatcher to emit signal.
151  */
152 void
154 {
155  __queue_writer_added.lock();
156  while (! __queue_writer_added.empty()) {
157  Interface *iface = __queue_writer_added.front();
158  __signal_writer_added.emit(iface);
159  __queue_writer_added.pop();
160  }
161  __queue_writer_added.unlock();
162 }
163 
164 
165 /** Internal event handler.
166  * Called by dispatcher to emit signal.
167  */
168 void
170 {
171  __queue_writer_removed.lock();
172  while (! __queue_writer_removed.empty()) {
173  Interface *iface = __queue_writer_removed.front();
174  __signal_writer_removed.emit(iface);
175  __queue_writer_removed.pop();
176  }
177  __queue_writer_removed.unlock();
178 }
179 
180 
181 /** Internal event handler.
182  * Called by dispatcher to emit signal.
183  */
184 void
186 {
187  __queue_reader_added.lock();
188  while (! __queue_reader_added.empty()) {
189  Interface *iface = __queue_reader_added.front();
190  __signal_reader_added.emit(iface);
191  __queue_reader_added.pop();
192  }
193  __queue_reader_added.unlock();
194 }
195 
196 
197 /** Internal event handler.
198  * Called by dispatcher to emit signal.
199  */
200 void
202 {
203  __queue_reader_removed.lock();
204  while (! __queue_reader_removed.empty()) {
205  Interface *iface = __queue_reader_removed.front();
206  __signal_reader_removed.emit(iface);
207  __queue_reader_removed.pop();
208  }
209  __queue_reader_removed.unlock();
210 }
211 
212 
213 void
215 {
216  __queue_data_changed.push_locked(interface);
217  __dispatcher_data_changed();
218 }
219 
220 bool
222 {
223  message->ref();
224  __queue_message_received.push_locked(std::make_pair(interface, message));
225  __dispatcher_message_received();
226  return __message_enqueueing;
227 }
228 
229 void
231  unsigned int instance_serial) throw()
232 {
233  __queue_writer_added.push_locked(interface);
234  __dispatcher_writer_added();
235 }
236 
237 void
239  unsigned int instance_serial) throw()
240 {
241  __queue_writer_removed.push_locked(interface);
242  __dispatcher_writer_removed();
243 }
244 
245 void
247  unsigned int instance_serial) throw()
248 {
249  __queue_reader_added.push_locked(interface);
250  __dispatcher_reader_added();
251 }
252 
253 void
255  unsigned int instance_serial) throw()
256 {
257  __queue_reader_removed.push_locked(interface);
258  __dispatcher_reader_removed();
259 }
260 
261 /** Get "data changed" signal.
262  * The signal is emitted if the data of the interface has changed.
263  * @return "data changed" signal.
264  */
265 sigc::signal<void, Interface *>
267 {
268  return __signal_data_changed;
269 }
270 
271 
272 /** Get "message received" signal.
273  * The signal is emitted if a message has been received via the watched
274  * interface. Note that this signal is only emitted on writing instances of
275  * an interface.
276  * @return "message received" signal.
277  */
278 sigc::signal<void, Interface *, Message *>
280 {
281  return __signal_message_received;
282 }
283 
284 
285 /** Get "writer added" signal.
286  * The signal is emitted if a writer has been added to the interface.
287  * @return "writer added" signal.
288  */
289 sigc::signal<void, Interface *>
291 {
292  return __signal_writer_added;
293 }
294 
295 
296 /** Get "writer removed" signal.
297  * The signal is emitted if a writer has been removed from the interface.
298  * @return "writer removed" signal.
299  */
300 sigc::signal<void, Interface *>
302 {
303  return __signal_writer_removed;
304 }
305 
306 
307 /** Get "reader added" signal.
308  * The signal is emitted if a reader has been added to the interface.
309  * @return "reader added" signal.
310  */
311 sigc::signal<void, Interface *>
313 {
314  return __signal_reader_added;
315 }
316 
317 
318 /** Get "reader removed" signal.
319  * The signal is emitted if a reader has been removed from the interface.
320  * @return "reader added" signal.
321  */
322 sigc::signal<void, Interface *>
324 {
325  return __signal_reader_removed;
326 }
327 
328 
329 } // end of namespace fawkes
Base class for all messages passed through interfaces in Fawkes BlackBoard.
Definition: message.h:44
virtual void on_data_changed()
Internal event handler.
virtual void on_message_received()
Internal event handler.
virtual void bb_interface_writer_added(Interface *interface, unsigned int instance_serial)
A writing instance has been opened for a watched interface.
virtual void bb_interface_reader_removed(Interface *interface, unsigned int instance_serial)
A reading instance has been closed for a watched interface.
Fawkes library namespace.
void bbil_add_writer_interface(Interface *interface)
Add an interface to the writer addition/removal watch list.
virtual bool bb_interface_message_received(Interface *interface, Message *message)
BlackBoard message received notification.
sigc::signal< void, Interface * > signal_writer_removed()
Get "writer removed" signal.
virtual void bb_interface_reader_added(Interface *interface, unsigned int instance_serial)
A reading instance has been opened for a watched interface.
virtual void on_writer_removed()
Internal event handler.
Base class for all Fawkes BlackBoard interfaces.
Definition: interface.h:79
virtual void on_reader_removed()
Internal event handler.
virtual void bb_interface_writer_removed(Interface *interface, unsigned int instance_serial)
A writing instance has been closed for a watched interface.
virtual void bb_interface_data_changed(Interface *interface)
BlackBoard data changed notification.
bool is_writer() const
Check if this is a writing instance.
Definition: interface.cpp:440
sigc::signal< void, Interface * > signal_reader_removed()
Get "reader removed" signal.
void bbil_add_reader_interface(Interface *interface)
Add an interface to the reader addition/removal watch list.
sigc::signal< void, Interface * > signal_writer_added()
Get "writer added" signal.
virtual void on_writer_added()
Internal event handler.
InterfaceDispatcher(const char *listener_name, fawkes::Interface *iface, bool message_enqueueing=true)
Constructor.
virtual void on_reader_added()
Internal event handler.
void bbil_add_message_interface(Interface *interface)
Add an interface to the message received watch list.
sigc::signal< void, Interface * > signal_reader_added()
Get "reader added" signal.
BlackBoard interface listener.
sigc::signal< void, Interface *, Message * > signal_message_received()
Get "message received" signal.
void set_message_enqueueing(bool enqueue)
Set if received messages should be enqueued or not.
sigc::signal< void, Interface * > signal_data_changed()
Get "data changed" signal.
void bbil_add_data_interface(Interface *interface)
Add an interface to the data modification watch list.