Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

273 lines
17 KiB

  1. //========== Copyright (c) Valve Corporation, All rights reserved. ==========//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. //===========================================================================//
  8. #ifndef IEVENTSYSTEM_H
  9. #define IEVENTSYSTEM_H
  10. #ifdef _WIN32
  11. #pragma once
  12. #endif
  13. #include "appframework/iappsystem.h"
  14. #include "tier0/basetypes.h"
  15. #include "tier1/functors.h"
  16. //-----------------------------------------------------------------------------
  17. // Event queues are used to allow listeners to decide at what point they
  18. // want to deal with event processing
  19. //-----------------------------------------------------------------------------
  20. DECLARE_POINTER_HANDLE( EventQueue_t );
  21. #define EVENT_QUEUE_HANDLE_INVALID ( (EventQueue_t)0 )
  22. DECLARE_POINTER_HANDLE( EventId_t );
  23. #define EVENT_ID_INVALID ( (EventId_t)0 )
  24. //-----------------------------------------------------------------------------
  25. // Global interface for posting/listening to events
  26. //
  27. // Usage for registering/unregistering listeners and posting events:
  28. // DEFINE_EVENT2_WITHNAMES( TestEvent, int, x, int, y );
  29. // void OnTestEvent( const int &x, const int &y );
  30. // void f()
  31. // {
  32. // hTest = g_pEventSystem->CreateEventQueue();
  33. // TestEvent::RegisterFunc( hTest, OnTestEvent );
  34. // or TestEvent::RegisterFunc( hTest, myClassPtr, &CMyClass::OnTestEvent );
  35. // TestEvent::Post( 100, 200 );
  36. // TestEvent::PostToListener( myClassPtr, 100, 200 );
  37. // g_pEventSystem->ProcessEvents( hTest );
  38. // TestEvent::UnregisterFunc( hTest, OnTestEvent );
  39. // g_pEventSystem->DestroyEventQueue( hTest );
  40. // }
  41. //
  42. // Note that the arguments of the event handlers are always const references
  43. // to the arguments specified in the event declaration to avoid extra copies
  44. // of the data.
  45. //
  46. // Also note that it's possible to post an event to a specific listener
  47. // using PostToListener. Just specify the class name as the first argument.
  48. //
  49. // Shit gets funky when you pass pointers to events. You need to be very careful
  50. // that the pointer is guaranteed to be valid until the messages are being posted.
  51. // Also, because everything is a const reference, the function prototypes
  52. // for stuff that accepts pointers looks like this strangeness:
  53. //
  54. // DEFINE_EVENT2_WITHNAMES( TestEvent, int, x, char *, pName );
  55. // void OnTestEvent( const int &x, char * const & pName );
  56. //
  57. // Also note: You cannot register or unregister while in the middle of processing events
  58. //
  59. // NOTE: We use EventClass::RegisterMemberFunc / EventClass:RegisterFunc
  60. // instead of overloading EventClass::Register to get more sane-looking
  61. // error message from the compiler if it happens to be passed an invalid
  62. // event handler.
  63. //
  64. // From a perf standpoint, registering + unregistering listeners, and
  65. // destroying event queues all can cause thread stalls. Do them with
  66. // low frequency.
  67. //-----------------------------------------------------------------------------
  68. abstract_class IEventSystem : public IAppSystem
  69. {
  70. public:
  71. // Creates an event queue.
  72. // Creation can occur at any time. Destruction can happen at any time
  73. // provided you're not simultaneously processing events or registering/unregistering
  74. // listeners on the same thread
  75. virtual EventQueue_t CreateEventQueue() = 0;
  76. virtual void DestroyEventQueue( EventQueue_t hQueue ) = 0;
  77. // Processess queued events for a event queue
  78. virtual void ProcessEvents( EventQueue_t hQueue ) = 0;
  79. // Ignore that macro magic! It allows us to call PostEvent on an arbitrary event id
  80. // with arbitrary arguments. Useful to allow systems to post event ids told to
  81. // it by external systems
  82. inline void PostEvent( EventId_t nEventId )
  83. {
  84. CFunctorData *pData = CreateFunctorData( );
  85. PostEventInternal( nEventId, EVENT_QUEUE_HANDLE_INVALID, NULL, pData );
  86. }
  87. inline void PostEvent( EventId_t nEventId, EventQueue_t hQueue )
  88. {
  89. CFunctorData *pData = CreateFunctorData( );
  90. PostEventInternal( nEventId, hQueue, NULL, pData );
  91. }
  92. inline void PostEventToListener( EventId_t nEventId, const void *pListener )
  93. {
  94. CFunctorData *pData = CreateFunctorData( );
  95. PostEventInternal( nEventId, EVENT_QUEUE_HANDLE_INVALID, pListener, pData );
  96. }
  97. inline void PostEventToListener( EventId_t nEventId, EventQueue_t hQueue, const void *pListener )
  98. {
  99. CFunctorData *pData = CreateFunctorData( );
  100. PostEventInternal( nEventId, hQueue, pListener, pData );
  101. }
  102. #define DEFINE_POST_EVENT(N) \
  103. template < FUNC_SOLO_TEMPLATE_ARG_PARAMS_##N > \
  104. inline void PostEvent( EventId_t nEventId FUNC_ARG_FORMAL_PARAMS_##N ) \
  105. { \
  106. CFunctorData *pData = CreateFunctorData( FUNC_CALL_ARGS_##N ); \
  107. PostEventInternal( nEventId, EVENT_QUEUE_HANDLE_INVALID, NULL, pData ); \
  108. } \
  109. template < FUNC_SOLO_TEMPLATE_ARG_PARAMS_##N > \
  110. inline void PostEvent( EventId_t nEventId, EventQueue_t hQueue FUNC_ARG_FORMAL_PARAMS_##N ) \
  111. { \
  112. CFunctorData *pData = CreateFunctorData( FUNC_CALL_ARGS_##N ); \
  113. PostEventInternal( nEventId, hQueue, NULL, pData ); \
  114. } \
  115. template < FUNC_SOLO_TEMPLATE_ARG_PARAMS_##N > \
  116. inline void PostEventToListener( EventId_t nEventId, const void *pListener FUNC_ARG_FORMAL_PARAMS_##N ) \
  117. { \
  118. CFunctorData *pData = CreateFunctorData( FUNC_CALL_ARGS_##N ); \
  119. PostEventInternal( nEventId, EVENT_QUEUE_HANDLE_INVALID, pListener, pData ); \
  120. } \
  121. template < FUNC_SOLO_TEMPLATE_ARG_PARAMS_##N > \
  122. inline void PostEventToListener( EventId_t nEventId, EventQueue_t hQueue, const void *pListener FUNC_ARG_FORMAL_PARAMS_##N ) \
  123. { \
  124. CFunctorData *pData = CreateFunctorData( FUNC_CALL_ARGS_##N ); \
  125. PostEventInternal( nEventId, hQueue, pListener, pData ); \
  126. }
  127. FUNC_GENERATE_ALL_BUT0( DEFINE_POST_EVENT );
  128. #undef DEFINE_POST_EVENT
  129. private:
  130. // NOTE: These are not meant to be called directly. See the comment above
  131. // the IEventSystem class definition for how to post/register/unregister events
  132. virtual EventId_t RegisterEvent( const char *pEventName ) = 0;
  133. virtual void PostEventInternal( EventId_t nEventId, EventQueue_t hQueue, const void *pListener, CFunctorData *pData ) = 0;
  134. virtual void RegisterListener( EventId_t nEventId, EventQueue_t hQueue, CFunctorCallback *pCallback ) = 0;
  135. virtual void UnregisterListener( EventId_t nEventId, EventQueue_t hQueue, CFunctorCallback *pCallback ) = 0;
  136. #define DEFINE_FRIEND_CLASSES(N) \
  137. template < typename Event_t FUNC_TEMPLATE_ARG_PARAMS_##N > friend class CEventSignature##N
  138. FUNC_GENERATE_ALL( DEFINE_FRIEND_CLASSES );
  139. #undef DEFINE_FRIEND_CLASSES
  140. };
  141. //-----------------------------------------------------------------------------
  142. // Ignore that man behind the curtain!
  143. //-----------------------------------------------------------------------------
  144. #define DEFINE_EVENT_INTERNAL(N) \
  145. template < typename Event_t FUNC_TEMPLATE_ARG_PARAMS_##N > \
  146. class CEventSignature##N \
  147. { \
  148. public: \
  149. static inline void Post( FUNC_PROXY_ARG_FORMAL_PARAMS_##N ) \
  150. { \
  151. CFunctorData *pData = CreateFunctorData( FUNC_CALL_ARGS_##N ); \
  152. g_pEventSystem->PostEventInternal( Event_t::GetEventId(), EVENT_QUEUE_HANDLE_INVALID, NULL, pData ); \
  153. } \
  154. static inline void Post( EventQueue_t hQueue FUNC_ARG_FORMAL_PARAMS_##N ) \
  155. { \
  156. CFunctorData *pData = CreateFunctorData( FUNC_CALL_ARGS_##N ); \
  157. g_pEventSystem->PostEventInternal( Event_t::GetEventId(), hQueue, NULL, pData ); \
  158. } \
  159. static inline void PostToListener( const void *pListener FUNC_ARG_FORMAL_PARAMS_##N ) \
  160. { \
  161. CFunctorData *pData = CreateFunctorData( FUNC_CALL_ARGS_##N ); \
  162. g_pEventSystem->PostEventInternal( Event_t::GetEventId(), EVENT_QUEUE_HANDLE_INVALID, pListener, pData ); \
  163. } \
  164. static inline void PostToListener( EventQueue_t hQueue, const void *pListener FUNC_ARG_FORMAL_PARAMS_##N ) \
  165. { \
  166. CFunctorData *pData = CreateFunctorData( FUNC_CALL_ARGS_##N ); \
  167. g_pEventSystem->PostEventInternal( Event_t::GetEventId(), hQueue, pListener, pData ); \
  168. } \
  169. static inline void RegisterFunc( EventQueue_t hQueue, void (*pfnProxied)( FUNC_PROXY_ARG_FORMAL_PARAMS_##N ) ) \
  170. { \
  171. CFunctorCallback *pCallback = CreateFunctorCallback( pfnProxied ); \
  172. g_pEventSystem->RegisterListener( Event_t::GetEventId(), hQueue, pCallback ); \
  173. } \
  174. static inline void UnregisterFunc( EventQueue_t hQueue, void (*pfnProxied)( FUNC_PROXY_ARG_FORMAL_PARAMS_##N ) ) \
  175. { \
  176. CFunctorCallback *pCallback = CreateFunctorCallback( pfnProxied ); \
  177. g_pEventSystem->UnregisterListener( Event_t::GetEventId(), hQueue, pCallback ); \
  178. } \
  179. template < class OBJECT_TYPE_PTR > \
  180. static inline void RegisterMemberFunc( EventQueue_t hQueue, OBJECT_TYPE_PTR *pClass, void (OBJECT_TYPE_PTR::*pfnProxied)( FUNC_PROXY_ARG_FORMAL_PARAMS_##N ) ) \
  181. { \
  182. CFunctorCallback *pCallback = CreateFunctorCallback( pClass, pfnProxied ); \
  183. g_pEventSystem->RegisterListener( Event_t::GetEventId(), hQueue, pCallback ); \
  184. } \
  185. template < class OBJECT_TYPE_PTR > \
  186. static inline void UnregisterMemberFunc( EventQueue_t hQueue, OBJECT_TYPE_PTR *pClass, void (OBJECT_TYPE_PTR::*pfnProxied)( FUNC_PROXY_ARG_FORMAL_PARAMS_##N ) ) \
  187. { \
  188. CFunctorCallback *pCallback = CreateFunctorCallback( pClass, pfnProxied ); \
  189. g_pEventSystem->UnregisterListener( Event_t::GetEventId(), hQueue, pCallback ); \
  190. } \
  191. static EventId_t RegisterEvent( const char *pEventName ) \
  192. { \
  193. return g_pEventSystem->RegisterEvent( pEventName ); \
  194. } \
  195. };
  196. FUNC_GENERATE_ALL( DEFINE_EVENT_INTERNAL )
  197. #define DEFINE_EVENTID_INTERNAL( _eventName ) \
  198. public: \
  199. static EventId_t GetEventId() \
  200. { \
  201. static EventId_t s_nEventId = EVENT_ID_INVALID; \
  202. if ( s_nEventId == EVENT_ID_INVALID ) \
  203. { \
  204. s_nEventId = RegisterEvent( #_eventName ); \
  205. } \
  206. return s_nEventId; \
  207. }
  208. #define DEFINE_EVENT( _eventName ) class _eventName : public CEventSignature0< _eventName > { DEFINE_EVENTID_INTERNAL( _eventName ); }
  209. #define DEFINE_EVENT1( _eventName, _arg1 ) class _eventName : public CEventSignature1< _eventName, _arg1 > { DEFINE_EVENTID_INTERNAL( _eventName ); }
  210. #define DEFINE_EVENT2( _eventName, _arg1, _arg2 ) class _eventName : public CEventSignature2< _eventName, _arg1, _arg2 > { DEFINE_EVENTID_INTERNAL( _eventName ); }
  211. #define DEFINE_EVENT3( _eventName, _arg1, _arg2, _arg3 ) class _eventName : public CEventSignature3< _eventName, _arg1, _arg2, _arg3 > { DEFINE_EVENTID_INTERNAL( _eventName ); }
  212. #define DEFINE_EVENT4( _eventName, _arg1, _arg2, _arg3, _arg4 ) class _eventName : public CEventSignature4< _eventName, _arg1, _arg2, _arg3, _arg4 > { DEFINE_EVENTID_INTERNAL( _eventName ); }
  213. #define DEFINE_EVENT5( _eventName, _arg1, _arg2, _arg3, _arg4, _arg5 ) class _eventName : public CEventSignature5< _eventName, _arg1, _arg2, _arg3, _arg4, _arg5 > { DEFINE_EVENTID_INTERNAL( _eventName ); }
  214. #define DEFINE_EVENT6( _eventName, _arg1, _arg2, _arg3, _arg4, _arg5, _arg6 ) class _eventName : public CEventSignature6< _eventName, _arg1, _arg2, _arg3, _arg4, _arg5, _arg6 > { DEFINE_EVENTID_INTERNAL( _eventName ); }
  215. #define DEFINE_EVENT7( _eventName, _arg1, _arg2, _arg3, _arg4, _arg5, _arg6, _arg7 ) class _eventName : public CEventSignature7< _eventName, _arg1, _arg2, _arg3, _arg4, _arg5, _arg6, _arg7 > { DEFINE_EVENTID_INTERNAL( _eventName ); }
  216. #define DEFINE_EVENT8( _eventName, _arg1, _arg2, _arg3, _arg4, _arg5, _arg6, _arg7, _arg8 ) class _eventName : public CEventSignature8< _eventName, _arg1, _arg2, _arg3, _arg4, _arg5, _arg6, _arg7, _arg8 > { DEFINE_EVENTID_INTERNAL( _eventName ); }
  217. #define DEFINE_EVENT9( _eventName, _arg1, _arg2, _arg3, _arg4, _arg5, _arg6, _arg7, _arg8, _arg9 ) class _eventName : public CEventSignature9< _eventName, _arg1, _arg2, _arg3, _arg4, _arg5, _arg6, _arg7, _arg8, _arg9 > { DEFINE_EVENTID_INTERNAL( _eventName ); }
  218. #define DEFINE_EVENT10( _eventName, _arg1, _arg2, _arg3, _arg4, _arg5, _arg6, _arg7, _arg8, _arg9, _arg10 ) class _eventName : public CEventSignature10< _eventName, _arg1, _arg2, _arg3, _arg4, _arg5, _arg6, _arg7, _arg8, _arg9, _arg10 > { DEFINE_EVENTID_INTERNAL( _eventName ); }
  219. #define DEFINE_EVENT11( _eventName, _arg1, _arg2, _arg3, _arg4, _arg5, _arg6, _arg7, _arg8, _arg9, _arg10, _arg11 ) class _eventName : public CEventSignature11< _eventName, _arg1, _arg2, _arg3, _arg4, _arg5, _arg6, _arg7, _arg8, _arg9, _arg10, _arg11 > { DEFINE_EVENTID_INTERNAL( _eventName ); }
  220. #define DEFINE_EVENT12( _eventName, _arg1, _arg2, _arg3, _arg4, _arg5, _arg6, _arg7, _arg8, _arg9, _arg10, _arg11, _arg12 ) class _eventName : public CEventSignature12< _eventName, _arg1, _arg2, _arg3, _arg4, _arg5, _arg6, _arg7, _arg8, _arg9, _arg10, _arg11, _arg12 > { DEFINE_EVENTID_INTERNAL( _eventName ); }
  221. #define DEFINE_EVENT13( _eventName, _arg1, _arg2, _arg3, _arg4, _arg5, _arg6, _arg7, _arg8, _arg9, _arg10, _arg11, _arg12, _arg13 ) class _eventName : public CEventSignature13< _eventName, _arg1, _arg2, _arg3, _arg4, _arg5, _arg6, _arg7, _arg8, _arg9, _arg10, _arg11, _arg12, _arg13 > { DEFINE_EVENTID_INTERNAL( _eventName ); }
  222. #define DEFINE_EVENT14( _eventName, _arg1, _arg2, _arg3, _arg4, _arg5, _arg6, _arg7, _arg8, _arg9, _arg10, _arg11, _arg12, _arg13, _arg14 ) class _eventName : public CEventSignature14< _eventName, _arg1, _arg2, _arg3, _arg4, _arg5, _arg6, _arg7, _arg8, _arg9, _arg10, _arg11, _arg12, _arg13, _arg14 > { DEFINE_EVENTID_INTERNAL( _eventName ); }
  223. #define DEFINE_EVENT1_WITHNAMES( _eventName, _arg1, _arg1Name ) \
  224. DEFINE_EVENT1( _eventName, _arg1 )
  225. #define DEFINE_EVENT2_WITHNAMES( _eventName, _arg1, _arg1Name, _arg2, _arg2Name ) \
  226. DEFINE_EVENT2( _eventName, _arg1, _arg2 )
  227. #define DEFINE_EVENT3_WITHNAMES( _eventName, _arg1, _arg1Name, _arg2, _arg2Name, _arg3, _arg3Name ) \
  228. DEFINE_EVENT3( _eventName, _arg1, _arg2, _arg3 )
  229. #define DEFINE_EVENT4_WITHNAMES( _eventName, _arg1, _arg1Name, _arg2, _arg2Name, _arg3, _arg3Name, _arg4, _arg4Name ) \
  230. DEFINE_EVENT4( _eventName, _arg1, _arg2, _arg3, _arg4 )
  231. #define DEFINE_EVENT5_WITHNAMES( _eventName, _arg1, _arg1Name, _arg2, _arg2Name, _arg3, _arg3Name, _arg4, _arg4Name, _arg5, _arg5Name ) \
  232. DEFINE_EVENT5( _eventName, _arg1, _arg2, _arg3, _arg4, _arg5 )
  233. #define DEFINE_EVENT6_WITHNAMES( _eventName, _arg1, _arg1Name, _arg2, _arg2Name, _arg3, _arg3Name, _arg4, _arg4Name, _arg5, _arg5Name, _arg6, _arg6Name ) \
  234. DEFINE_EVENT6( _eventName, _arg1, _arg2, _arg3, _arg4, _arg5, _arg6 )
  235. #define DEFINE_EVENT7_WITHNAMES( _eventName, _arg1, _arg1Name, _arg2, _arg2Name, _arg3, _arg3Name, _arg4, _arg4Name, _arg5, _arg5Name, _arg6, _arg6Name, _arg7, _arg7Name ) \
  236. DEFINE_EVENT7( _eventName, _arg1, _arg2, _arg3, _arg4, _arg5, _arg6, _arg7 )
  237. #define DEFINE_EVENT8_WITHNAMES( _eventName, _arg1, _arg1Name, _arg2, _arg2Name, _arg3, _arg3Name, _arg4, _arg4Name, _arg5, _arg5Name, _arg6, _arg6Name, _arg7, _arg7Name, _arg8, _arg8Name ) \
  238. DEFINE_EVENT8( _eventName, _arg1, _arg2, _arg3, _arg4, _arg5, _arg6, _arg7, _arg8 )
  239. #define DEFINE_EVENT9_WITHNAMES( _eventName, _arg1, _arg1Name, _arg2, _arg2Name, _arg3, _arg3Name, _arg4, _arg4Name, _arg5, _arg5Name, _arg6, _arg6Name, _arg7, _arg7Name, _arg8, _arg8Name, _arg9, _arg9Name ) \
  240. DEFINE_EVENT9( _eventName, _arg1, _arg2, _arg3, _arg4, _arg5, _arg6, _arg7, _arg8, _arg9 )
  241. #define DEFINE_EVENT10_WITHNAMES( _eventName, _arg1, _arg1Name, _arg2, _arg2Name, _arg3, _arg3Name, _arg4, _arg4Name, _arg5, _arg5Name, _arg6, _arg6Name, _arg7, _arg7Name, _arg8, _arg8Name, _arg9, _arg9Name, _arg10, _arg10Name ) \
  242. DEFINE_EVENT10( _eventName, _arg1, _arg2, _arg3, _arg4, _arg5, _arg6, _arg7, _arg8, _arg9, _arg10 )
  243. #define DEFINE_EVENT11_WITHNAMES( _eventName, _arg1, _arg1Name, _arg2, _arg2Name, _arg3, _arg3Name, _arg4, _arg4Name, _arg5, _arg5Name, _arg6, _arg6Name, _arg7, _arg7Name, _arg8, _arg8Name, _arg9, _arg9Name, _arg10, _arg10Name, _arg11, _arg11Name ) \
  244. DEFINE_EVENT11( _eventName, _arg1, _arg2, _arg3, _arg4, _arg5, _arg6, _arg7, _arg8, _arg9, _arg10, _arg11 )
  245. #define DEFINE_EVENT12_WITHNAMES( _eventName, _arg1, _arg1Name, _arg2, _arg2Name, _arg3, _arg3Name, _arg4, _arg4Name, _arg5, _arg5Name, _arg6, _arg6Name, _arg7, _arg7Name, _arg8, _arg8Name, _arg9, _arg9Name, _arg10, _arg10Name, _arg11, _arg11Name, _arg12, _arg12Name ) \
  246. DEFINE_EVENT12( _eventName, _arg1, _arg2, _arg3, _arg4, _arg5, _arg6, _arg7, _arg8, _arg9, _arg10, _arg11, _arg12 )
  247. #define DEFINE_EVENT13_WITHNAMES( _eventName, _arg1, _arg1Name, _arg2, _arg2Name, _arg3, _arg3Name, _arg4, _arg4Name, _arg5, _arg5Name, _arg6, _arg6Name, _arg7, _arg7Name, _arg8, _arg8Name, _arg9, _arg9Name, _arg10, _arg10Name, _arg11, _arg11Name, _arg12, _arg12Name, _arg13, _arg13Name ) \
  248. DEFINE_EVENT13( _eventName, _arg1, _arg2, _arg3, _arg4, _arg5, _arg6, _arg7, _arg8, _arg9, _arg10, _arg11, _arg12, _arg13 )
  249. #define DEFINE_EVENT14_WITHNAMES( _eventName, _arg1, _arg1Name, _arg2, _arg2Name, _arg3, _arg3Name, _arg4, _arg4Name, _arg5, _arg5Name, _arg6, _arg6Name, _arg7, _arg7Name, _arg8, _arg8Name, _arg9, _arg9Name, _arg10, _arg10Name, _arg11, _arg11Name, _arg12, _arg12Name, _arg13, _arg13Name, _arg14, _arg14Name ) \
  250. DEFINE_EVENT14( _eventName, _arg1, _arg2, _arg3, _arg4, _arg5, _arg6, _arg7, _arg8, _arg9, _arg10, _arg11, _arg12, _arg13, _arg14 )
  251. #endif // IEVENTSYSTEM_H