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.

275 lines
6.9 KiB

  1. //=========== (C) Copyright Valve, L.L.C. All rights reserved. ===========
  2. #include "cbase.h"
  3. #include "ui_nugget.h"
  4. #include "vstdlib/ikeyvaluessystem.h"
  5. //////////////////////////////////////////////////////////////////////////
  6. //
  7. // CUiNuggetReference implementation
  8. //
  9. class CUiNuggetReference
  10. {
  11. public:
  12. virtual void OnNuggetReleased( CUiNuggetBase *pNugget ) = 0;
  13. };
  14. //////////////////////////////////////////////////////////////////////////
  15. //
  16. // CUiNuggetBase implementation
  17. //
  18. CUiNuggetBase::CUiNuggetBase() :
  19. m_pUiNuggetData( new KeyValues( "" ) ),
  20. m_autodelete_m_pUiNuggetData( m_pUiNuggetData )
  21. {
  22. }
  23. CUiNuggetBase::~CUiNuggetBase()
  24. {
  25. while ( m_arrReferences.Count() )
  26. {
  27. CUiNuggetReference *pSink = m_arrReferences.Head();
  28. m_arrReferences.RemoveMultipleFromHead( 1 );
  29. pSink->OnNuggetReleased( this );
  30. }
  31. }
  32. int CUiNuggetBase::OnScreenConnected( IGameUISystem *pScreenView )
  33. {
  34. ConnectionInfo_t ci( pScreenView );
  35. int idx = m_arrConnectedScreens.Find( ci );
  36. if ( idx != m_arrConnectedScreens.InvalidIndex() )
  37. {
  38. ++ m_arrConnectedScreens[idx].m_nRefCount;
  39. }
  40. else
  41. {
  42. ci.m_nRefCount = 1;
  43. m_arrConnectedScreens.AddToTail( ci );
  44. }
  45. return m_arrConnectedScreens.Count();
  46. }
  47. int CUiNuggetBase::OnScreenDisconnected( IGameUISystem *pScreenView )
  48. {
  49. ConnectionInfo_t ci( pScreenView );
  50. int idx = m_arrConnectedScreens.Find( ci );
  51. if ( idx != m_arrConnectedScreens.InvalidIndex() )
  52. {
  53. if ( -- m_arrConnectedScreens[idx].m_nRefCount )
  54. return m_arrConnectedScreens.Count();
  55. // Otherwise this screen must be released
  56. m_arrConnectedScreens.Remove( idx );
  57. // Assert that screen is not disconnecting in the middle of
  58. // event broadcast (otherwise need to implement index adjustment
  59. // so that broadcast could succeed)
  60. Assert( !m_arrBroadcastEventIdxArray.Count() );
  61. // Check if we need to delete us
  62. int numRemaining = m_arrConnectedScreens.Count();
  63. if ( !numRemaining && ShouldDeleteOnLastScreenDisconnect() )
  64. {
  65. delete this;
  66. }
  67. return numRemaining;
  68. }
  69. else
  70. {
  71. Warning( "CUiNuggetBase::OnScreenDisconnected %p for not connected screen!\n", pScreenView );
  72. Assert( !"OnScreenDisconnected" );
  73. return m_arrConnectedScreens.Count();
  74. }
  75. }
  76. KeyValues * CUiNuggetBase::OnScreenEvent( IGameUISystem *pScreenView, KeyValues *kvEvent )
  77. {
  78. int nEvent = kvEvent->GetNameSymbol();
  79. static int const s_nGetData = KeyValuesSystem()->GetSymbolForString( "GetData" );
  80. if ( nEvent == s_nGetData )
  81. {
  82. return m_pUiNuggetData->MakeCopy();
  83. }
  84. static int const s_nEnableEvents = KeyValuesSystem()->GetSymbolForString( "EnableEvents" );
  85. if ( nEvent == s_nEnableEvents )
  86. {
  87. int nScriptHandle = kvEvent->GetInt( "scripthandle" );
  88. bool bEnabled = kvEvent->GetBool( "enable", true );
  89. m_arrEventsDisabledScreenHandles.FindAndFastRemove( nScriptHandle );
  90. if ( !bEnabled )
  91. m_arrEventsDisabledScreenHandles.AddToTail( nScriptHandle );
  92. return NULL;
  93. }
  94. DevWarning( "CUiNuggetBase(%p)::OnScreenEvent for unknown command %s!\n", this, kvEvent->GetName() );
  95. return NULL;
  96. }
  97. void CUiNuggetBase::BroadcastEventToScreens( KeyValues *kvEvent )
  98. {
  99. int idx = 0;
  100. m_arrBroadcastEventIdxArray.AddToTail( &idx );
  101. for ( ; idx < m_arrConnectedScreens.Count(); ++ idx )
  102. {
  103. IGameUISystem *pUI = m_arrConnectedScreens[idx].m_pScreen;
  104. int iScriptHandle = pUI->GetScriptHandle();
  105. if ( m_arrEventsDisabledScreenHandles.Find( iScriptHandle ) != m_arrEventsDisabledScreenHandles.InvalidIndex() )
  106. continue;
  107. pUI->ExecuteScript( kvEvent );
  108. }
  109. m_arrBroadcastEventIdxArray.RemoveMultipleFromTail( 1 );
  110. }
  111. //////////////////////////////////////////////////////////////////////////
  112. //
  113. // CUiNuggetFactoryRegistrarBase implementation
  114. //
  115. static CUiNuggetFactoryRegistrarBase *g_pUiNuggetFactoriesCircularList = NULL;
  116. CUiNuggetFactoryRegistrarBase::CUiNuggetFactoryRegistrarBase()
  117. {
  118. // Add us to list
  119. CUiNuggetFactoryRegistrarBase *pLeft = this;
  120. CUiNuggetFactoryRegistrarBase *pRight = this;
  121. if ( g_pUiNuggetFactoriesCircularList )
  122. {
  123. pLeft = g_pUiNuggetFactoriesCircularList;
  124. pRight = g_pUiNuggetFactoriesCircularList->m_pNext;
  125. pLeft->m_pNext = this;
  126. pRight->m_pPrev = this;
  127. }
  128. g_pUiNuggetFactoriesCircularList = this;
  129. m_pNext = pRight;
  130. m_pPrev = pLeft;
  131. }
  132. CUiNuggetFactoryRegistrarBase::~CUiNuggetFactoryRegistrarBase()
  133. {
  134. // Remove us from list
  135. if ( m_pPrev == this || m_pNext == this )
  136. {
  137. Assert( m_pPrev == this && m_pNext == this && g_pUiNuggetFactoriesCircularList == this );
  138. g_pUiNuggetFactoriesCircularList = NULL;
  139. }
  140. else
  141. {
  142. m_pPrev->m_pNext = m_pNext;
  143. m_pNext->m_pPrev = m_pPrev;
  144. if ( g_pUiNuggetFactoriesCircularList == this )
  145. g_pUiNuggetFactoriesCircularList = m_pPrev;
  146. }
  147. }
  148. void CUiNuggetFactoryRegistrarBase::Register()
  149. {
  150. Assert( g_pGameUISystemMgr );
  151. g_pGameUISystemMgr->RegisterScreenControllerFactory( GetName(), this );
  152. }
  153. void CUiNuggetFactoryRegistrarBase::RegisterAll()
  154. {
  155. CUiNuggetFactoryRegistrarBase *p = g_pUiNuggetFactoriesCircularList;
  156. if ( !p )
  157. return;
  158. do
  159. {
  160. p->Register();
  161. p = p->m_pNext;
  162. }
  163. while ( p != g_pUiNuggetFactoriesCircularList );
  164. }
  165. //////////////////////////////////////////////////////////////////////////
  166. //
  167. // factories implementation
  168. //
  169. CUiNuggetFactoryRegistrarBaseSingleton::CUiNuggetFactoryRegistrarBaseSingleton() :
  170. m_pSingleton( NULL )
  171. {
  172. }
  173. class CUiNuggetFactoryRegistrarBaseSingletonReferenceTracker : public CUiNuggetReference
  174. {
  175. public:
  176. CUiNuggetFactoryRegistrarBaseSingletonReferenceTracker( CUiNuggetBase *pNugget, CUiNuggetFactoryRegistrarBaseSingleton *pFactory )
  177. {
  178. m_pFactory = pFactory;
  179. m_pFactory->m_pSingleton = pNugget;
  180. pNugget->AddReferenceSink( this );
  181. }
  182. private:
  183. virtual void OnNuggetReleased( CUiNuggetBase *pNugget )
  184. {
  185. m_pFactory->m_pSingleton = NULL;
  186. delete this;
  187. }
  188. private:
  189. CUiNuggetFactoryRegistrarBaseSingleton *m_pFactory;
  190. };
  191. IGameUIScreenController * CUiNuggetFactoryRegistrarBaseSingleton::GetController( KeyValues *kvRequest )
  192. {
  193. if ( Q_stricmp( GetName(), kvRequest->GetName() ) )
  194. return NULL;
  195. if ( !m_pSingleton )
  196. {
  197. m_pSingleton = CreateNewController();
  198. new CUiNuggetFactoryRegistrarBaseSingletonReferenceTracker( m_pSingleton, this );
  199. }
  200. return m_pSingleton;
  201. }
  202. class CUiNuggetFactoryRegistrarBaseInstancesReferenceTracker : public CUiNuggetReference
  203. {
  204. public:
  205. CUiNuggetFactoryRegistrarBaseInstancesReferenceTracker( CUiNuggetBase *pNugget, CUiNuggetFactoryRegistrarBaseInstances *pFactory )
  206. {
  207. m_pFactory = pFactory;
  208. m_pFactory->m_arrInstances.AddToTail( pNugget );
  209. pNugget->AddReferenceSink( this );
  210. }
  211. private:
  212. virtual void OnNuggetReleased( CUiNuggetBase *pNugget )
  213. {
  214. m_pFactory->m_arrInstances.FindAndRemove( pNugget );
  215. delete this;
  216. }
  217. private:
  218. CUiNuggetFactoryRegistrarBaseInstances *m_pFactory;
  219. };
  220. IGameUIScreenController * CUiNuggetFactoryRegistrarBaseInstances::GetController( KeyValues *kvRequest )
  221. {
  222. if ( Q_stricmp( GetName(), kvRequest->GetName() ) )
  223. return NULL;
  224. CUiNuggetBase *pInstance = CreateNewController();
  225. if ( !pInstance )
  226. return NULL;
  227. new CUiNuggetFactoryRegistrarBaseInstancesReferenceTracker( pInstance, this );
  228. return pInstance;
  229. }