Fawkes API
Fawkes Development Version
|
00001 00002 /*************************************************************************** 00003 * blackboard.h - BlackBoard Interface 00004 * 00005 * Created: Sat Sep 16 17:09:15 2006 (on train to Cologne) 00006 * Copyright 2006-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 #ifndef __BLACKBOARD_BLACKBOARD_H_ 00025 #define __BLACKBOARD_BLACKBOARD_H_ 00026 00027 #include <core/exceptions/software.h> 00028 #include <interface/interface.h> 00029 00030 #include <list> 00031 #include <string> 00032 #include <typeinfo> 00033 00034 namespace fawkes { 00035 #if 0 /* just to make Emacs auto-indent happy */ 00036 } 00037 #endif 00038 00039 class BlackBoardInterfaceManager; 00040 class BlackBoardMemoryManager; 00041 class BlackBoardMessageManager; 00042 class BlackBoardNetworkHandler; 00043 class BlackBoardNotifier; 00044 class InterfaceInfoList; 00045 class BlackBoardInterfaceListener; 00046 class BlackBoardInterfaceObserver; 00047 class FawkesNetworkHub; 00048 00049 class BlackBoard 00050 { 00051 public: 00052 BlackBoard(); 00053 virtual ~BlackBoard(); 00054 00055 virtual Interface * open_for_reading(const char *interface_type, 00056 const char *identifier) = 0; 00057 virtual Interface * open_for_writing(const char *interface_type, 00058 const char *identifier) = 0; 00059 virtual void close(Interface *interface) = 0; 00060 00061 virtual InterfaceInfoList * list_all() = 0; 00062 virtual InterfaceInfoList * list(const char *type_pattern, 00063 const char *id_pattern) = 0; 00064 virtual bool is_alive() const throw() = 0; 00065 virtual bool try_aliveness_restore() throw() = 0; 00066 00067 virtual std::list<Interface *> 00068 open_multiple_for_reading(const char *type_pattern, 00069 const char *id_pattern = "*") = 0; 00070 00071 template <class InterfaceType> 00072 std::list<InterfaceType *> 00073 open_multiple_for_reading(const char *id_pattern = "*"); 00074 00075 template <class InterfaceType> 00076 InterfaceType * open_for_reading(const char *identifier); 00077 00078 template <class InterfaceType> 00079 InterfaceType * open_for_writing(const char *identifier); 00080 00081 /** Flags to constrain listener registraion/updates. */ 00082 typedef enum { 00083 BBIL_FLAG_DATA = 1, ///< consider data events 00084 BBIL_FLAG_MESSAGES = 2, ///< consider message received events 00085 BBIL_FLAG_READER = 4, ///< consider reader events 00086 BBIL_FLAG_WRITER = 8, ///< consider writer events 00087 BBIL_FLAG_ALL = 15, ///< consider all events 00088 } ListenerRegisterFlag; 00089 00090 virtual void register_listener(BlackBoardInterfaceListener *listener, 00091 ListenerRegisterFlag flag = BBIL_FLAG_ALL); 00092 virtual void update_listener(BlackBoardInterfaceListener *listener, 00093 ListenerRegisterFlag flag = BBIL_FLAG_ALL); 00094 virtual void unregister_listener(BlackBoardInterfaceListener *listener); 00095 00096 virtual void register_observer(BlackBoardInterfaceObserver *observer); 00097 virtual void unregister_observer(BlackBoardInterfaceObserver *observer); 00098 00099 std::string demangle_fawkes_interface_name(const char *type); 00100 00101 protected: 00102 BlackBoardNotifier *__notifier; ///< Notifier for BB events. 00103 }; 00104 00105 00106 /** Get interface of given type. 00107 * This will open a new interface for reading just like the 00108 * non-template version of open_for_reading(). But with the template 00109 * method you will get a correctly typed object that you can use. An 00110 * TypeMismatchException is thrown if the string representation of the 00111 * type and the actual class type of the interface do not match. 00112 * @param identifier identifier of the interface 00113 * @return new fully initialized interface instance of requested type 00114 * @exception OutOfMemoryException thrown if there is not enough free space for 00115 * the requested interface. 00116 * @exception TypeMismatchException thrown if type in interface_type 00117 * and the actual class type do not fit. 00118 */ 00119 template <class InterfaceType> 00120 InterfaceType * 00121 BlackBoard::open_for_reading(const char *identifier) 00122 { 00123 std::string type_name = 00124 demangle_fawkes_interface_name(typeid(InterfaceType).name()); 00125 Interface *interface = open_for_reading(type_name.c_str(), identifier); 00126 return static_cast<InterfaceType *>(interface); 00127 } 00128 00129 00130 /** Open all interfaces of given type for reading. 00131 * This will create interface instances for all currently registered interfaces of 00132 * the given type. The result can be casted to the appropriate type. 00133 * @param id_pattern pattern of interface IDs to open, supports wildcards similar 00134 * to filenames (*, ?, []), see "man fnmatch" for all supported. 00135 * @return list of new fully initialized interface instances of requested type. The 00136 * is allocated using new and you have to free it using delete after you are done 00137 * with it! 00138 */ 00139 template <class InterfaceType> 00140 std::list<InterfaceType *> 00141 BlackBoard::open_multiple_for_reading(const char *id_pattern) 00142 { 00143 std::string type_name = 00144 demangle_fawkes_interface_name(typeid(InterfaceType).name()); 00145 std::list<Interface *> il = 00146 open_multiple_for_reading(type_name.c_str(), id_pattern); 00147 std::list<InterfaceType *> rv; 00148 for (std::list<Interface *>::iterator i = il.begin(); i != il.end(); ++i) { 00149 rv.push_back(static_cast<InterfaceType *>(*i)); 00150 } 00151 00152 return rv; 00153 } 00154 00155 00156 /** Get writer interface of given type. 00157 * This will open a new interface for writing just like the 00158 * non-template version of open_for_writing(). But with the template 00159 * method you will get a correctly typed object that you can use. An 00160 * TypeMismatchException is thrown if the string representation of the 00161 * type and the actual class type of the interface do not match. 00162 * @param identifier identifier of the interface 00163 * @return new fully initialized interface instance of requested type 00164 * @exception OutOfMemoryException thrown if there is not enough free space for 00165 * the requested interface. 00166 * @exception BlackBoardWriterActiveException thrown if there is already a writing 00167 * instance with the same type/id 00168 * @exception TypeMismatchException thrown if type in interface_type 00169 * and the actual class type do not fit. 00170 */ 00171 template <class InterfaceType> 00172 InterfaceType * 00173 BlackBoard::open_for_writing(const char *identifier) 00174 { 00175 std::string type_name = 00176 demangle_fawkes_interface_name(typeid(InterfaceType).name()); 00177 Interface *interface = open_for_writing(type_name.c_str(), identifier); 00178 return static_cast<InterfaceType *>(interface);; 00179 } 00180 00181 00182 /** Concatenation of register flags. 00183 * @param a flags to concatenate 00184 * @param b other flags to concatenate 00185 * @return concatenated flags 00186 */ 00187 inline BlackBoard::ListenerRegisterFlag 00188 operator|(const BlackBoard::ListenerRegisterFlag &a, 00189 const BlackBoard::ListenerRegisterFlag &b) 00190 { 00191 return (BlackBoard::ListenerRegisterFlag)((int)a | (int)b); 00192 } 00193 00194 00195 /** Testing of register flags. 00196 * @param a flags to test 00197 * @param b flags to test for 00198 * @return resulting flags 00199 */ 00200 inline BlackBoard::ListenerRegisterFlag 00201 operator&(const BlackBoard::ListenerRegisterFlag &a, 00202 const BlackBoard::ListenerRegisterFlag &b) 00203 { 00204 return (BlackBoard::ListenerRegisterFlag)((int)a & (int)b); 00205 } 00206 00207 00208 } // end namespace fawkes 00209 00210 #endif