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.

430 lines
13 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================//
  6. #include <stdio.h>
  7. #include "ienginevgui.h"
  8. #include "vguisystemmoduleloader.h"
  9. #include "sys_utils.h"
  10. #include "IVguiModule.h"
  11. #include "ServerBrowser/IServerBrowser.h"
  12. #include <vgui/IPanel.h>
  13. #include <vgui/ISystem.h>
  14. #include <vgui/IVGui.h>
  15. #include <vgui/ILocalize.h>
  16. #include <keyvalues.h>
  17. #include <vgui_controls/Controls.h>
  18. #include <vgui_controls/Panel.h>
  19. #include "filesystem.h"
  20. // memdbgon must be the last include file in a .cpp file!!!
  21. #include "tier0/memdbgon.h"
  22. // instance of class
  23. CVGuiSystemModuleLoader g_VModuleLoader;
  24. #ifdef GAMEUI_EXPORTS
  25. extern vgui::VPANEL GetGameUIBasePanel();
  26. #else
  27. #include "../SteamUI/PlatformMainPanel.h"
  28. extern CPlatformMainPanel *g_pMainPanel;
  29. #endif
  30. bool bSteamCommunityFriendsVersion = false;
  31. #include <tier0/dbg.h>
  32. // memdbgon must be the last include file in a .cpp file!!!
  33. #include <tier0/memdbgon.h>
  34. EXPOSE_SINGLE_INTERFACE_GLOBALVAR(CVGuiSystemModuleLoader, IVGuiModuleLoader, VGUIMODULELOADER_INTERFACE_VERSION, g_VModuleLoader);
  35. //-----------------------------------------------------------------------------
  36. // Purpose: Constructor
  37. //-----------------------------------------------------------------------------
  38. CVGuiSystemModuleLoader::CVGuiSystemModuleLoader()
  39. {
  40. m_bModulesInitialized = false;
  41. m_bPlatformShouldRestartAfterExit = false;
  42. m_pPlatformModuleData = NULL;
  43. }
  44. //-----------------------------------------------------------------------------
  45. // Purpose: Destructor
  46. //-----------------------------------------------------------------------------
  47. CVGuiSystemModuleLoader::~CVGuiSystemModuleLoader()
  48. {
  49. }
  50. //-----------------------------------------------------------------------------
  51. // Purpose: returns true if the module loader has acquired the platform mutex and loaded the modules
  52. //-----------------------------------------------------------------------------
  53. bool CVGuiSystemModuleLoader::IsPlatformReady()
  54. {
  55. return m_bModulesInitialized;
  56. }
  57. //-----------------------------------------------------------------------------
  58. // Purpose: sets up all the modules for use
  59. //-----------------------------------------------------------------------------
  60. bool CVGuiSystemModuleLoader::InitializeAllModules(CreateInterfaceFn *factorylist, int factorycount)
  61. {
  62. if ( IsGameConsole() )
  63. {
  64. // not valid for 360
  65. return false;
  66. }
  67. bool bSuccess = true;
  68. // Init vgui in the modules
  69. int i;
  70. for ( i = 0; i < m_Modules.Count(); i++ )
  71. {
  72. if (!m_Modules[i].moduleInterface->Initialize(factorylist, factorycount))
  73. {
  74. bSuccess = false;
  75. Error("Platform Error: module failed to initialize\n");
  76. }
  77. }
  78. // create a table of all the loaded modules
  79. CreateInterfaceFn *moduleFactories = (CreateInterfaceFn *)_alloca(sizeof(CreateInterfaceFn) * m_Modules.Count());
  80. for ( i = 0; i < m_Modules.Count(); i++ )
  81. {
  82. moduleFactories[i] = Sys_GetFactory(m_Modules[i].module);
  83. }
  84. // give the modules a chance to link themselves together
  85. for (i = 0; i < m_Modules.Count(); i++)
  86. {
  87. if (!m_Modules[i].moduleInterface->PostInitialize(moduleFactories, m_Modules.Count()))
  88. {
  89. bSuccess = false;
  90. Error("Platform Error: module failed to initialize\n");
  91. }
  92. #ifdef GAMEUI_EXPORTS
  93. vgui::VPANEL rootpanel = enginevgui->GetPanel( PANEL_GAMEUIDLL );
  94. m_Modules[i].moduleInterface->SetParent( rootpanel );
  95. #else
  96. m_Modules[i].moduleInterface->SetParent(g_pMainPanel->GetVPanel());
  97. #endif
  98. }
  99. m_bModulesInitialized = true;
  100. return bSuccess;
  101. }
  102. //-----------------------------------------------------------------------------
  103. // Purpose: Loads and initializes all the modules specified in the platform file
  104. //-----------------------------------------------------------------------------
  105. bool CVGuiSystemModuleLoader::LoadPlatformModules(CreateInterfaceFn *factorylist, int factorycount, bool useSteamModules)
  106. {
  107. #ifdef DEDICATED
  108. return false;
  109. #endif
  110. if ( IsGameConsole() )
  111. {
  112. // not valid for 360
  113. return false;
  114. }
  115. bool bSuccess = true;
  116. // load platform menu
  117. KeyValues *kv = new KeyValues("Platform");
  118. if (!kv->LoadFromFile(g_pFullFileSystem, "steam/games/PlatformMenu.vdf", "PLATFORM"))
  119. {
  120. kv->deleteThis();
  121. return false;
  122. }
  123. // walk the platform menu loading all the interfaces
  124. KeyValues *menuKeys = kv->FindKey("Menu", true);
  125. for (KeyValues *it = menuKeys->GetFirstSubKey(); it != NULL; it = it->GetNextKey())
  126. {
  127. // see if we should skip steam modules
  128. if (!useSteamModules && it->GetInt("SteamApp"))
  129. continue;
  130. const char *pchInterface = it->GetString("interface");
  131. // don't load friends if we are using Steam Community
  132. if ( !Q_stricmp( pchInterface, "VGuiModuleTracker001" ) && bSteamCommunityFriendsVersion )
  133. continue;
  134. // get copy out of steam cache
  135. const char *dllPath = NULL;
  136. if ( IsOSX() )
  137. {
  138. dllPath = it->GetString("dll_osx");
  139. }
  140. else if ( IsLinux() )
  141. {
  142. dllPath = it->GetString("dll_linux");
  143. }
  144. else
  145. {
  146. dllPath = it->GetString("dll");
  147. }
  148. // load the module (LoadModule calls GetLocalCopy() under steam)
  149. printf("****loading %s\n", dllPath);
  150. CSysModule *mod = g_pFullFileSystem->LoadModule(dllPath, "EXECUTABLE_PATH");
  151. if (!mod)
  152. {
  153. Error("Platform Error: bad module '%s', not loading\n", it->GetString("dll"));
  154. bSuccess = false;
  155. continue;
  156. }
  157. // make sure we get the right version
  158. IVGuiModule *moduleInterface = (IVGuiModule *)Sys_GetFactory(mod)(pchInterface, NULL);
  159. if (!moduleInterface)
  160. {
  161. Warning("Platform Error: module version ('%s, %s) invalid, not loading\n", it->GetString("dll"), it->GetString("interface"));
  162. bSuccess = false;
  163. continue;
  164. }
  165. // store off the module
  166. int newIndex = m_Modules.AddToTail();
  167. m_Modules[newIndex].module = mod;
  168. m_Modules[newIndex].moduleInterface = moduleInterface;
  169. m_Modules[newIndex].data = it;
  170. }
  171. m_pPlatformModuleData = kv;
  172. return InitializeAllModules(factorylist, factorycount) && bSuccess;
  173. }
  174. //-----------------------------------------------------------------------------
  175. // Purpose: gives all platform modules a chance to Shutdown gracefully
  176. //-----------------------------------------------------------------------------
  177. void CVGuiSystemModuleLoader::ShutdownPlatformModules()
  178. {
  179. if ( IsGameConsole() )
  180. {
  181. // not valid for 360
  182. return;
  183. }
  184. // static include guard to prevent recursive calls
  185. static bool runningFunction = false;
  186. if (runningFunction)
  187. return;
  188. runningFunction = true;
  189. // deactivate all the modules first
  190. DeactivatePlatformModules();
  191. // give all the modules notice of quit
  192. int i;
  193. for ( i = 0; i < m_Modules.Count(); i++ )
  194. {
  195. vgui::ivgui()->PostMessage(m_Modules[i].moduleInterface->GetPanel(), new KeyValues("Command", "command", "Quit"), NULL);
  196. }
  197. for ( i = 0; i < m_Modules.Count(); i++ )
  198. {
  199. m_Modules[i].moduleInterface->Shutdown();
  200. }
  201. runningFunction = false;
  202. }
  203. //-----------------------------------------------------------------------------
  204. // Purpose: Deactivates all the modules (puts them into in inactive but recoverable state)
  205. //-----------------------------------------------------------------------------
  206. void CVGuiSystemModuleLoader::DeactivatePlatformModules()
  207. {
  208. for (int i = 0; i < m_Modules.Count(); i++)
  209. {
  210. m_Modules[i].moduleInterface->Deactivate();
  211. }
  212. }
  213. //-----------------------------------------------------------------------------
  214. // Purpose: Reenables all the deactivated platform modules
  215. //-----------------------------------------------------------------------------
  216. void CVGuiSystemModuleLoader::ReactivatePlatformModules()
  217. {
  218. for (int i = 0; i < m_Modules.Count(); i++)
  219. {
  220. m_Modules[i].moduleInterface->Reactivate();
  221. }
  222. }
  223. //-----------------------------------------------------------------------------
  224. // Purpose: Disables and unloads platform
  225. //-----------------------------------------------------------------------------
  226. void CVGuiSystemModuleLoader::UnloadPlatformModules()
  227. {
  228. for (int i = 0; i < m_Modules.Count(); i++)
  229. {
  230. g_pFullFileSystem->UnloadModule(m_Modules[i].module);
  231. }
  232. m_Modules.RemoveAll();
  233. if (m_pPlatformModuleData)
  234. {
  235. m_pPlatformModuleData->deleteThis();
  236. m_pPlatformModuleData = NULL;
  237. }
  238. }
  239. //-----------------------------------------------------------------------------
  240. // Purpose: Called every frame
  241. //-----------------------------------------------------------------------------
  242. void CVGuiSystemModuleLoader::RunFrame()
  243. {
  244. }
  245. //-----------------------------------------------------------------------------
  246. // Purpose: returns number of modules loaded
  247. //-----------------------------------------------------------------------------
  248. int CVGuiSystemModuleLoader::GetModuleCount()
  249. {
  250. return m_Modules.Count();
  251. }
  252. //-----------------------------------------------------------------------------
  253. // Purpose: returns the string menu name (unlocalized) of a module
  254. // moduleIndex is of the range [0, GetModuleCount())
  255. //-----------------------------------------------------------------------------
  256. const char *CVGuiSystemModuleLoader::GetModuleLabel(int moduleIndex)
  257. {
  258. return m_Modules[moduleIndex].data->GetString("MenuName", "< unknown >");
  259. }
  260. //-----------------------------------------------------------------------------
  261. // Purpose:
  262. //-----------------------------------------------------------------------------
  263. bool CVGuiSystemModuleLoader::IsModuleVisible(int moduleIndex)
  264. {
  265. return vgui::ipanel()->IsVisible( m_Modules[moduleIndex].moduleInterface->GetPanel() );
  266. }
  267. //-----------------------------------------------------------------------------
  268. // Purpose: brings the specified module to the foreground
  269. //-----------------------------------------------------------------------------
  270. bool CVGuiSystemModuleLoader::IsModuleHidden(int moduleIndex)
  271. {
  272. return m_Modules[moduleIndex].data->GetBool("Hidden", false);
  273. }
  274. //-----------------------------------------------------------------------------
  275. // Purpose: brings the specified module to the foreground
  276. //-----------------------------------------------------------------------------
  277. bool CVGuiSystemModuleLoader::ActivateModule(int moduleIndex)
  278. {
  279. if (!m_Modules.IsValidIndex(moduleIndex))
  280. return false;
  281. m_Modules[moduleIndex].moduleInterface->Activate();
  282. return true;
  283. }
  284. //-----------------------------------------------------------------------------
  285. // Purpose: look up a module by name
  286. //-----------------------------------------------------------------------------
  287. int CVGuiSystemModuleLoader::GetModuleIndexFromName( const char* moduleName )
  288. {
  289. int result = -1;
  290. for ( int i = 0; i < GetModuleCount(); i++ )
  291. {
  292. if ( !stricmp( GetModuleLabel( i ), moduleName ) || !stricmp( m_Modules[i].data->GetName(), moduleName ) )
  293. {
  294. result = i;
  295. break;
  296. }
  297. }
  298. return result;
  299. }
  300. //-----------------------------------------------------------------------------
  301. // Purpose: activates a module by name
  302. //-----------------------------------------------------------------------------
  303. bool CVGuiSystemModuleLoader::ActivateModule( const char *moduleName )
  304. {
  305. // ActivateModule checks the validity of the index, so it will
  306. // work correctly even if moduleName is not a valid module
  307. return ActivateModule( GetModuleIndexFromName( moduleName ) );
  308. }
  309. //-----------------------------------------------------------------------------
  310. // Purpose: returns a modules interface factory
  311. //-----------------------------------------------------------------------------
  312. CreateInterfaceFn CVGuiSystemModuleLoader::GetModuleFactory(int moduleIndex)
  313. {
  314. return Sys_GetFactory(m_Modules[moduleIndex].module);
  315. }
  316. //-----------------------------------------------------------------------------
  317. // Purpose:
  318. //-----------------------------------------------------------------------------
  319. void CVGuiSystemModuleLoader::PostMessageToAllModules(KeyValues *message)
  320. {
  321. for (int i = 0; i < m_Modules.Count(); i++)
  322. {
  323. vgui::ivgui()->PostMessage(m_Modules[i].moduleInterface->GetPanel(), message->MakeCopy(), NULL);
  324. }
  325. message->deleteThis();
  326. }
  327. //-----------------------------------------------------------------------------
  328. // Purpose: Post a message to a particular module
  329. //-----------------------------------------------------------------------------
  330. // posts a message to a single module
  331. bool CVGuiSystemModuleLoader::PostMessageToModule( int moduleIndex, KeyValues *message )
  332. {
  333. if ( !m_Modules.IsValidIndex( moduleIndex ) )
  334. return false;
  335. vgui::ivgui()->PostMessage( m_Modules[moduleIndex].moduleInterface->GetPanel(), message->MakeCopy(), NULL );
  336. return true;
  337. }
  338. bool CVGuiSystemModuleLoader::PostMessageToModule( const char *moduleName, KeyValues *message )
  339. {
  340. // ActivateModule checks the validity of the index, so it will
  341. // work correctly even if moduleName is not a valid module
  342. return PostMessageToModule( GetModuleIndexFromName( moduleName ), message );
  343. }
  344. //-----------------------------------------------------------------------------
  345. // Purpose: sets the the platform should update and restart when it quits
  346. //-----------------------------------------------------------------------------
  347. void CVGuiSystemModuleLoader::SetPlatformToRestart()
  348. {
  349. m_bPlatformShouldRestartAfterExit = true;
  350. }
  351. //-----------------------------------------------------------------------------
  352. // Purpose: data accessor
  353. //-----------------------------------------------------------------------------
  354. bool CVGuiSystemModuleLoader::ShouldPlatformRestart()
  355. {
  356. return m_bPlatformShouldRestartAfterExit;
  357. }