You.i Engine
YiEventDispatcher.h
Go to the documentation of this file.
1 // © You i Labs Inc. 2000-2017. All rights reserved.
2 #ifndef _YI_EVENT_DISPATCHER_H_
3 #define _YI_EVENT_DISPATCHER_H_
4 
6 #include "framework/YiPredef.h"
8 #include "event/YiEvent.h"
10 #include "signal/YiSignalHandler.h"
11 #include "thread/YiThread.h"
12 #include "thread/YiMutex.h"
14 #include "thread/YiWaitCondition.h"
16 
17 #include <memory>
18 
24 class CYIEventDispatcher;
25 class CYIEventHandler;
27 class CYIEventFilter;
29 class CYISignalEmitEventHandler;
32 
37 {
38 public:
39 
42 
43  virtual void EventLoopStarted(const std::shared_ptr<CYIEventDispatcher> &pDispatcher) = 0;
44 
45  virtual void EventLoopExited(const std::shared_ptr<CYIEventDispatcher> &pDispatcher) = 0;
46 
47  virtual void EventDispatchStarted(const std::shared_ptr<CYIEventDispatcher> &pDispatcher, CYIEvent *pEvent) = 0;
48 
49  virtual void EventDispatchEnded(const std::shared_ptr<CYIEventDispatcher> &pDispatcher, CYIEvent *pEvent) = 0;
50 
51  virtual void EventPreFilteredByDispatcher(const std::shared_ptr<CYIEventDispatcher> &pDispatcher, CYIEvent *pEvent, CYIEventFilter *pFilter) = 0;
52 
53  virtual void EventPreFilteredByHandler(const std::shared_ptr<CYIEventDispatcher> &pDispatcher, CYIEvent *pEvent, CYIEventFilter *pFilter, CYIEventHandler *pHandler) = 0;
54 
55  virtual void EventHandled(const std::shared_ptr<CYIEventDispatcher> &pDispatcher, CYIEvent *pEvent, CYIEventHandler *pHandler) = 0;
56 
57  virtual void EventPostFilteredByHandler(const std::shared_ptr<CYIEventDispatcher> &pDispatcher, CYIEvent *pEvent, CYIEventFilter *pFilter, CYIEventHandler *pHandler) = 0;
58 
59  virtual void EventPostFilteredByDispatcher(const std::shared_ptr<CYIEventDispatcher> &pDispatcher, CYIEvent *pEvent, CYIEventFilter *pFilter) = 0;
60 };
61 
65 class CYIEventDispatcher : public CYISignalHandler, public std::enable_shared_from_this<CYIEventDispatcher>, public CYIScriptableObject
66 {
67  friend class CYIEventHandler;
68 
69  typedef std::vector<std::shared_ptr<CYIEventHandlerProxy>> YI_EVENT_HANDLER_LIST;
70  typedef std::vector<std::shared_ptr<CYIEventFilterProxy>> YI_EVENT_FILTER_LIST;
71  typedef std::vector<IYIEventDispatcherListener *> YI_EVENT_DISPATCHER_LISTENER_LIST;
72  typedef CYIPriorityQueue<std::pair<std::unique_ptr<CYIEvent>, std::shared_ptr<CYIEventHandlerProxy>>> YI_EVENT_QUEUE;
73  typedef std::vector<std::pair<CYIThreadHandle, std::shared_ptr<CYIEventDispatcher>>> YI_DISPATCHER_MAP;
74 
75 public:
76 
78  virtual ~CYIEventDispatcher();
79 
83  bool Start();
84 
92  bool Exit(bool bJoin = false, bool bWaitUntilEmpty = false);
93 
97  void WaitUntilEventQueueRunning();
98 
107  bool WaitUntilEventPosted(uint64_t uTimeoutMs = 0);
108 
114  bool ProcessOneEvent();
115 
121  bool ProcessAllEvents();
122 
126  bool ProcessAllEvents(uint64_t uTimeoutUs);
127 
143  bool RegisterEventHandler(CYIEventHandler *pEventHandler);
144 
160  bool UnregisterEventHandler(CYIEventHandler *pEventHandler);
161 
175  bool RegisterEventFilter(CYIEventFilter *pEventFilter);
176 
188  bool UnregisterEventFilter(CYIEventFilter *pEventFilter);
189 
195  bool RegisterEventDispatcherListener(IYIEventDispatcherListener *pEventDispatcherListener);
196 
202  bool UnregisterEventDispatcherListener(IYIEventDispatcherListener *pEventDispatcherListener);
203 
209  bool PostEvent(std::unique_ptr<CYIEvent> pEvent, YI_EVENT_PRIORITY priority = YI_EVENT_PRIORITY_DEFAULT, bool bBump = false);
210 
214  bool PostEvent(std::unique_ptr<CYIEvent> pEvent, CYIEventHandler *pDestination, YI_EVENT_PRIORITY priority = YI_EVENT_PRIORITY_DEFAULT, bool bBump = false);
215 
219  bool PostUniqueEvent(std::unique_ptr<CYIEvent> pEvent, YI_EVENT_PRIORITY priority = YI_EVENT_PRIORITY_DEFAULT);
220 
226  bool PostUniqueEvent(std::unique_ptr<CYIEvent> pEvent, CYIEventHandler *pDestination, YI_EVENT_PRIORITY priority = YI_EVENT_PRIORITY_DEFAULT);
227 
247  bool SendEvent(std::unique_ptr<CYIEvent> pEvent);
248 
270  bool SendEvent(std::unique_ptr<CYIEvent> pEvent, CYIEventHandler *pDestination);
271 
275  int32_t GetEventCount() const;
276 
282  void Shutdown();
283 
287  void DiscardAllPosts();
288 
292  void DiscardPosts(CYIEventHandler *pDestination);
293 
294 
298  void DiscardPostsIf(bool (*predicate)(const std::shared_ptr<CYIEventDispatcher> &, CYIEvent *, CYIEventHandler *, YI_EVENT_PRIORITY));
299 
303  static std::shared_ptr<CYIEventDispatcher> GetDispatcher(const CYIThreadHandle &threadAffinity);
304 
308  static const std::shared_ptr<CYIEventDispatcher> &GetDefaultDispatcher();
309 
313  static const CYIThreadHandle &GetDefaultDispatcherThreadAffinity();
314 
320  static const std::shared_ptr<CYIEventDispatcher> &GetDrawDispatcher();
321 
325  static void SetDispatcher(const CYIThreadHandle &threadAffinity, const std::shared_ptr<CYIEventDispatcher> &pDispatcher);
326 
330  static void RemoveDispatcher(const CYIThreadHandle &threadAffinity);
331 
335  static void SetDefaultDispatcher(const std::shared_ptr<CYIEventDispatcher> &pDispatcher);
336 
340  static void RemoveDefaultDispatcher();
341 
345  static void SetDrawDispatcher(const std::shared_ptr<CYIEventDispatcher> &pDispatcher);
346 
350  static void RemoveDrawDispatcher();
351 
352 
353 
357  CYIEventHandler *GetSignalEmitEventHandler();
358 
362  CYIEventHandler *GetDeferredDeletionEventHandler();
363 
367  CYIEventHandler *GetTaskEventHandler();
368 
369 private:
372 
373  bool PreFilter(CYIEvent *pEvent, const std::shared_ptr<CYIEventHandlerProxy> &pDestination);
374  bool PostFilter(CYIEvent *pEvent, const std::shared_ptr<CYIEventHandlerProxy> &pDestination);
375  bool DispatchEvent(CYIEvent *pEvent, const std::shared_ptr<CYIEventHandlerProxy> &pDestination);
376  bool ProcessEvent(CYIEvent *pEvent, const std::shared_ptr<CYIEventHandlerProxy> &pDestination);
377 
378  void NotifyEventLoopStarted();
379  void NotifyEventLoopExited();
380  void NotifyEventDispatchStarted(CYIEvent *pEvent);
381  void NotifyEventDispatchEnded(CYIEvent *pEvent);
382  void NotifyEventPreFilteredByDispatcher(CYIEvent *pEvent, CYIEventFilter *pFilter);
383  void NotifyEventPreFilteredByHandler(CYIEvent *pEvent, CYIEventFilter *pFilter, CYIEventHandler *pHandler);
384  void NotifyEventHandled(CYIEvent *pEvent, CYIEventHandler *pHandler);
385  void NotifyEventPostFilteredByHandler(CYIEvent *pEvent, CYIEventFilter *pFilter, CYIEventHandler *pHandler);
386  void NotifyEventPostFilteredByDispatcher(CYIEvent *pEvent, CYIEventFilter *pFilter);
387 
388  bool m_bEventQueueRunning;
389 
390  CYISignalEmitEventHandler *m_pSignalEmitEventHandler;
391  CYIDeferredDeletionEventHandler *m_pDeferredDeletionEventHandler;
392  CYITaskEventHandler *m_pTaskEventHandler;
393 
394  YI_EVENT_HANDLER_LIST m_eventHandlerList;
395  YI_EVENT_FILTER_LIST m_eventFilterList;
396  YI_EVENT_DISPATCHER_LISTENER_LIST m_eventDispatcherListenerList;
397  YI_EVENT_QUEUE m_eventQueue;
398 
399  CYILazy<CYIMutex> m_eventHandlerListMutex;
400  CYILazy<CYIMutex> m_eventFilterListMutex;
401  CYILazy<CYIMutex> m_eventDispatcherListenerListMutex;
402 
403  mutable CYIMutex m_eventQueueMutex;
404  CYIWaitCondition m_eventQueueWaitCondition;
405  CYIWaitCondition m_waitUntilEventWaitCondition;
406 
407  static YI_DISPATCHER_MAP s_dispatcherMap;
408  static std::shared_ptr<CYIEventDispatcher> s_dispatcherDefault;
409  static CYIThreadHandle s_dispatcherDefaultThreadAffinity;
410  static std::shared_ptr<CYIEventDispatcher> s_dispatcherDraw;
411  static CYIReadWriteMutex s_dispatcherMapMutex;
412 };
413 
419 template<typename YI_TYPE>
420 inline void YiDeleteLater(std::unique_ptr<YI_TYPE> pPtr)
421 {
422  if (pPtr)
423  {
424  std::shared_ptr<CYIEventDispatcher> pDispatcher = CYIEventDispatcher::GetDispatcher(CYIThread::GetCurrentThreadId());
425  if (!pDispatcher)
426  {
428  }
429 
430  if (!pDispatcher)
431  {
432  YI_LOGD("YiDeleteLater", "No event dispatcher. YiDeleteLater called while the application is shutting down, so deleting ptr immediately.");
433  // If we can't delete later, we have to delete now to avoid a memory leak. This will occur during shutdown when the CYIDeferredDeletionEvent is deleting the pPtr, and it in turn results in a YiDeleteLater being called.
434  pPtr.reset();
435  return;
436  }
437 
438  pDispatcher->PostEvent(std::unique_ptr<CYIEvent>(new CYIDeferredDeletionEvent<YI_TYPE>(std::move(pPtr))), pDispatcher->GetDeferredDeletionEventHandler(), YI_EVENT_PRIORITY_HIGHEST);
439  }
440 }
441 
445 #endif /* _YI_EVENT_DISPATCHER_H_ */
bool RegisterEventFilter(CYIEventFilter *pFilter)
virtual void EventPostFilteredByHandler(const std::shared_ptr< CYIEventDispatcher > &pDispatcher, CYIEvent *pEvent, CYIEventFilter *pFilter, CYIEventHandler *pHandler)=0
Allows registering of event filters which can be used to perform processing on an event before and af...
Definition: YiEventHandler.h:25
Definition: YiMutex.h:110
Base class for events.
Definition: YiEvent.h:489
static std::shared_ptr< CYIEventDispatcher > GetDispatcher(const CYIThreadHandle &threadAffinity)
virtual ~IYIEventDispatcherListener()
Definition: YiEventDispatcher.h:41
#define YI_LOGD(tag, msg,...)
Definition: YiLoggerHelper.h:80
Definition: YiEvent.h:481
virtual void EventDispatchStarted(const std::shared_ptr< CYIEventDispatcher > &pDispatcher, CYIEvent *pEvent)=0
bool PreFilter(const std::shared_ptr< CYIEventDispatcher > &pDispatcher, CYIEvent *pEvent)
virtual void EventDispatchEnded(const std::shared_ptr< CYIEventDispatcher > &pDispatcher, CYIEvent *pEvent)=0
Proxy for a CYIEventFilter allowing safe destruction of the internal event filter objects...
Definition: YiEventFilterProxy.h:24
The base class for an object accessible from script source code.
Definition: YiScriptableObject.h:28
static const std::shared_ptr< CYIEventDispatcher > & GetDefaultDispatcher()
YI_EVENT_PRIORITY
Priority of the event in the event queue.
Definition: YiEvent.h:473
A container class which maintains a queue of items within defined YI_PRIORITY_QUEUE_PRIORITY prioriti...
Definition: YiPriorityQueue.h:44
virtual void EventHandled(const std::shared_ptr< CYIEventDispatcher > &pDispatcher, CYIEvent *pEvent, CYIEventHandler *pHandler)=0
Handles events where data deletion needs to be deferred.
Definition: YiDeferredDeletionEventHandler.h:17
static CYIThreadHandle GetCurrentThreadId()
friend class CYIEventDispatcher
Definition: YiEventHandler.h:27
Definition: YiReadWriteMutex.h:14
Definition: YiSignalHandler.h:174
virtual void EventLoopExited(const std::shared_ptr< CYIEventDispatcher > &pDispatcher)=0
virtual void EventLoopStarted(const std::shared_ptr< CYIEventDispatcher > &pDispatcher)=0
bool PostFilter(const std::shared_ptr< CYIEventDispatcher > &pDispatcher, CYIEvent *pEvent)
virtual void EventPreFilteredByDispatcher(const std::shared_ptr< CYIEventDispatcher > &pDispatcher, CYIEvent *pEvent, CYIEventFilter *pFilter)=0
Handles events where tasks are executed when the event is processed on an event queue.
Definition: YiTaskEventHandler.h:15
Stores, queues and dispatches events as well as sending notifications to IYIEventDispatcherListener o...
Definition: YiEventDispatcher.h:65
A class used to block a thread until a condition is met, as signaled by a different thread...
Definition: YiWaitCondition.h:64
Allows children that inherit from this class to implement processing before and after events are hand...
Definition: YiEventFilter.h:24
bool UnregisterEventFilter(CYIEventFilter *pFilter)
void YiDeleteLater(std::unique_ptr< YI_TYPE > pPtr)
Adds the given pointer to the deferred deletion queue.
Definition: YiEventDispatcher.h:420
IYIEventDispatcherListener()
Definition: YiEventDispatcher.h:40
Implementors of this Listener interface can register themselves with the CYIEventDispather and become...
Definition: YiEventDispatcher.h:36
Definition: YiThreadHandle.h:43
virtual void EventPreFilteredByHandler(const std::shared_ptr< CYIEventDispatcher > &pDispatcher, CYIEvent *pEvent, CYIEventFilter *pFilter, CYIEventHandler *pHandler)=0
Proxy for a CYIEventHandler allowing safe destruction of the internal event handler objects...
Definition: YiEventHandlerProxy.h:26
CYIEventHandler & operator=(const CYIEventHandler &)
virtual void EventPostFilteredByDispatcher(const std::shared_ptr< CYIEventDispatcher > &pDispatcher, CYIEvent *pEvent, CYIEventFilter *pFilter)=0
Event for handling deferred deletion of data of type YI_TYPE. SfinaeHelper type is used to control a ...
Definition: YiDeferredDeletionEvent.h:30
Definition: YiEvent.h:475