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