tickCache.cpp 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #include "platform/platform.h"
  23. #include "T3D/gameBase/gameBase.h"
  24. #include "console/consoleTypes.h"
  25. #include "console/consoleInternal.h"
  26. #include "core/stream/bitStream.h"
  27. #include "sim/netConnection.h"
  28. #include "T3D/gameBase/gameConnection.h"
  29. #include "math/mathIO.h"
  30. #include "T3D/gameBase/moveManager.h"
  31. #include "T3D/gameBase/gameProcess.h"
  32. struct TickCacheHead
  33. {
  34. TickCacheEntry * oldest;
  35. TickCacheEntry * newest;
  36. TickCacheEntry * next;
  37. U32 numEntry;
  38. };
  39. namespace
  40. {
  41. FreeListChunker<TickCacheHead> sgTickCacheHeadStore;
  42. FreeListChunker<TickCacheEntry> sgTickCacheEntryStore;
  43. FreeListChunker<Move> sgMoveStore;
  44. static TickCacheHead * allocHead() { return sgTickCacheHeadStore.alloc(); }
  45. static void freeHead(TickCacheHead * head) { sgTickCacheHeadStore.free(head); }
  46. static TickCacheEntry * allocEntry() { return sgTickCacheEntryStore.alloc(); }
  47. static void freeEntry(TickCacheEntry * entry) { sgTickCacheEntryStore.free(entry); }
  48. static Move * allocMove() { return sgMoveStore.alloc(); }
  49. static void freeMove(Move * move) { sgMoveStore.free(move); }
  50. }
  51. //----------------------------------------------------------------------------
  52. TickCache::~TickCache()
  53. {
  54. if (mTickCacheHead)
  55. {
  56. setCacheSize(0);
  57. freeHead(mTickCacheHead);
  58. mTickCacheHead = NULL;
  59. }
  60. }
  61. Move * TickCacheEntry::allocateMove()
  62. {
  63. return allocMove();
  64. }
  65. TickCacheEntry * TickCache::addCacheEntry()
  66. {
  67. // Add a new entry, creating head if needed
  68. if (!mTickCacheHead)
  69. {
  70. mTickCacheHead = allocHead();
  71. mTickCacheHead->newest = mTickCacheHead->oldest = mTickCacheHead->next = NULL;
  72. mTickCacheHead->numEntry = 0;
  73. }
  74. if (!mTickCacheHead->newest)
  75. {
  76. mTickCacheHead->newest = mTickCacheHead->oldest = allocEntry();
  77. }
  78. else
  79. {
  80. mTickCacheHead->newest->next = allocEntry();
  81. mTickCacheHead->newest = mTickCacheHead->newest->next;
  82. }
  83. mTickCacheHead->newest->next = NULL;
  84. mTickCacheHead->newest->move = NULL;
  85. mTickCacheHead->numEntry++;
  86. return mTickCacheHead->newest;
  87. }
  88. void TickCache::setCacheSize(S32 len)
  89. {
  90. // grow cache to len size, adding to newest side of the list
  91. while (!mTickCacheHead || mTickCacheHead->numEntry < len)
  92. addCacheEntry();
  93. // shrink tick cache down to given size, popping off oldest entries first
  94. while (mTickCacheHead && mTickCacheHead->numEntry > len)
  95. dropOldest();
  96. }
  97. void TickCache::dropOldest()
  98. {
  99. AssertFatal(mTickCacheHead->oldest,"Popping off too many tick cache entries");
  100. TickCacheEntry * oldest = mTickCacheHead->oldest;
  101. mTickCacheHead->oldest = oldest->next;
  102. if (oldest->move)
  103. freeMove(oldest->move);
  104. freeEntry(oldest);
  105. mTickCacheHead->numEntry--;
  106. if (mTickCacheHead->numEntry < 2)
  107. mTickCacheHead->newest = mTickCacheHead->oldest;
  108. }
  109. void TickCache::dropNextOldest()
  110. {
  111. AssertFatal(mTickCacheHead->oldest && mTickCacheHead->numEntry>1,"Popping off too many tick cache entries");
  112. TickCacheEntry * oldest = mTickCacheHead->oldest;
  113. TickCacheEntry * nextoldest = mTickCacheHead->oldest->next;
  114. oldest->next = nextoldest->next;
  115. if (nextoldest->move)
  116. freeMove(nextoldest->move);
  117. freeEntry(nextoldest);
  118. mTickCacheHead->numEntry--;
  119. if (mTickCacheHead->numEntry==1)
  120. mTickCacheHead->newest = mTickCacheHead->oldest;
  121. }
  122. void TickCache::ageCache(S32 numToAge, S32 len)
  123. {
  124. AssertFatal(mTickCacheHead,"No tick cache head");
  125. AssertFatal(mTickCacheHead->numEntry>=numToAge,"Too few entries!");
  126. AssertFatal(mTickCacheHead->numEntry>numToAge,"Too few entries!");
  127. while (numToAge--)
  128. dropOldest();
  129. while (mTickCacheHead->numEntry>len)
  130. dropNextOldest();
  131. while (mTickCacheHead->numEntry<len)
  132. addCacheEntry();
  133. }
  134. void TickCache::beginCacheList()
  135. {
  136. // get ready iterate from oldest to newest entry
  137. if (mTickCacheHead)
  138. mTickCacheHead->next = mTickCacheHead->oldest;
  139. // if no head, that's ok, we'll just add entries as we go
  140. }
  141. TickCacheEntry * TickCache::incCacheList(bool addIfNeeded)
  142. {
  143. // continue iterating through cache, returning current entry
  144. // we'll add new entries if need be
  145. TickCacheEntry * ret = NULL;
  146. if (mTickCacheHead && mTickCacheHead->next)
  147. {
  148. ret = mTickCacheHead->next;
  149. mTickCacheHead->next = mTickCacheHead->next->next;
  150. }
  151. else if (addIfNeeded)
  152. {
  153. addCacheEntry();
  154. ret = mTickCacheHead->newest;
  155. }
  156. return ret;
  157. }