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 
53  bbil_add_data_interface(iface);
54  if (iface->is_writer()) {
55  bbil_add_message_interface(iface);
56  }
57  bbil_add_writer_interface(iface);
58  bbil_add_reader_interface(iface);
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 void
92 InterfaceDispatcher::setup_signals()
93 {
94  dispatcher_data_changed_.connect(sigc::mem_fun(*this, &InterfaceDispatcher::on_data_changed));
95  dispatcher_message_received_.connect(
96  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 /** Internal event handler.
116  * Called by dispatcher to emit signal.
117  */
118 void
120 {
121  queue_data_changed_.lock();
122  while (!queue_data_changed_.empty()) {
123  Interface *iface = queue_data_changed_.front();
124  signal_data_changed_.emit(iface);
125  queue_data_changed_.pop();
126  }
127  queue_data_changed_.unlock();
128 }
129 
130 /** Internal event handler.
131  * Called by dispatcher to emit signal.
132  */
133 void
135 {
136  queue_message_received_.lock();
137  while (!queue_message_received_.empty()) {
138  std::pair<Interface *, Message *> p = queue_message_received_.front();
139  signal_message_received_.emit(p.first, p.second);
140  p.second->unref();
141  queue_message_received_.pop();
142  }
143  queue_message_received_.unlock();
144 }
145 
146 /** Internal event handler.
147  * Called by dispatcher to emit signal.
148  */
149 void
151 {
152  queue_writer_added_.lock();
153  while (!queue_writer_added_.empty()) {
154  Interface *iface = queue_writer_added_.front();
155  signal_writer_added_.emit(iface);
156  queue_writer_added_.pop();
157  }
158  queue_writer_added_.unlock();
159 }
160 
161 /** Internal event handler.
162  * Called by dispatcher to emit signal.
163  */
164 void
166 {
167  queue_writer_removed_.lock();
168  while (!queue_writer_removed_.empty()) {
169  Interface *iface = queue_writer_removed_.front();
170  signal_writer_removed_.emit(iface);
171  queue_writer_removed_.pop();
172  }
173  queue_writer_removed_.unlock();
174 }
175 
176 /** Internal event handler.
177  * Called by dispatcher to emit signal.
178  */
179 void
181 {
182  queue_reader_added_.lock();
183  while (!queue_reader_added_.empty()) {
184  Interface *iface = queue_reader_added_.front();
185  signal_reader_added_.emit(iface);
186  queue_reader_added_.pop();
187  }
188  queue_reader_added_.unlock();
189 }
190 
191 /** Internal event handler.
192  * Called by dispatcher to emit signal.
193  */
194 void
196 {
197  queue_reader_removed_.lock();
198  while (!queue_reader_removed_.empty()) {
199  Interface *iface = queue_reader_removed_.front();
200  signal_reader_removed_.emit(iface);
201  queue_reader_removed_.pop();
202  }
203  queue_reader_removed_.unlock();
204 }
205 
206 void
207 InterfaceDispatcher::bb_interface_data_changed(Interface *interface) throw()
208 {
209  queue_data_changed_.push_locked(interface);
210  dispatcher_data_changed_();
211 }
212 
213 bool
215 {
216  message->ref();
217  queue_message_received_.push_locked(std::make_pair(interface, message));
218  dispatcher_message_received_();
219  return message_enqueueing_;
220 }
221 
222 void
224  unsigned int instance_serial) throw()
225 {
226  queue_writer_added_.push_locked(interface);
227  dispatcher_writer_added_();
228 }
229 
230 void
232  unsigned int instance_serial) throw()
233 {
234  queue_writer_removed_.push_locked(interface);
235  dispatcher_writer_removed_();
236 }
237 
238 void
240  unsigned int instance_serial) throw()
241 {
242  queue_reader_added_.push_locked(interface);
243  dispatcher_reader_added_();
244 }
245 
246 void
248  unsigned int instance_serial) throw()
249 {
250  queue_reader_removed_.push_locked(interface);
251  dispatcher_reader_removed_();
252 }
253 
254 /** Get "data changed" signal.
255  * The signal is emitted if the data of the interface has changed.
256  * @return "data changed" signal.
257  */
258 sigc::signal<void, Interface *>
260 {
261  return signal_data_changed_;
262 }
263 
264 /** Get "message received" signal.
265  * The signal is emitted if a message has been received via the watched
266  * interface. Note that this signal is only emitted on writing instances of
267  * an interface.
268  * @return "message received" signal.
269  */
270 sigc::signal<void, Interface *, Message *>
272 {
273  return signal_message_received_;
274 }
275 
276 /** Get "writer added" signal.
277  * The signal is emitted if a writer has been added to the interface.
278  * @return "writer added" signal.
279  */
280 sigc::signal<void, Interface *>
282 {
283  return signal_writer_added_;
284 }
285 
286 /** Get "writer removed" signal.
287  * The signal is emitted if a writer has been removed from the interface.
288  * @return "writer removed" signal.
289  */
290 sigc::signal<void, Interface *>
292 {
293  return signal_writer_removed_;
294 }
295 
296 /** Get "reader added" signal.
297  * The signal is emitted if a reader has been added to the interface.
298  * @return "reader added" signal.
299  */
300 sigc::signal<void, Interface *>
302 {
303  return signal_reader_added_;
304 }
305 
306 /** Get "reader removed" signal.
307  * The signal is emitted if a reader has been removed from the interface.
308  * @return "reader added" signal.
309  */
310 sigc::signal<void, Interface *>
312 {
313  return signal_reader_removed_;
314 }
315 
316 } // end of namespace fawkes
fawkes::InterfaceDispatcher::bb_interface_writer_added
virtual void bb_interface_writer_added(Interface *interface, unsigned int instance_serial)
A writing instance has been opened for a watched interface.
Definition: interface_dispatcher.cpp:229
fawkes::InterfaceDispatcher::bb_interface_reader_removed
virtual void bb_interface_reader_removed(Interface *interface, unsigned int instance_serial)
A reading instance has been closed for a watched interface.
Definition: interface_dispatcher.cpp:253
fawkes::InterfaceDispatcher::on_writer_removed
virtual void on_writer_removed()
Internal event handler.
Definition: interface_dispatcher.cpp:171
fawkes::InterfaceDispatcher::signal_writer_added
sigc::signal< void, Interface * > signal_writer_added()
Get "writer added" signal.
Definition: interface_dispatcher.cpp:287
fawkes::InterfaceDispatcher::on_reader_added
virtual void on_reader_added()
Internal event handler.
Definition: interface_dispatcher.cpp:186
fawkes::InterfaceDispatcher::bb_interface_message_received
virtual bool bb_interface_message_received(Interface *interface, Message *message)
BlackBoard message received notification.
Definition: interface_dispatcher.cpp:220
fawkes::InterfaceDispatcher::signal_writer_removed
sigc::signal< void, Interface * > signal_writer_removed()
Get "writer removed" signal.
Definition: interface_dispatcher.cpp:297
fawkes::InterfaceDispatcher::set_message_enqueueing
void set_message_enqueueing(bool enqueue)
Set if received messages should be enqueued or not.
Definition: interface_dispatcher.cpp:116
fawkes::Message
Definition: message.h:41
fawkes::InterfaceDispatcher::on_reader_removed
virtual void on_reader_removed()
Internal event handler.
Definition: interface_dispatcher.cpp:201
fawkes::InterfaceDispatcher::on_message_received
virtual void on_message_received()
Internal event handler.
Definition: interface_dispatcher.cpp:140
fawkes::InterfaceDispatcher::on_data_changed
virtual void on_data_changed()
Internal event handler.
Definition: interface_dispatcher.cpp:125
fawkes::InterfaceDispatcher::bb_interface_data_changed
virtual void bb_interface_data_changed(Interface *interface)
BlackBoard data changed notification.
Definition: interface_dispatcher.cpp:213
fawkes::InterfaceDispatcher::signal_reader_removed
sigc::signal< void, Interface * > signal_reader_removed()
Get "reader removed" signal.
Definition: interface_dispatcher.cpp:317
fawkes::InterfaceDispatcher::bb_interface_reader_added
virtual void bb_interface_reader_added(Interface *interface, unsigned int instance_serial)
A reading instance has been opened for a watched interface.
Definition: interface_dispatcher.cpp:245
fawkes
fawkes::InterfaceDispatcher::bb_interface_writer_removed
virtual void bb_interface_writer_removed(Interface *interface, unsigned int instance_serial)
A writing instance has been closed for a watched interface.
Definition: interface_dispatcher.cpp:237
fawkes::BlackBoardInterfaceListener::bbil_add_message_interface
void bbil_add_message_interface(Interface *interface)
Add an interface to the message received watch list.
Definition: interface_listener.cpp:247
fawkes::Interface
Definition: interface.h:78
fawkes::InterfaceDispatcher::on_writer_added
virtual void on_writer_added()
Internal event handler.
Definition: interface_dispatcher.cpp:156
fawkes::InterfaceDispatcher::InterfaceDispatcher
InterfaceDispatcher(const char *listener_name, fawkes::Interface *iface, bool message_enqueueing=true)
Constructor.
Definition: interface_dispatcher.cpp:52
fawkes::InterfaceDispatcher::signal_reader_added
sigc::signal< void, Interface * > signal_reader_added()
Get "reader added" signal.
Definition: interface_dispatcher.cpp:307
fawkes::InterfaceDispatcher::signal_message_received
sigc::signal< void, Interface *, Message * > signal_message_received()
Get "message received" signal.
Definition: interface_dispatcher.cpp:277
fawkes::InterfaceDispatcher::signal_data_changed
sigc::signal< void, Interface * > signal_data_changed()
Get "data changed" signal.
Definition: interface_dispatcher.cpp:265
fawkes::BlackBoardInterfaceListener::bbil_add_reader_interface
void bbil_add_reader_interface(Interface *interface)
Add an interface to the reader addition/removal watch list.
Definition: interface_listener.cpp:264
fawkes::BlackBoardInterfaceListener::bbil_add_data_interface
void bbil_add_data_interface(Interface *interface)
Add an interface to the data modification watch list.
Definition: interface_listener.cpp:238
fawkes::BlackBoardInterfaceListener::bbil_add_writer_interface
void bbil_add_writer_interface(Interface *interface)
Add an interface to the writer addition/removal watch list.
Definition: interface_listener.cpp:276