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.

252 lines
9.4 KiB

  1. //=========== (C) Copyright Valve, L.L.C. All rights reserved. ===========
  2. #ifndef UI_NUGGET_H
  3. #define UI_NUGGET_H
  4. #include "game_controls/igameuisystemmgr.h"
  5. #include "matchmaking/imatchframework.h"
  6. #include "fmtstr.h"
  7. #include "utlstringmap.h"
  8. class CUiNuggetBase;
  9. class CUiNuggetReference;
  10. class CUiNuggetFactoryRegistrarBase;
  11. class CUiNuggetFactoryRegistrarBaseInstances;
  12. class CUiNuggetFactoryRegistrarBaseSingleton;
  13. //////////////////////////////////////////////////////////////////////////
  14. //
  15. // Base class for implementing UI nuggets
  16. //
  17. class CUiNuggetBase : public IGameUIScreenController
  18. {
  19. public:
  20. CUiNuggetBase();
  21. virtual ~CUiNuggetBase();
  22. // IGameUIScreenController
  23. public:
  24. // Connects a screen to the controller, returns number of
  25. // remaining connected screens (or 1 for the first connection)
  26. virtual int OnScreenConnected( IGameUISystem *pScreenView );
  27. // Releases the screen from controller, returns number of
  28. // remaining connected screens (returns 0 if no screens are
  29. // connected - new object must be reacquired from factory
  30. // in this case)
  31. virtual int OnScreenDisconnected( IGameUISystem *pScreenView );
  32. // Callback for screen events handling
  33. virtual KeyValues * OnScreenEvent( IGameUISystem *pScreenView, KeyValues *kvEvent );
  34. // Broadcast an event to all connected screens (caller retains ownership of keyvalues)
  35. virtual void BroadcastEventToScreens( KeyValues *kvEvent );
  36. public:
  37. // Add a reference to the nugget to be notified upon release
  38. virtual void AddReferenceSink( CUiNuggetReference *pSink ) { m_arrReferences.AddToTail( pSink ); }
  39. protected:
  40. // Policy for whether the object should be deleted when no screen references remain
  41. virtual bool ShouldDeleteOnLastScreenDisconnect() { return true; }
  42. protected:
  43. struct ConnectionInfo_t
  44. {
  45. IGameUISystem *m_pScreen;
  46. int m_nRefCount;
  47. explicit ConnectionInfo_t( IGameUISystem *pScreen = NULL ) : m_pScreen( pScreen ), m_nRefCount( 0 ) {}
  48. bool operator == ( ConnectionInfo_t const &other ) const { return m_pScreen == other.m_pScreen; }
  49. };
  50. typedef CUtlVector< ConnectionInfo_t > ConnectedScreens;
  51. ConnectedScreens m_arrConnectedScreens;
  52. CUtlVector< int > m_arrEventsDisabledScreenHandles;
  53. KeyValues *m_pUiNuggetData;
  54. KeyValues::AutoDelete m_autodelete_m_pUiNuggetData;
  55. private:
  56. CUtlVector< int * > m_arrBroadcastEventIdxArray;
  57. CUtlVector< CUiNuggetReference * > m_arrReferences;
  58. };
  59. //////////////////////////////////////////////////////////////////////////
  60. //
  61. // Declaration of UI nuggets factories
  62. //
  63. class CUiNuggetFactoryRegistrarBase : public IGameUIScreenControllerFactory
  64. {
  65. public:
  66. CUiNuggetFactoryRegistrarBase();
  67. ~CUiNuggetFactoryRegistrarBase();
  68. virtual void Register();
  69. virtual char const *GetName() = 0;
  70. public:
  71. static void RegisterAll();
  72. private:
  73. CUiNuggetFactoryRegistrarBase *m_pPrev, *m_pNext;
  74. };
  75. class CUiNuggetFactoryRegistrarBaseGlobalInstance : public CUiNuggetFactoryRegistrarBase
  76. {
  77. public:
  78. // Returns an instance of a controller interface
  79. virtual IGameUIScreenController * GetController( KeyValues *kvRequest ) = 0;
  80. // Access controller instances
  81. virtual int GetControllerInstancesCount() { return 1; }
  82. virtual IGameUIScreenController * GetControllerInstance( int iIndex ) = 0;
  83. };
  84. class CUiNuggetFactoryRegistrarBaseSingleton : public CUiNuggetFactoryRegistrarBase
  85. {
  86. friend class CUiNuggetFactoryRegistrarBaseSingletonReferenceTracker;
  87. public:
  88. CUiNuggetFactoryRegistrarBaseSingleton();
  89. public:
  90. // Returns an instance of a controller interface
  91. virtual IGameUIScreenController * GetController( KeyValues *kvRequest );
  92. // Access controller instances
  93. virtual int GetControllerInstancesCount() { return !!m_pSingleton; }
  94. virtual IGameUIScreenController * GetControllerInstance( int iIndex ) { return m_pSingleton; }
  95. public:
  96. // Creates an instance of a controller interface
  97. virtual CUiNuggetBase * CreateNewController() = 0;
  98. protected:
  99. CUiNuggetBase *m_pSingleton;
  100. };
  101. class CUiNuggetFactoryRegistrarBaseInstances : public CUiNuggetFactoryRegistrarBase
  102. {
  103. friend class CUiNuggetFactoryRegistrarBaseInstancesReferenceTracker;
  104. public:
  105. // Returns an instance of a controller interface
  106. virtual IGameUIScreenController * GetController( KeyValues *kvRequest );
  107. // Access controller instances
  108. virtual int GetControllerInstancesCount() { return m_arrInstances.Count(); }
  109. virtual IGameUIScreenController * GetControllerInstance( int iIndex ) { return m_arrInstances.IsValidIndex( iIndex ) ? m_arrInstances[iIndex] : NULL; }
  110. public:
  111. // Creates an instance of a controller interface
  112. virtual CUiNuggetBase * CreateNewController() = 0;
  113. protected:
  114. // Nugget instances
  115. CUtlVector< CUiNuggetBase * > m_arrInstances;
  116. };
  117. //////////////////////////////////////////////////////////////////////////
  118. //
  119. // Macros to be used to declare UI nuggets factories
  120. //
  121. // Global instance factory - a nugget instance always exists in a global variable
  122. // and is always shared with all screens.
  123. #define UI_NUGGET_FACTORY_GLOBAL_INSTANCE( nuggetclassname, instanceptr, scriptname ) \
  124. namespace { \
  125. class Factory_##nuggetclassname##_Class : public CUiNuggetFactoryRegistrarBaseGlobalInstance \
  126. { \
  127. virtual IGameUIScreenController * GetController( KeyValues *kvRequest ) { return static_cast< nuggetclassname * >( instanceptr ); } \
  128. virtual IGameUIScreenController * GetControllerInstance( int iIndex ) { return static_cast< nuggetclassname * >( instanceptr ); } \
  129. virtual char const * GetName() { return scriptname; } \
  130. } \
  131. g_factory_##nuggetclassname##_globalinstance; \
  132. };
  133. // Singleton factory - create a new nugget instance and share it with all screens
  134. // until all references to the nugget are released and nugget is destroyed.
  135. // If nugget policy is not deleting the nugget upon last release, then a single nugget
  136. // instance will be created once and shared with all screens.
  137. #define UI_NUGGET_FACTORY_SINGLETON( nuggetclassname, scriptname ) \
  138. namespace { \
  139. class Factory_##nuggetclassname##_Class : public CUiNuggetFactoryRegistrarBaseSingleton \
  140. { \
  141. virtual CUiNuggetBase * CreateNewController() { return new nuggetclassname; } \
  142. virtual char const * GetName() { return scriptname; } \
  143. } \
  144. g_factory_##nuggetclassname##_singleton; \
  145. };
  146. // Instances factory - create a new nugget instance per each request.
  147. // Screens need to implement own methods of sharing data from a single nugget
  148. // instance. Nugget instance must be marked for delete upon last release.
  149. #define UI_NUGGET_FACTORY_INSTANCES( nuggetclassname, scriptname ) \
  150. namespace { \
  151. class Factory_##nuggetclassname##_Class : public CUiNuggetFactoryRegistrarBaseInstances \
  152. { \
  153. virtual CUiNuggetBase * CreateNewController() { return new nuggetclassname; } \
  154. virtual char const * GetName() { return scriptname; } \
  155. } \
  156. g_factory_##nuggetclassname##_instances; \
  157. };
  158. //////////////////////////////////////////////////////////////////////////
  159. //
  160. // Macros to be used to declare nuggets functions
  161. //
  162. #define DECLARE_NUGGET_FN_MAP( classname, baseclass ) \
  163. typedef classname NuggetEventMapClass; \
  164. typedef baseclass NuggetEventMapBaseClass; \
  165. class NuggetEventMap : \
  166. public CUtlStringMap< KeyValues * (classname::*)( IGameUISystem *pScreenView, KeyValues *args ) > \
  167. {} \
  168. m_NuggetEventMap; \
  169. class NuggetPreBroadcastMap : \
  170. public CUtlStringMap< bool (classname::*)( KeyValues *args ) > \
  171. {} \
  172. m_NuggetPreBroadcastMap; \
  173. virtual KeyValues * OnScreenEvent( IGameUISystem *pScreenView, KeyValues *args ) { \
  174. char const *szEvent = args->GetName(); \
  175. UtlSymId_t sym = m_NuggetEventMap.Find( szEvent ); \
  176. if ( sym != m_NuggetEventMap.InvalidIndex() ) { \
  177. return (this->* (m_NuggetEventMap[sym]) )( pScreenView, args ); \
  178. } \
  179. return NuggetEventMapBaseClass::OnScreenEvent( pScreenView, args ); \
  180. } \
  181. virtual void BroadcastEventToScreens( KeyValues *args ) { \
  182. char const *szEvent = args->GetName(); \
  183. UtlSymId_t sym = m_NuggetPreBroadcastMap.Find( szEvent ); \
  184. if ( sym != m_NuggetPreBroadcastMap.InvalidIndex() ) { \
  185. if ( ! (this->* (m_NuggetPreBroadcastMap[sym]) )( args ) ) return; \
  186. } \
  187. return NuggetEventMapBaseClass::BroadcastEventToScreens( args ); \
  188. }
  189. #define NUGGET_FN( eventname ) \
  190. class eventname##_EventRegistrar { \
  191. public: typedef eventname##_EventRegistrar ThisClass; \
  192. eventname##_EventRegistrar() { \
  193. NuggetEventMapClass *pNugget = reinterpret_cast< NuggetEventMapClass * >( reinterpret_cast< size_t >( this ) - offsetof( NuggetEventMapClass, m_##eventname##_EventRegistrar ) ); \
  194. pNugget->m_NuggetEventMap[ #eventname ] = &NuggetEventMapClass::Event_##eventname; \
  195. COMPILE_TIME_ASSERT( offsetof( NuggetEventMapClass, m_##eventname##_EventRegistrar ) > offsetof( NuggetEventMapClass, m_NuggetEventMap ) ); \
  196. } } m_##eventname##_EventRegistrar; \
  197. KeyValues * Event_##eventname( IGameUISystem *pScreenView, KeyValues *args )
  198. #define NUGGET_BROADCAST_FN( eventname ) \
  199. class eventname##_BroadcastRegistrar { \
  200. public: typedef eventname##_BroadcastRegistrar ThisClass; \
  201. eventname##_BroadcastRegistrar() { \
  202. NuggetEventMapClass *pNugget = reinterpret_cast< NuggetEventMapClass * >( reinterpret_cast< size_t >( this ) - offsetof( NuggetEventMapClass, m_##eventname##_BroadcastRegistrar ) ); \
  203. pNugget->m_NuggetPreBroadcastMap[ #eventname ] = &NuggetEventMapClass::Broadcast_##eventname; \
  204. COMPILE_TIME_ASSERT( offsetof( NuggetEventMapClass, m_##eventname##_BroadcastRegistrar ) > offsetof( NuggetEventMapClass, m_NuggetPreBroadcastMap ) ); \
  205. } } m_##eventname##_BroadcastRegistrar; \
  206. bool Broadcast_##eventname( KeyValues *args )
  207. #endif // UI_NUGGET_H