SubsystemInterface.cpp 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. /*
  2. ** Command & Conquer Generals Zero Hour(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. m_dumpUpdate(false),
  46. m_dumpDraw(false)
  47. #endif
  48. {
  49. if (TheSubsystemList) {
  50. TheSubsystemList->addSubsystem(this);
  51. }
  52. }
  53. SubsystemInterface::~SubsystemInterface()
  54. {
  55. if (TheSubsystemList) {
  56. TheSubsystemList->removeSubsystem(this);
  57. }
  58. }
  59. #ifdef DUMP_PERF_STATS
  60. static const Real MIN_TIME_THRESHOLD = 0.0002f; // .2 msec. [8/13/2003]
  61. void SubsystemInterface::UPDATE(void)
  62. {
  63. __int64 startTime64;
  64. __int64 endTime64,freq64;
  65. GetPrecisionTimerTicksPerSec(&freq64);
  66. GetPrecisionTimer(&startTime64);
  67. m_startTimeConsumed = s_msConsumed;
  68. update();
  69. GetPrecisionTimer(&endTime64);
  70. m_curUpdateTime = ((double)(endTime64-startTime64))/((double)(freq64));
  71. Real subTime = s_msConsumed - m_startTimeConsumed;
  72. if (m_name.isEmpty()) return;
  73. if (m_curUpdateTime>MIN_TIME_THRESHOLD) {
  74. m_dumpUpdate = true;
  75. }
  76. if (m_curUpdateTime > MIN_TIME_THRESHOLD/10.0f) {
  77. //DLOG(Debug::Format("Subsys %s total time %.2f, subTime %.2f, net time %.2f\n",
  78. // m_name.str(), m_curUpdateTime*1000, subTime*1000, (m_curUpdateTime-subTime)*1000 ));
  79. m_curUpdateTime -= subTime;
  80. s_msConsumed += m_curUpdateTime;
  81. } else {
  82. m_curUpdateTime = 0;
  83. }
  84. }
  85. void SubsystemInterface::DRAW(void)
  86. {
  87. __int64 startTime64;
  88. __int64 endTime64,freq64;
  89. GetPrecisionTimerTicksPerSec(&freq64);
  90. GetPrecisionTimer(&startTime64);
  91. m_startDrawTimeConsumed = s_msConsumed;
  92. draw();
  93. GetPrecisionTimer(&endTime64);
  94. m_curDrawTime = ((double)(endTime64-startTime64))/((double)(freq64));
  95. Real subTime = s_msConsumed - m_startDrawTimeConsumed;
  96. if (m_name.isEmpty()) return;
  97. if (m_curDrawTime>MIN_TIME_THRESHOLD) {
  98. m_dumpDraw = true;
  99. }
  100. if (m_curDrawTime > MIN_TIME_THRESHOLD/10.0f) {
  101. //DLOG(Debug::Format("Subsys %s total time %.2f, subTime %.2f, net time %.2f\n",
  102. // m_name.str(), m_curUpdateTime*1000, subTime*1000, (m_curUpdateTime-subTime)*1000 ));
  103. m_curDrawTime -= subTime;
  104. s_msConsumed += m_curDrawTime;
  105. } else {
  106. m_curDrawTime = 0;
  107. }
  108. }
  109. #endif
  110. //-----------------------------------------------------------------------------
  111. SubsystemInterfaceList::SubsystemInterfaceList()
  112. {
  113. }
  114. //-----------------------------------------------------------------------------
  115. SubsystemInterfaceList::~SubsystemInterfaceList()
  116. {
  117. DEBUG_ASSERTCRASH(m_subsystems.empty(), ("not empty"));
  118. shutdownAll();
  119. }
  120. //-----------------------------------------------------------------------------
  121. void SubsystemInterfaceList::addSubsystem(SubsystemInterface* sys)
  122. {
  123. #ifdef DUMP_PERF_STATS
  124. m_allSubsystems.push_back(sys);
  125. #endif
  126. }
  127. //-----------------------------------------------------------------------------
  128. void SubsystemInterfaceList::removeSubsystem(SubsystemInterface* sys)
  129. {
  130. #ifdef DUMP_PERF_STATS
  131. for (SubsystemList::iterator it = m_allSubsystems.begin(); it != m_subsystems.end(); ++it)
  132. {
  133. if ( (*it) == sys) {
  134. m_allSubsystems.erase(it);
  135. break;
  136. }
  137. }
  138. #endif
  139. }
  140. //-----------------------------------------------------------------------------
  141. void SubsystemInterfaceList::initSubsystem(SubsystemInterface* sys, const char* path1, const char* path2, const char* dirpath, Xfer *pXfer, AsciiString name)
  142. {
  143. sys->setName(name);
  144. sys->init();
  145. INI ini;
  146. if (path1)
  147. ini.load(path1, INI_LOAD_OVERWRITE, pXfer );
  148. if (path2)
  149. ini.load(path2, INI_LOAD_OVERWRITE, pXfer );
  150. if (dirpath)
  151. ini.loadDirectory(dirpath, TRUE, INI_LOAD_OVERWRITE, pXfer );
  152. m_subsystems.push_back(sys);
  153. }
  154. //-----------------------------------------------------------------------------
  155. void SubsystemInterfaceList::postProcessLoadAll()
  156. {
  157. for (SubsystemList::iterator it = m_subsystems.begin(); it != m_subsystems.end(); ++it)
  158. {
  159. (*it)->postProcessLoad();
  160. }
  161. }
  162. //-----------------------------------------------------------------------------
  163. void SubsystemInterfaceList::resetAll()
  164. {
  165. // for (SubsystemList::iterator it = m_subsystems.begin(); it != m_subsystems.end(); ++it)
  166. for (SubsystemList::reverse_iterator it = m_subsystems.rbegin(); it != m_subsystems.rend(); ++it)
  167. {
  168. (*it)->reset();
  169. }
  170. }
  171. //-----------------------------------------------------------------------------
  172. void SubsystemInterfaceList::shutdownAll()
  173. {
  174. // must go in reverse order!
  175. for (SubsystemList::reverse_iterator it = m_subsystems.rbegin(); it != m_subsystems.rend(); ++it)
  176. {
  177. SubsystemInterface* sys = *it;
  178. delete sys;
  179. }
  180. m_subsystems.clear();
  181. }
  182. #ifdef DUMP_PERF_STATS
  183. //-----------------------------------------------------------------------------
  184. AsciiString SubsystemInterfaceList::dumpTimesForAll()
  185. {
  186. AsciiString buffer;
  187. buffer = "ALL SUBSYSTEMS:\n";
  188. //buffer.format("\nSUBSYSTEMS: total time %.2f MS\n",
  189. // SubsystemInterface::getTotalTime()*1000.0f);
  190. Real misc = 0;
  191. Real total = 0;
  192. SubsystemInterface::clearTotalTime();
  193. for (SubsystemList::reverse_iterator it = m_allSubsystems.rbegin(); it != m_allSubsystems.rend(); ++it)
  194. {
  195. SubsystemInterface* sys = *it;
  196. total += sys->getUpdateTime();
  197. if (sys->doDumpUpdate()) {
  198. AsciiString curLine;
  199. curLine.format(" Time %02.2f MS update() %s \n", sys->getUpdateTime()*1000.0f, sys->getName().str());
  200. buffer.concat(curLine);
  201. } else {
  202. misc += sys->getUpdateTime();
  203. }
  204. total += sys->getDrawTime();
  205. if (sys->doDumpDraw()) {
  206. AsciiString curLine;
  207. curLine.format(" Time %02.2f MS draw () %s \n", sys->getDrawTime()*1000.0f, sys->getName().str());
  208. buffer.concat(curLine);
  209. } else {
  210. misc += sys->getDrawTime();
  211. }
  212. }
  213. AsciiString tmp;
  214. tmp.format("TOTAL %.2f MS, Misc time %.2f MS\n", total*1000.0f, misc*1000.0f);
  215. buffer.concat(tmp);
  216. return buffer;
  217. }
  218. #endif