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
27namespace 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 */
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 */
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
91void
92InterfaceDispatcher::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 */
109void
111{
112 message_enqueueing_ = enqueue;
113}
114
115/** Internal event handler.
116 * Called by dispatcher to emit signal.
117 */
118void
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 */
133void
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 */
149void
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 */
164void
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 */
179void
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 */
194void
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
206void
208{
209 queue_data_changed_.push_locked(interface);
210 dispatcher_data_changed_();
211}
212
213bool
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
222void
224{
225 queue_writer_added_.push_locked(interface);
226 dispatcher_writer_added_();
227}
228
229void
231 Uuid instance_serial) noexcept
232{
233 queue_writer_removed_.push_locked(interface);
234 dispatcher_writer_removed_();
235}
236
237void
239{
240 queue_reader_added_.push_locked(interface);
241 dispatcher_reader_added_();
242}
243
244void
246 Uuid instance_serial) noexcept
247{
248 queue_reader_removed_.push_locked(interface);
249 dispatcher_reader_removed_();
250}
251
252/** Get "data changed" signal.
253 * The signal is emitted if the data of the interface has changed.
254 * @return "data changed" signal.
255 */
256sigc::signal<void, Interface *>
258{
259 return signal_data_changed_;
260}
261
262/** Get "message received" signal.
263 * The signal is emitted if a message has been received via the watched
264 * interface. Note that this signal is only emitted on writing instances of
265 * an interface.
266 * @return "message received" signal.
267 */
268sigc::signal<void, Interface *, Message *>
270{
271 return signal_message_received_;
272}
273
274/** Get "writer added" signal.
275 * The signal is emitted if a writer has been added to the interface.
276 * @return "writer added" signal.
277 */
278sigc::signal<void, Interface *>
280{
281 return signal_writer_added_;
282}
283
284/** Get "writer removed" signal.
285 * The signal is emitted if a writer has been removed from the interface.
286 * @return "writer removed" signal.
287 */
288sigc::signal<void, Interface *>
290{
291 return signal_writer_removed_;
292}
293
294/** Get "reader added" signal.
295 * The signal is emitted if a reader has been added to the interface.
296 * @return "reader added" signal.
297 */
298sigc::signal<void, Interface *>
300{
301 return signal_reader_added_;
302}
303
304/** Get "reader removed" signal.
305 * The signal is emitted if a reader has been removed from the interface.
306 * @return "reader added" signal.
307 */
308sigc::signal<void, Interface *>
310{
311 return signal_reader_removed_;
312}
313
314} // end of namespace fawkes
BlackBoard interface listener.
void bbil_add_reader_interface(Interface *interface)
Add an interface to the reader addition/removal watch list.
void bbil_add_message_interface(Interface *interface)
Add an interface to the message received watch list.
void bbil_add_writer_interface(Interface *interface)
Add an interface to the writer addition/removal watch list.
void bbil_add_data_interface(Interface *interface)
Add an interface to the data modification watch list.
sigc::signal< void, Interface *, Message * > signal_message_received()
Get "message received" signal.
sigc::signal< void, Interface * > signal_reader_added()
Get "reader added" signal.
sigc::signal< void, Interface * > signal_reader_removed()
Get "reader removed" signal.
virtual void bb_interface_reader_added(Interface *interface, Uuid instance_serial) noexcept
A reading instance has been opened for a watched interface.
virtual void on_writer_added()
Internal event handler.
void set_message_enqueueing(bool enqueue)
Set if received messages should be enqueued or not.
sigc::signal< void, Interface * > signal_writer_added()
Get "writer added" signal.
virtual void on_data_changed()
Internal event handler.
virtual bool bb_interface_message_received(Interface *interface, Message *message) noexcept
BlackBoard message received notification.
virtual void on_reader_added()
Internal event handler.
virtual void bb_interface_reader_removed(Interface *interface, Uuid instance_serial) noexcept
A reading instance has been closed for a watched interface.
virtual void bb_interface_data_refreshed(Interface *interface) noexcept
BlackBoard data refreshed notification.
virtual void bb_interface_writer_added(Interface *interface, Uuid instance_serial) noexcept
A writing instance has been opened for a watched interface.
virtual void bb_interface_writer_removed(Interface *interface, Uuid instance_serial) noexcept
A writing instance has been closed for a watched interface.
sigc::signal< void, Interface * > signal_writer_removed()
Get "writer removed" signal.
virtual void on_message_received()
Internal event handler.
sigc::signal< void, Interface * > signal_data_changed()
Get "data changed" signal.
virtual void on_writer_removed()
Internal event handler.
virtual void on_reader_removed()
Internal event handler.
InterfaceDispatcher(const char *listener_name, fawkes::Interface *iface, bool message_enqueueing=true)
Constructor.
Base class for all Fawkes BlackBoard interfaces.
Definition: interface.h:80
bool is_writer() const
Check if this is a writing instance.
Definition: interface.cpp:445
Base class for all messages passed through interfaces in Fawkes BlackBoard.
Definition: message.h:44
A convenience class for universally unique identifiers (UUIDs).
Definition: uuid.h:29
Fawkes library namespace.