SubsystemInterface.cpp 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. /*
  2. ** Command & Conquer Generals(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. ////////////////////////////////////////////////////////////////////////////////
  19. // //
  20. // (c) 2001-2003 Electronic Arts Inc. //
  21. // //
  22. ////////////////////////////////////////////////////////////////////////////////
  23. // FILE: SubsystemInterface.cpp
  24. // ----------------------------------------------------------------------------
  25. #include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
  26. #include "Common/SubsystemInterface.h"
  27. #include "Common/Xfer.h"
  28. #ifdef _INTERNAL
  29. // for occasional debugging...
  30. //#pragma optimize("", off)
  31. //#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes")
  32. #endif
  33. #ifdef DUMP_PERF_STATS
  34. #include "GameLogic\GameLogic.h"
  35. #include "Common/PerfTimer.h"
  36. Real SubsystemInterface::s_msConsumed = 0;
  37. #endif
  38. //-----------------------------------------------------------------------------
  39. SubsystemInterface::SubsystemInterface()
  40. #ifdef DUMP_PERF_STATS
  41. :m_curDrawTime(0),
  42. m_startDrawTimeConsumed(0),
  43. m_startTimeConsumed(0),
  44. m_curUpdateTime(0)
  45. #endif
  46. {
  47. if (TheSubsystemList) {
  48. TheSubsystemList->addSubsystem(this);
  49. }
  50. }
  51. SubsystemInterface::~SubsystemInterface()
  52. {
  53. if (TheSubsystemList) {
  54. TheSubsystemList->removeSubsystem(this);
  55. }
  56. }
  57. #ifdef DUMP_PERF_STATS
  58. void SubsystemInterface::UPDATE(void)
  59. {
  60. __int64 startTime64;
  61. __int64 endTime64,freq64;
  62. GetPrecisionTimerTicksPerSec(&freq64);
  63. GetPrecisionTimer(&startTime64);
  64. m_startTimeConsumed = s_msConsumed;
  65. update();
  66. GetPrecisionTimer(&endTime64);
  67. m_curUpdateTime = ((double)(endTime64-startTime64))/((double)(freq64));
  68. Real subTime = s_msConsumed - m_startTimeConsumed;
  69. if (m_name.isEmpty()) return;
  70. if (m_curUpdateTime > 0.00001) {
  71. //DEBUG_LOG(("Subsys %s total time %.2f, subTime %.2f, net time %.2f\n",
  72. // m_name.str(), m_curUpdateTime*1000, subTime*1000, (m_curUpdateTime-subTime)*1000 ));
  73. m_curUpdateTime -= subTime;
  74. s_msConsumed += m_curUpdateTime;
  75. } else {
  76. m_curUpdateTime = 0;
  77. }
  78. }
  79. void SubsystemInterface::DRAW(void)
  80. {
  81. __int64 startTime64;
  82. __int64 endTime64,freq64;
  83. GetPrecisionTimerTicksPerSec(&freq64);
  84. GetPrecisionTimer(&startTime64);
  85. m_startDrawTimeConsumed = s_msConsumed;
  86. draw();
  87. GetPrecisionTimer(&endTime64);
  88. m_curDrawTime = ((double)(endTime64-startTime64))/((double)(freq64));
  89. Real subTime = s_msConsumed - m_startDrawTimeConsumed;
  90. if (m_name.isEmpty()) return;
  91. if (m_curDrawTime > 0.00001) {
  92. //DEBUG_LOG(("Subsys %s total time %.2f, subTime %.2f, net time %.2f\n",
  93. // m_name.str(), m_curUpdateTime*1000, subTime*1000, (m_curUpdateTime-subTime)*1000 ));
  94. m_curDrawTime -= subTime;
  95. s_msConsumed += m_curDrawTime;
  96. } else {
  97. m_curDrawTime = 0;
  98. }
  99. }
  100. #endif
  101. //-----------------------------------------------------------------------------
  102. SubsystemInterfaceList::SubsystemInterfaceList()
  103. {
  104. }
  105. //-----------------------------------------------------------------------------
  106. SubsystemInterfaceList::~SubsystemInterfaceList()
  107. {
  108. DEBUG_ASSERTCRASH(m_subsystems.empty(), ("not empty"));
  109. shutdownAll();
  110. }
  111. //-----------------------------------------------------------------------------
  112. void SubsystemInterfaceList::addSubsystem(SubsystemInterface* sys)
  113. {
  114. #ifdef DUMP_PERF_STATS
  115. m_allSubsystems.push_back(sys);
  116. #endif
  117. }
  118. //-----------------------------------------------------------------------------
  119. void SubsystemInterfaceList::removeSubsystem(SubsystemInterface* sys)
  120. {
  121. #ifdef DUMP_PERF_STATS
  122. for (SubsystemList::iterator it = m_allSubsystems.begin(); it != m_subsystems.end(); ++it)
  123. {
  124. if ( (*it) == sys) {
  125. m_allSubsystems.erase(it);
  126. break;
  127. }
  128. }
  129. #endif
  130. }
  131. //-----------------------------------------------------------------------------
  132. void SubsystemInterfaceList::initSubsystem(SubsystemInterface* sys, const char* path1, const char* path2, const char* dirpath, Xfer *pXfer, AsciiString name)
  133. {
  134. sys->setName(name);
  135. sys->init();
  136. INI ini;
  137. if (path1)
  138. ini.load(path1, INI_LOAD_OVERWRITE, pXfer );
  139. if (path2)
  140. ini.load(path2, INI_LOAD_OVERWRITE, pXfer );
  141. if (dirpath)
  142. ini.loadDirectory(dirpath, TRUE, INI_LOAD_OVERWRITE, pXfer );
  143. m_subsystems.push_back(sys);
  144. }
  145. //-----------------------------------------------------------------------------
  146. void SubsystemInterfaceList::postProcessLoadAll()
  147. {
  148. for (SubsystemList::iterator it = m_subsystems.begin(); it != m_subsystems.end(); ++it)
  149. {
  150. (*it)->postProcessLoad();
  151. }
  152. }
  153. //-----------------------------------------------------------------------------
  154. void SubsystemInterfaceList::resetAll()
  155. {
  156. // for (SubsystemList::iterator it = m_subsystems.begin(); it != m_subsystems.end(); ++it)
  157. for (SubsystemList::reverse_iterator it = m_subsystems.rbegin(); it != m_subsystems.rend(); ++it)
  158. {
  159. (*it)->reset();
  160. }
  161. }
  162. //-----------------------------------------------------------------------------
  163. void SubsystemInterfaceList::shutdownAll()
  164. {
  165. // must go in reverse order!
  166. for (SubsystemList::reverse_iterator it = m_subsystems.rbegin(); it != m_subsystems.rend(); ++it)
  167. {
  168. SubsystemInterface* sys = *it;
  169. delete sys;
  170. }
  171. m_subsystems.clear();
  172. }
  173. #ifdef DUMP_PERF_STATS
  174. //-----------------------------------------------------------------------------
  175. AsciiString SubsystemInterfaceList::dumpTimesForAll()
  176. {
  177. AsciiString buffer;
  178. buffer = "ALL SUBSYSTEMS:\n";
  179. //buffer.format("\nSUBSYSTEMS: total time %.2f MS\n",
  180. // SubsystemInterface::getTotalTime()*1000.0f);
  181. Real misc = 0;
  182. Real total = 0;
  183. SubsystemInterface::clearTotalTime();
  184. for (SubsystemList::reverse_iterator it = m_allSubsystems.rbegin(); it != m_allSubsystems.rend(); ++it)
  185. {
  186. SubsystemInterface* sys = *it;
  187. total += sys->getUpdateTime();
  188. if (sys->getUpdateTime()>0.00001f) {
  189. AsciiString curLine;
  190. curLine.format(" Time %02.2f MS update() %s \n", sys->getUpdateTime()*1000.0f, sys->getName().str());
  191. buffer.concat(curLine);
  192. } else {
  193. misc += sys->getUpdateTime();
  194. }
  195. total += sys->getDrawTime();
  196. if (sys->getDrawTime()>0.00001f) {
  197. AsciiString curLine;
  198. curLine.format(" Time %02.2f MS draw () %s \n", sys->getDrawTime()*1000.0f, sys->getName().str());
  199. buffer.concat(curLine);
  200. } else {
  201. misc += sys->getDrawTime();
  202. }
  203. }
  204. AsciiString tmp;
  205. tmp.format("TOTAL %.2f MS, Misc time %.2f MS\n", total*1000.0f, misc*1000.0f);
  206. buffer.concat(tmp);
  207. return buffer;
  208. }
  209. #endif