interface.h
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef __INTERFACE_H_
00025 #define __INTERFACE_H_
00026
00027 #include <interface/message.h>
00028 #include <interface/message_queue.h>
00029 #include <core/exception.h>
00030
00031 #include <cstddef>
00032 #include <list>
00033 #define __STD_LIMIT_MACROS
00034 #include <stdint.h>
00035
00036 #define __INTERFACE_TYPE_SIZE 32
00037 #define __INTERFACE_ID_SIZE 32
00038
00039 #define __INTERFACE_HASH_SIZE 16
00040
00041 #define __INTERFACE_UID_SIZE __INTERFACE_TYPE_SIZE + 2 + __INTERFACE_ID_SIZE
00042
00043 namespace fawkes {
00044 #if 0
00045 }
00046 #endif
00047
00048 class RefCountRWLock;
00049 class InterfaceMediator;
00050 class MessageMediator;
00051 class Time;
00052 class Clock;
00053
00054 class InterfaceWriteDeniedException : public Exception
00055 {
00056 public:
00057 InterfaceWriteDeniedException(const char *type, const char *id, const char *msg);
00058 };
00059
00060 class InterfaceMessageEnqueueException : public Exception
00061 {
00062 public:
00063 InterfaceMessageEnqueueException(const char *type, const char *id);
00064 };
00065
00066 class InterfaceInvalidMessageException : public Exception
00067 {
00068 public:
00069 InterfaceInvalidMessageException(const Interface *interface, const Message *message);
00070 };
00071
00072
00073 class InterfaceInvalidException : public Exception
00074 {
00075 public:
00076 InterfaceInvalidException(const Interface *interface, const char *method);
00077 };
00078
00079 class Interface
00080 {
00081 friend class BlackBoardInterfaceManager;
00082 friend class BlackBoardInstanceFactory;
00083 friend class BlackBoardMessageManager;
00084 friend class BlackBoardInterfaceProxy;
00085
00086 public:
00087 virtual ~Interface();
00088
00089 bool oftype(const char *interface_type) const;
00090 const void * datachunk() const;
00091 unsigned int datasize() const;
00092 const char * type() const;
00093 const char * id() const;
00094 const char * uid() const;
00095 unsigned short serial() const;
00096 unsigned int mem_serial() const;
00097 bool operator== (Interface &comp) const;
00098 const unsigned char * hash() const;
00099 size_t hash_size() const;
00100 const char * hash_printable() const;
00101 bool is_writer() const;
00102 void set_validity(bool valid);
00103 bool is_valid() const;
00104
00105 void set_from_chunk(void *chunk);
00106
00107 virtual Message * create_message(const char *type) const = 0;
00108 virtual void copy_values(const Interface *interface) = 0;
00109 virtual const char * enum_tostring(const char *enumtype, int val) const = 0;
00110
00111 void read();
00112 void write();
00113
00114 bool has_writer() const;
00115 unsigned int num_readers() const;
00116
00117 bool changed() const;
00118 const Time * timestamp() const;
00119 void set_auto_timestamping(bool enabled);
00120 void set_timestamp(const Time *t = NULL);
00121 void set_clock(Clock *clock);
00122
00123 std::list<const char *> get_message_types();
00124
00125 unsigned int msgq_enqueue(Message *message);
00126 unsigned int msgq_enqueue_copy(Message *message);
00127 void msgq_remove(Message *message);
00128 void msgq_remove(unsigned int message_id);
00129 unsigned int msgq_size();
00130 void msgq_flush();
00131 void msgq_lock();
00132 bool msgq_try_lock();
00133 void msgq_unlock();
00134 void msgq_pop();
00135 Message * msgq_first();
00136 bool msgq_empty();
00137
00138
00139
00140
00141 template <class MessageType>
00142 bool msgq_first_is();
00143
00144
00145
00146
00147
00148 template <class MessageType>
00149 MessageType * msgq_first();
00150
00151
00152
00153
00154
00155
00156
00157 template <class MessageType>
00158 MessageType * msgq_first(MessageType *&msg);
00159
00160 MessageQueue::MessageIterator msgq_begin();
00161 MessageQueue::MessageIterator msgq_end();
00162
00163
00164
00165
00166 struct interface_messageinfo_t {
00167 const char *type;
00168 interface_messageinfo_t *next;
00169 };
00170
00171 InterfaceFieldIterator fields();
00172 InterfaceFieldIterator fields_end();
00173
00174 unsigned int num_fields();
00175
00176
00177 static void parse_uid(const char *uid, char **type, char **id);
00178
00179 protected:
00180 Interface();
00181 virtual bool message_valid(const Message *message) const = 0;
00182
00183 void set_hash(unsigned char *ihash);
00184 void add_fieldinfo(interface_fieldtype_t type, const char *name,
00185 size_t length, void *value, const char *enumtype = 0);
00186 void add_messageinfo(const char *name);
00187
00188 void *data_ptr;
00189 unsigned int data_size;
00190 bool data_changed;
00191
00192
00193
00194 typedef struct {
00195 int64_t timestamp_sec;
00196 int64_t timestamp_usec;
00197 } interface_data_ts_t;
00198 interface_data_ts_t *data_ts;
00199
00200 private:
00201 void msgq_append(Message *message);
00202 void set_type_id(const char *type, const char *id);
00203 void set_instance_serial(unsigned short instance_serial);
00204 void set_mediators(InterfaceMediator *iface_mediator,
00205 MessageMediator *msg_mediator);
00206 void set_memory(unsigned int serial, void *real_ptr, void *data_ptr);
00207 void set_readwrite(bool write_access, RefCountRWLock *rwlock);
00208
00209 inline unsigned int next_msg_id()
00210 {
00211 return (__instance_serial << 16) | ++__next_message_id;
00212 }
00213
00214 char __type[__INTERFACE_TYPE_SIZE + 1];
00215 char __id[__INTERFACE_ID_SIZE + 1];
00216 char __uid[__INTERFACE_UID_SIZE + 1];
00217 unsigned char __hash[__INTERFACE_HASH_SIZE];
00218 char __hash_printable[__INTERFACE_HASH_SIZE * 2 + 1];
00219
00220 unsigned short __instance_serial;
00221 bool __valid;
00222
00223 void * __mem_data_ptr;
00224 void * __mem_real_ptr;
00225 unsigned int __mem_serial;
00226 bool __write_access;
00227
00228 RefCountRWLock *__rwlock;
00229
00230 InterfaceMediator *__interface_mediator;
00231 MessageMediator *__message_mediator;
00232 MessageQueue *__message_queue;
00233 unsigned short __next_message_id;
00234
00235 interface_fieldinfo_t *__fieldinfo_list;
00236 interface_messageinfo_t *__messageinfo_list;
00237
00238 unsigned int __num_fields;
00239
00240 Clock *__clock;
00241 Time *__timestamp;
00242 Time *__local_read_timestamp;
00243 bool __auto_timestamping;
00244 };
00245
00246
00247 template <class MessageType>
00248 MessageType *
00249 Interface::msgq_first()
00250 {
00251 MessageType *m = dynamic_cast<MessageType *>(__message_queue->first());
00252 if (m) {
00253 return m;
00254 } else {
00255 throw TypeMismatchException("Message is not of desired type");
00256 }
00257 }
00258
00259
00260 template <class MessageType>
00261 MessageType *
00262 Interface::msgq_first(MessageType *&msg)
00263 {
00264 msg = this->msgq_first<MessageType>();
00265 return msg;
00266 }
00267
00268
00269
00270
00271
00272 template <class MessageType>
00273 bool
00274 Interface::msgq_first_is()
00275 {
00276 return (dynamic_cast<MessageType *>(__message_queue->first()) != 0);
00277 }
00278
00279
00280
00281
00282
00283
00284 typedef void (* InterfaceDestroyFunc) (Interface *interface);
00285
00286
00287
00288
00289 typedef Interface * (* InterfaceFactoryFunc) (void);
00290
00291
00292
00293 #define INTERFACE_MGMT_FRIENDS(interface_class) \
00294 friend Interface * private_new##interface_class(); \
00295 friend void private_delete##interface_class(interface_class *interface);
00296
00297
00298
00299
00300 #define INTERFACE_GENERATOR(interface_class) \
00301 Interface * \
00302 private_new##interface_class() \
00303 { \
00304 return new interface_class(); \
00305 }
00306
00307
00308
00309
00310
00311 #define INTERFACE_DELETER(interface_class) \
00312 void \
00313 private_delete##interface_class(interface_class *interface) \
00314 { \
00315 delete interface; \
00316 }
00317
00318
00319
00320
00321
00322 #define INTERFACE_FACTORY(interface_class) \
00323 extern "C" \
00324 Interface * \
00325 interface_factory() \
00326 { \
00327 return private_new##interface_class(); \
00328 }
00329
00330
00331
00332
00333
00334 #define INTERFACE_DESTROY(interface_class) \
00335 extern "C" \
00336 void \
00337 interface_destroy(interface_class *interface) \
00338 { \
00339 private_delete##interface_class(interface); \
00340 }
00341
00342
00343
00344
00345 #define EXPORT_INTERFACE(interface_class) \
00346 INTERFACE_GENERATOR(interface_class) \
00347 INTERFACE_DELETER(interface_class) \
00348 INTERFACE_FACTORY(interface_class) \
00349 INTERFACE_DESTROY(interface_class)
00350
00351 }
00352
00353 #endif