interface_dispatcher.cpp

00001 
00002 /***************************************************************************
00003  *  interface_dispatcher.cpp - BlackBoard listener and dispatcher
00004  *
00005  *  Created: Thu Oct 09 23:07:16 2008
00006  *  Copyright  2008  Tim Niemueller [www.niemueller.de]
00007  *
00008  ****************************************************************************/
00009 
00010 /*  This program is free software; you can redistribute it and/or modify
00011  *  it under the terms of the GNU General Public License as published by
00012  *  the Free Software Foundation; either version 2 of the License, or
00013  *  (at your option) any later version. A runtime exception applies to
00014  *  this software (see LICENSE.GPL_WRE file mentioned below for details).
00015  *
00016  *  This program is distributed in the hope that it will be useful,
00017  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  *  GNU Library General Public License for more details.
00020  *
00021  *  Read the full text in the LICENSE.GPL_WRE file in the doc directory.
00022  */
00023 
00024 #include <gui_utils/interface_dispatcher.h>
00025 #include <interface/interface.h>
00026 
00027 namespace fawkes {
00028 
00029 /** @class InterfaceDispatcher <gui_utils/interface_dispatcher.h>
00030  * Interface listener with dispatcher.
00031  * An instance is used to react to a data changed event by triggering a
00032  * signal dispatcher (which is thread-safe and can be used across thread borders
00033  * in Glib/Gtk apps.
00034  * You have to register this listener with BlackBoard::BBIL_FLAGS_DATA flag by
00035  * yourself. Do not forget to unregister.
00036  * @author Tim Niemueller
00037  */
00038 
00039 /** Constructor.
00040  * @param listener_name name of the listener
00041  * @param iface interface to watch for data changes. Register this dispatcher as
00042  * listener by yourself!
00043  * @param message_enqueueing true to enqueue messages after the message received
00044  * event handler has been called, false to drop the message afterwards.
00045  */
00046 InterfaceDispatcher::InterfaceDispatcher(const char *listener_name,
00047                                          Interface *iface,
00048                                          bool message_enqueueing)
00049   : BlackBoardInterfaceListener(listener_name)
00050 {
00051   __message_enqueueing = message_enqueueing;
00052 
00053   bbil_add_data_interface(iface);
00054   if ( iface->is_writer() ) {
00055     bbil_add_message_interface(iface);
00056   }
00057   bbil_add_writer_interface(iface);
00058   bbil_add_reader_interface(iface);
00059 
00060   __dispatcher_data_changed.connect(sigc::mem_fun(*this, &InterfaceDispatcher::on_data_changed));
00061   __dispatcher_message_received.connect(sigc::mem_fun(*this, &InterfaceDispatcher::on_message_received));
00062   __dispatcher_writer_added.connect(sigc::mem_fun(*this, &InterfaceDispatcher::on_writer_added));
00063   __dispatcher_writer_removed.connect(sigc::mem_fun(*this, &InterfaceDispatcher::on_writer_removed));
00064   __dispatcher_reader_added.connect(sigc::mem_fun(*this, &InterfaceDispatcher::on_reader_added));
00065   __dispatcher_reader_removed.connect(sigc::mem_fun(*this, &InterfaceDispatcher::on_writer_removed));
00066 }
00067 
00068 
00069 /** Set if received messages should be enqueued or not.
00070  * The message received event handler can cause the message to be enqueued or not.
00071  * The default is to enqueue the messages.
00072  * @param enqueue true to cause messages to be enqueued, false to cause the
00073  * messages not to be enqueued after they have been processed
00074  */
00075 void
00076 InterfaceDispatcher::set_message_enqueueing(bool enqueue)
00077 {
00078   __message_enqueueing = enqueue;
00079 }
00080 
00081 
00082 /** Internal event handler.
00083  * Called by dispatcher to emit signal.
00084  */
00085 void
00086 InterfaceDispatcher::on_data_changed()
00087 {
00088   __queue_data_changed.lock();
00089   while (! __queue_data_changed.empty()) {
00090     Interface *iface = __queue_data_changed.front();
00091     __signal_data_changed.emit(iface);
00092     __queue_data_changed.pop();
00093   }
00094   __queue_data_changed.unlock();
00095 }
00096 
00097 
00098 /** Internal event handler.
00099  * Called by dispatcher to emit signal.
00100  */
00101 void
00102 InterfaceDispatcher::on_message_received()
00103 {
00104   __queue_message_received.lock();
00105   while (! __queue_message_received.empty()) {
00106     std::pair<Interface *, Message *> p = __queue_message_received.front();
00107     __signal_message_received.emit(p.first, p.second);
00108     p.second->unref();
00109     __queue_message_received.pop();
00110   }
00111   __queue_message_received.unlock();
00112 }
00113 
00114 
00115 /** Internal event handler.
00116  * Called by dispatcher to emit signal.
00117  */
00118 void
00119 InterfaceDispatcher::on_writer_added()
00120 {
00121   __queue_writer_added.lock();
00122   while (! __queue_writer_added.empty()) {
00123     Interface *iface = __queue_writer_added.front();
00124     __signal_writer_added.emit(iface);
00125     __queue_writer_added.pop();
00126   }
00127   __queue_writer_added.unlock();
00128 }
00129 
00130 
00131 /** Internal event handler.
00132  * Called by dispatcher to emit signal.
00133  */
00134 void
00135 InterfaceDispatcher::on_writer_removed()
00136 {
00137   __queue_writer_removed.lock();
00138   while (! __queue_writer_removed.empty()) {
00139     Interface *iface = __queue_writer_removed.front();
00140     __signal_writer_removed.emit(iface);
00141     __queue_writer_removed.pop();
00142   }
00143   __queue_writer_removed.unlock();
00144 }
00145 
00146 
00147 /** Internal event handler.
00148  * Called by dispatcher to emit signal.
00149  */
00150 void
00151 InterfaceDispatcher::on_reader_added()
00152 {
00153   __queue_reader_added.lock();
00154   while (! __queue_reader_added.empty()) {
00155     Interface *iface = __queue_reader_added.front();
00156     __signal_reader_added.emit(iface);
00157     __queue_reader_added.pop();
00158   }
00159   __queue_reader_added.unlock();
00160 }
00161 
00162 
00163 /** Internal event handler.
00164  * Called by dispatcher to emit signal.
00165  */
00166 void
00167 InterfaceDispatcher::on_reader_removed()
00168 {
00169   __queue_reader_removed.lock();
00170   while (! __queue_reader_removed.empty()) {
00171     Interface *iface = __queue_reader_removed.front();
00172     __signal_reader_removed.emit(iface);
00173     __queue_reader_removed.pop();
00174   }
00175   __queue_reader_removed.unlock();
00176 }
00177 
00178 
00179 void
00180 InterfaceDispatcher::bb_interface_data_changed(Interface *interface) throw()
00181 {
00182   __queue_data_changed.push_locked(interface);
00183   __dispatcher_data_changed();
00184 }
00185 
00186 bool
00187 InterfaceDispatcher::bb_interface_message_received(Interface *interface, Message *message) throw()
00188 {
00189   message->ref();
00190   __queue_message_received.push_locked(std::make_pair(interface, message));
00191   __dispatcher_message_received();
00192   return __message_enqueueing;
00193 }
00194 
00195 void
00196 InterfaceDispatcher::bb_interface_writer_added(Interface *interface,
00197                                                unsigned int instance_serial) throw()
00198 {
00199   __queue_writer_added.push_locked(interface);
00200   __dispatcher_writer_added();
00201 }
00202 
00203 void
00204 InterfaceDispatcher::bb_interface_writer_removed(Interface *interface,
00205                                                  unsigned int instance_serial) throw()
00206 {
00207   __queue_writer_removed.push_locked(interface);
00208   __dispatcher_writer_removed();
00209 }
00210 
00211 void
00212 InterfaceDispatcher::bb_interface_reader_added(Interface *interface,
00213                                                unsigned int instance_serial) throw()
00214 {
00215   __queue_reader_added.push_locked(interface);
00216   __dispatcher_reader_added();
00217 }
00218 
00219 void
00220 InterfaceDispatcher::bb_interface_reader_removed(Interface *interface,
00221                                                  unsigned int instance_serial) throw()
00222 {
00223   __queue_reader_removed.push_locked(interface);
00224   __dispatcher_reader_removed();
00225 }
00226 
00227 /** Get "data changed" signal.
00228  * The signal is emitted if the data of the interface has changed.
00229  * @return "data changed" signal.
00230  */
00231 sigc::signal<void, Interface *>
00232 InterfaceDispatcher::signal_data_changed()
00233 {
00234   return __signal_data_changed;
00235 }
00236 
00237 
00238 /** Get "message received" signal.
00239  * The signal is emitted if a message has been received via the watched
00240  * interface. Note that this signal is only emitted on writing instances of
00241  * an interface.
00242  * @return "message received" signal.
00243  */
00244 sigc::signal<void, Interface *, Message *>
00245 InterfaceDispatcher::signal_message_received()
00246 {
00247   return __signal_message_received;
00248 }
00249 
00250 
00251 /** Get "writer added" signal.
00252  * The signal is emitted if a writer has been added to the interface.
00253  * @return "writer added" signal.
00254  */
00255 sigc::signal<void, Interface *>
00256 InterfaceDispatcher::signal_writer_added()
00257 {
00258   return __signal_writer_added;
00259 }
00260 
00261 
00262 /** Get "writer removed" signal.
00263  * The signal is emitted if a writer has been removed from the interface.
00264  * @return "writer removed" signal.
00265  */
00266 sigc::signal<void, Interface *>
00267 InterfaceDispatcher::signal_writer_removed()
00268 {
00269   return __signal_writer_removed;
00270 }
00271 
00272 
00273 /** Get "reader added" signal.
00274  * The signal is emitted if a reader has been added to the interface.
00275  * @return "reader added" signal.
00276  */
00277 sigc::signal<void, Interface *>
00278 InterfaceDispatcher::signal_reader_added()
00279 {
00280   return __signal_reader_added;
00281 }
00282 
00283 
00284 /** Get "reader removed" signal.
00285  * The signal is emitted if a reader has been removed from the interface.
00286  * @return "reader added" signal.
00287  */
00288 sigc::signal<void, Interface *>
00289 InterfaceDispatcher::signal_reader_removed()
00290 {
00291   return __signal_reader_removed;
00292 }
00293 
00294 
00295 } // end of namespace fawkes

Generated on Tue Feb 22 13:31:26 2011 for Fawkes API by  doxygen 1.4.7