Fawkes API  Fawkes Development Version
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
blackboard.h
1 
2 /***************************************************************************
3  * blackboard.h - BlackBoard Interface
4  *
5  * Created: Sat Sep 16 17:09:15 2006 (on train to Cologne)
6  * Copyright 2006-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 #ifndef __BLACKBOARD_BLACKBOARD_H_
25 #define __BLACKBOARD_BLACKBOARD_H_
26 
27 #include <core/exceptions/software.h>
28 #include <interface/interface.h>
29 
30 #include <list>
31 #include <string>
32 #include <typeinfo>
33 
34 namespace fawkes {
35 #if 0 /* just to make Emacs auto-indent happy */
36 }
37 #endif
38 
39 class BlackBoardInterfaceManager;
40 class BlackBoardMemoryManager;
41 class BlackBoardMessageManager;
42 class BlackBoardNetworkHandler;
43 class BlackBoardNotifier;
44 class InterfaceInfoList;
45 class BlackBoardInterfaceListener;
46 class BlackBoardInterfaceObserver;
47 class FawkesNetworkHub;
48 
50 {
51  public:
52  BlackBoard();
53  virtual ~BlackBoard();
54 
55  virtual Interface * open_for_reading(const char *interface_type,
56  const char *identifier) = 0;
57  virtual Interface * open_for_writing(const char *interface_type,
58  const char *identifier) = 0;
59  virtual void close(Interface *interface) = 0;
60 
61  virtual InterfaceInfoList * list_all() = 0;
62  virtual InterfaceInfoList * list(const char *type_pattern,
63  const char *id_pattern) = 0;
64  virtual bool is_alive() const throw() = 0;
65  virtual bool try_aliveness_restore() throw() = 0;
66 
67  virtual std::list<Interface *>
68  open_multiple_for_reading(const char *type_pattern,
69  const char *id_pattern = "*") = 0;
70 
71  template <class InterfaceType>
72  std::list<InterfaceType *>
73  open_multiple_for_reading(const char *id_pattern = "*");
74 
75  template <class InterfaceType>
76  InterfaceType * open_for_reading(const char *identifier);
77 
78  template <class InterfaceType>
79  InterfaceType * open_for_writing(const char *identifier);
80 
81  /** Flags to constrain listener registraion/updates. */
82  typedef enum {
83  BBIL_FLAG_DATA = 1, ///< consider data events
84  BBIL_FLAG_MESSAGES = 2, ///< consider message received events
85  BBIL_FLAG_READER = 4, ///< consider reader events
86  BBIL_FLAG_WRITER = 8, ///< consider writer events
87  BBIL_FLAG_ALL = 15, ///< consider all events
88  } ListenerRegisterFlag;
89 
90  virtual void register_listener(BlackBoardInterfaceListener *listener,
91  ListenerRegisterFlag flag = BBIL_FLAG_ALL);
92  virtual void update_listener(BlackBoardInterfaceListener *listener,
93  ListenerRegisterFlag flag = BBIL_FLAG_ALL);
94  virtual void unregister_listener(BlackBoardInterfaceListener *listener);
95 
96  virtual void register_observer(BlackBoardInterfaceObserver *observer);
97  virtual void unregister_observer(BlackBoardInterfaceObserver *observer);
98 
99  std::string demangle_fawkes_interface_name(const char *type);
100 
101  protected:
102  BlackBoardNotifier *__notifier; ///< Notifier for BB events.
103 };
104 
105 
106 /** Get interface of given type.
107  * This will open a new interface for reading just like the
108  * non-template version of open_for_reading(). But with the template
109  * method you will get a correctly typed object that you can use. An
110  * TypeMismatchException is thrown if the string representation of the
111  * type and the actual class type of the interface do not match.
112  * @param identifier identifier of the interface
113  * @return new fully initialized interface instance of requested type
114  * @exception OutOfMemoryException thrown if there is not enough free space for
115  * the requested interface.
116  * @exception TypeMismatchException thrown if type in interface_type
117  * and the actual class type do not fit.
118  */
119 template <class InterfaceType>
120 InterfaceType *
121 BlackBoard::open_for_reading(const char *identifier)
122 {
123  std::string type_name =
124  demangle_fawkes_interface_name(typeid(InterfaceType).name());
125  Interface *interface = open_for_reading(type_name.c_str(), identifier);
126  return static_cast<InterfaceType *>(interface);
127 }
128 
129 
130 /** Open all interfaces of given type for reading.
131  * This will create interface instances for all currently registered interfaces of
132  * the given type. The result can be casted to the appropriate type.
133  * @param id_pattern pattern of interface IDs to open, supports wildcards similar
134  * to filenames (*, ?, []), see "man fnmatch" for all supported.
135  * @return list of new fully initialized interface instances of requested type. The
136  * is allocated using new and you have to free it using delete after you are done
137  * with it!
138  */
139 template <class InterfaceType>
140 std::list<InterfaceType *>
141 BlackBoard::open_multiple_for_reading(const char *id_pattern)
142 {
143  std::string type_name =
144  demangle_fawkes_interface_name(typeid(InterfaceType).name());
145  std::list<Interface *> il =
146  open_multiple_for_reading(type_name.c_str(), id_pattern);
147  std::list<InterfaceType *> rv;
148  for (std::list<Interface *>::iterator i = il.begin(); i != il.end(); ++i) {
149  rv.push_back(static_cast<InterfaceType *>(*i));
150  }
151 
152  return rv;
153 }
154 
155 
156 /** Get writer interface of given type.
157  * This will open a new interface for writing just like the
158  * non-template version of open_for_writing(). But with the template
159  * method you will get a correctly typed object that you can use. An
160  * TypeMismatchException is thrown if the string representation of the
161  * type and the actual class type of the interface do not match.
162  * @param identifier identifier of the interface
163  * @return new fully initialized interface instance of requested type
164  * @exception OutOfMemoryException thrown if there is not enough free space for
165  * the requested interface.
166  * @exception BlackBoardWriterActiveException thrown if there is already a writing
167  * instance with the same type/id
168  * @exception TypeMismatchException thrown if type in interface_type
169  * and the actual class type do not fit.
170  */
171 template <class InterfaceType>
172 InterfaceType *
173 BlackBoard::open_for_writing(const char *identifier)
174 {
175  std::string type_name =
176  demangle_fawkes_interface_name(typeid(InterfaceType).name());
177  Interface *interface = open_for_writing(type_name.c_str(), identifier);
178  return static_cast<InterfaceType *>(interface);;
179 }
180 
181 
182 /** Concatenation of register flags.
183  * @param a flags to concatenate
184  * @param b other flags to concatenate
185  * @return concatenated flags
186  */
190 {
191  return (BlackBoard::ListenerRegisterFlag)((int)a | (int)b);
192 }
193 
194 
195 /** Testing of register flags.
196  * @param a flags to test
197  * @param b flags to test for
198  * @return resulting flags
199  */
200 inline BlackBoard::ListenerRegisterFlag
203 {
204  return (BlackBoard::ListenerRegisterFlag)((int)a & (int)b);
205 }
206 
207 
208 } // end namespace fawkes
209 
210 #endif