Team Fortress 2 Source Code as on 22/4/2020
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.

384 lines
12 KiB

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