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