Stock.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. /* Copyright (c) 2002-2012 Croteam Ltd.
  2. This program is free software; you can redistribute it and/or modify
  3. it under the terms of version 2 of the GNU General Public License as published by
  4. the Free Software Foundation
  5. This program is distributed in the hope that it will be useful,
  6. but WITHOUT ANY WARRANTY; without even the implied warranty of
  7. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  8. GNU General Public License for more details.
  9. You should have received a copy of the GNU General Public License along
  10. with this program; if not, write to the Free Software Foundation, Inc.,
  11. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
  12. #include <Engine/Base/Stream.h>
  13. #include <Engine/Templates/DynamicContainer.cpp>
  14. /*
  15. * Default constructor.
  16. */
  17. CStock_TYPE::CStock_TYPE(void)
  18. {
  19. st_ntObjects.SetAllocationParameters(50, 2, 2);
  20. }
  21. /*
  22. * Destructor.
  23. */
  24. CStock_TYPE::~CStock_TYPE(void)
  25. {
  26. // free all unused elements of the stock
  27. FreeUnused();
  28. }
  29. /*
  30. * Obtain an object from stock - loads if not loaded.
  31. */
  32. TYPE *CStock_TYPE::Obtain_t(const CTFileName &fnmFileName)
  33. {
  34. // find stocked object with same name
  35. TYPE *pExisting = st_ntObjects.Find(fnmFileName);
  36. // if found
  37. if (pExisting!=NULL) {
  38. // mark that it is used once again
  39. pExisting->MarkUsed();
  40. // return its pointer
  41. return pExisting;
  42. }
  43. /* if not found, */
  44. // create new stock object
  45. TYPE *ptNew = new TYPE;
  46. ptNew->ser_FileName = fnmFileName;
  47. st_ctObjects.Add(ptNew);
  48. st_ntObjects.Add(ptNew);
  49. // load it
  50. try {
  51. ptNew->Load_t(fnmFileName);
  52. } catch(char *) {
  53. st_ctObjects.Remove(ptNew);
  54. st_ntObjects.Remove(ptNew);
  55. delete ptNew;
  56. throw;
  57. }
  58. // mark that it is used for the first time
  59. //ASSERT(!ptNew->IsUsed());
  60. ptNew->MarkUsed();
  61. // return the pointer to the new one
  62. return ptNew;
  63. }
  64. /*
  65. * Release an object when not needed any more.
  66. */
  67. void CStock_TYPE::Release(TYPE *ptObject)
  68. {
  69. // mark that it is used one less time
  70. ptObject->MarkUnused();
  71. // if it is not used at all any more and should be freed automatically
  72. if (!ptObject->IsUsed() && ptObject->IsAutoFreed()) {
  73. // remove it from stock
  74. st_ctObjects.Remove(ptObject);
  75. st_ntObjects.Remove(ptObject);
  76. delete ptObject;
  77. }
  78. }
  79. // free all unused elements of the stock
  80. void CStock_TYPE::FreeUnused(void)
  81. {
  82. BOOL bAnyRemoved;
  83. // repeat
  84. do {
  85. // create container of objects that should be freed
  86. CDynamicContainer<TYPE> ctToFree;
  87. {FOREACHINDYNAMICCONTAINER(st_ctObjects, TYPE, itt) {
  88. if (!itt->IsUsed()) {
  89. ctToFree.Add(itt);
  90. }
  91. }}
  92. bAnyRemoved = ctToFree.Count()>0;
  93. // for each object that should be freed
  94. {FOREACHINDYNAMICCONTAINER(ctToFree, TYPE, itt) {
  95. st_ctObjects.Remove(itt);
  96. st_ntObjects.Remove(itt);
  97. delete (&*itt);
  98. }}
  99. // as long as there is something to remove
  100. } while (bAnyRemoved);
  101. }
  102. // calculate amount of memory used by all objects in the stock
  103. SLONG CStock_TYPE::CalculateUsedMemory(void)
  104. {
  105. SLONG slUsedTotal = 0;
  106. {FOREACHINDYNAMICCONTAINER(st_ctObjects, TYPE, itt) {
  107. SLONG slUsedByObject = itt->GetUsedMemory();
  108. if (slUsedByObject<0) {
  109. return -1;
  110. }
  111. slUsedTotal+=slUsedByObject;
  112. }}
  113. return slUsedTotal;
  114. }
  115. // dump memory usage report to a file
  116. void CStock_TYPE::DumpMemoryUsage_t(CTStream &strm) // throw char *
  117. {
  118. CTString strLine;
  119. SLONG slUsedTotal = 0;
  120. {FOREACHINDYNAMICCONTAINER(st_ctObjects, TYPE, itt) {
  121. SLONG slUsedByObject = itt->GetUsedMemory();
  122. if (slUsedByObject<0) {
  123. strm.PutLine_t("Error!");
  124. return;
  125. }
  126. strLine.PrintF("%7.1fk %s(%d) %s",
  127. slUsedByObject/1024.0f, (const char*)(itt->GetName()), itt->GetUsedCount(), itt->GetDescription());
  128. strm.PutLine_t(strLine);
  129. }}
  130. }
  131. // get number of total elements in stock
  132. INDEX CStock_TYPE::GetTotalCount(void)
  133. {
  134. return st_ctObjects.Count();
  135. }
  136. // get number of used elements in stock
  137. INDEX CStock_TYPE::GetUsedCount(void)
  138. {
  139. INDEX ctUsed = 0;
  140. {FOREACHINDYNAMICCONTAINER(st_ctObjects, TYPE, itt) {
  141. if (itt->IsUsed()) {
  142. ctUsed++;
  143. }
  144. }}
  145. return ctUsed;
  146. }