Fawkes API Fawkes Development Version
|
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