vrecko
virtual reality framework
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
EventDispatcher.h
Go to the documentation of this file.
1 /***************************************************************************
2  EventDispatcher.h - description
3  -------------------
4  begin : Jul 2003
5  copyright : (C) 2003 by Jan Flasar
6  email : flasar@fi.muni.cz
7  ***************************************************************************/
8 
9 
10 #ifndef EVENTDISPATCHER_H
11 #define EVENTDISPATCHER_H
12 
13 #include <vrecko/Export>
14 #include <vrecko/BaseClass.h>
15 #include <vrecko/DeviceManager.h>
16 #include <vrecko/MTLock.h>
17 
18 #include <string>
19 #include <vector>
20 #include <map>
21 
22 #ifdef WIN32
23 #include <windows.h>
24 #else
25 #include <pthread.h>
26 #endif
27 
28 namespace vrecko {
29 
30 
32 class VRECKO_EXPORT EventDispatcher: public BaseClass {
33  public:
35  ~EventDispatcher();
37 
40  FORWARD_OUTPUT = 1,
42  REQUEST
43  };
44 
46  enum SRType {
47  UNKNOWN = 0,
53  OUTER_OBJECT
54  };
55 
56 
58  VRECKO_EXPORT struct ICSBase {
60  public:
61  ICSBase() { _receiver_ptr = NULL; }
62 
63  inline void setReceiverPtrDirty() { _receiver_ptr = NULL; }
64 
69  BaseClass* getReceiverPtr() { if (_receiver_ptr) return _receiver_ptr; else return getReceiverPtrCore(); }
70 
71  std::string receiver;
72  std::string receiverPin;
73 
75 
76  protected:
79 
80  VRECKO_EXPORT BaseClass* getReceiverPtrCore();
81  };
82 
83 
84  VRECKO_EXPORT struct ICS : public ICSBase{
85  public:
86  //TODO - vyresit lepe?
87  std::string sender;
88 
93  osg::ref_ptr<VreckoMessage> conditionalMessage;
94 
95  osg::ref_ptr<VreckoMessage> activationMessage;
96  };
97 
98  VRECKO_EXPORT struct REQUEST_Struct : public ICSBase {
99  public:
100  const std::string *sceneFile; // a file that this connection will be saved to.
101  // It is a pointer to a shared memory pool, so don't deallocate it.
102  // BTW it's a _variable pointer_ to a _constant string_
103  };
104 
106  VRECKO_EXPORT struct EventStruct {
109  std::string senderIdOrInputName;
110  // Depending on [pReceiver] this member semantics will change.
111  // If [pReceiver] is NULL, then [senderIdOrInputName] will hold the full sender string with the output name
112  // If [pReceiver] is not NULL, then [senderIdOrInputName] will hold the input name of the requested "pin" on the receiver side.
113  osg::ref_ptr<VreckoMessage> message;
114  };
115 
116  VRECKO_EXPORT struct StringWithHash {
118  StringWithHash(const std::string &str) { originalString = str; hashValue = calculateHash(originalString.c_str()); }
119  StringWithHash(const StringWithHash& src) { originalString = src.originalString; hashValue = src.hashValue; };
120 
121  std::string originalString;
122  unsigned int hashValue;
123 
124  unsigned int calculateHash(const char* str) {
125  // From: http://www.partow.net/programming/hashfunctions/ (JSHash)
126  // Simple use another method if this one isn't working well.
127  unsigned int hash = 1315423911;
128 
129  int i = 0;
130  while (str[i]) {
131  hash ^= ((hash << 5) + str[i] + (hash >> 2));
132  ++i;
133  }
134 
135  return hash;
136  }
137  };
138 
139  VRECKO_EXPORT struct StringWithHashComparator {
140  bool operator()(const StringWithHash &a, StringWithHash const &b) {
141  if (a.hashValue != b.hashValue)
142  return (a.hashValue < b.hashValue);
143  return (a.originalString < b.originalString);
144  }
145  };
146 
156  typedef std::multimap<StringWithHash, ICS *, StringWithHashComparator> EI_Type;
157 
159  typedef std::map<StringWithHash, REQUEST_Struct, StringWithHashComparator> REQUEST_Map;
160 
161 #ifdef WIN32
162  void setMainThreadId(DWORD dwID) { hMainThreadId = dwID; }
163 #else
164  void setMainThreadId(pthread_t ptID) { hMainThreadId = ptID; }
165 #endif
166 
174  bool insertEventInterconnection(const std::string &sender, const std::string &receiver, InterconnectionType type = FORWARD_OUTPUT, const std::string &sceneFile = *((std::string*)NULL));
175 
178  bool deleteEventInterconnection(const std::string &sender, const std::string &receiver, InterconnectionType type = FORWARD_OUTPUT);
179 
183  void dirtyInterconnectionsForObject(BaseClass *object, bool bProcessEvents = true, bool bProcessRequests = true);
184 
185 
190  inline bool reportEvent(const std::string &senderAndOutputString, VreckoMessage *pMessage, EventType eType = EXPRESS_EVENT) {
191  return reportEventCore(NULL, senderAndOutputString, pMessage, eType);
192  }
193 
197  inline bool reportEvent(BaseClass *receiver_ptr, const std::string &input_name, VreckoMessage *pMessage, EventType eType = EXPRESS_EVENT) {
198  return reportEventCore(receiver_ptr, input_name, pMessage, eType);
199  }
200 
202  osg::ref_ptr<VreckoMessage> request(const std::string &req_sender, VreckoMessage *pMessage);
203 
205  osg::ref_ptr<VreckoMessage> request(BaseClass *receiver_ptr, const std::string &request_name, VreckoMessage *pMessage);
206 
207 
212  void update(void);
213 
215  void setScenePtr(Scene *ptr) {scene_ptr = ptr;}
216 
217  /* Sets pointer of the World. ... REDUNDANT: Already present in the BaseClass*/
218 // void setWorldPtr(World *ptr) {pWorld = ptr;}
219 
224  bool addOuterObject(const std::string &object_id, BaseClass *pOObject);
225 
227  bool removeOuterObject(const std::string &object_id);
228 
230  bool removeOuterObject(BaseClass *pOObject);
231 
232  inline EI_Type &getEventInterconnectionMap() { return event_interconnection_map; }
233  inline REQUEST_Map &getRequestInterconnectionMap() { return request_interconnection_map; }
234  inline REQUEST_Map &getDefaultRequestInterconnectionMap() { return default_request_interconnection_map; }
235 
237  typedef struct {
238  std::string sender;
239  std::string receiver;
241  const std::string *sceneFile;
242  // a file that this connection will be saved to. Pointer to a shared memory.
243  // BTW it's a _variable pointer_ to a _constant string_
245 
247  std::vector<EventDefinitionStruct> &getEventsVector(void) {return eventsVector;}
248 
249  // ----- Net support
250 
251 /* OBSOLETE - never really used in real life, but may be reimplemented again if necessary (it was made obsolete after the new message implementation
252 
253  typedef struct NetEventStruct {
254  NetEventStruct() {message_event_image = NULL;}
255  ~NetEventStruct() {if (message_event_image) free(message_event_image);}
256 
257  std::string sender;
258  BaseClass::IO_Type type;
259  long int int_event;
260  double double_event;
261  double field_event[16];
262  std::string string_event; // used also for Message ID
263  void *message_event_image;
264  long int message_image_size;
265  };
266 
267  bool sendNetEvents(void);
268 
269  bool reportNetEvents(std::vector<NetEventStruct> *ne_vector);
270 */
272  void setNetSupport(bool status);
273 
290  bool parseSR(const std::string &sr, bool isSender, BaseClass **pEntity, SRType *pSRType, std::string *pIOName, osg::ref_ptr<VreckoMessage> *pRefMessage, bool isRequest = false, bool noErrorOuptut = false);
291 
293  int getProcessedEventsCounter() { return iProcessedEventsCounter; }
294 
296  void resetProcessedEventsCounter() { iProcessedEventsCounter = 0; }
297 
298  protected:
300  std::vector<EventDefinitionStruct> eventsVector;
304  std::vector<EventStruct*> incoming_events[2];
305  int bgListId; // background list Id (index)
307  // Allow messages to be queued into the foreground list (with locking!)
308  // Such messages will be guaranteed to be processed in the current frame.
309  // WARNING: Only change this variable inside a locked block (see [mainLock])
310 
312  std::map<std::string, void*> received_event_map;
313 
314  typedef std::vector<std::string> Decomposition_vec;
316  std::map<std::string, Decomposition_vec> sender_decomposition;
317 
319  std::map<std::string, Decomposition_vec> receiver_decomposition;
320 
323 
326 
327 // World *pWorld;
328 
330  std::map<std::string, BaseClass *> outerObject_map;
331 
333 
334 
337 // std::vector<NetEventStruct> *net_events;
338 // void (*reportNetEventsToServer)(std::vector<NetEventStruct> *);
339 
340 #ifdef WIN32
341  DWORD hMainThreadId;
342 #else
343  pthread_t hMainThreadId;
344 #endif
347  bool isInMainThread();
348 
349  /* Processes pending batch of message.
350  *
351  * Typically called once per frame (in the EventDispatcher::update() ), to process all the messages,
352  * which were accumulated over the last frame.
353  * This is only relevant for messages with a lower priority then EXPRESS, as the EXPRESS messages
354  * are usually processed immediately (except EXPRESS message from other-than-main threads, which
355  * are converted into lower priority messages and processed here).
356  */
357  void processBatchOfEvents(std::vector<EventStruct*> *ref_incoming_events, bool bTurnOffForegroundQueing);
358 
359  /* Main low-level method, which handles processing of a single event.
360  *
361  * Note that it is different from BaseClass::processEvent().
362  */
363  void processEvent(EventStruct *pES);
364 
365  /* Main low-level method, which handles attempts to send an event.
366  *
367  * Decides the time of actual processing of the event. Either postpones the processing or diretly calls the EventDispatcher::processEvent().
368  */
369  bool reportEventCore(BaseClass *receiver_ptr, const std::string &sender, VreckoMessage *pMessage, EventType eType);
370 
372  void debugPrintInterconnectionMap(EI_Type *map);
373 
375  void debugPrintRequestMap(REQUEST_Map *map);
376 
377 
383  bool checkInterconnection(const std::string &sender, const std::string &receiver, bool bRequest);
384  // Great for debug, but can be turned off.
385  // Checks interconnection for any problems (missing sender/receiver), incorrect output/input types
386 };
387 
388 }
389 
390 #endif
391