include/AK/Tools/Common/AkDynaBlkPool.h
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef _AKBLOCKPOOL_H
00029 #define _AKBLOCKPOOL_H
00030
00031 #include <AK/Tools/Common/AkObject.h>
00032 #include <AK/Tools/Common/AkAssert.h>
00033 #include <AK/Tools/Common/AkListBareLight.h>
00034
00035
00036
00037
00038
00039
00040 #ifdef _DEBUG
00041
00042 #define AK_DYNA_BLK_SCRUB_MEM
00043 #endif
00044
00045 #ifdef AK_DYNA_BLK_STATS
00046 #define STATS_ALLOC() Stats_Alloc()
00047 #define STATS_NEWCHUNK() Stats_NewChunk()
00048 #define STATS_FREE() Stats_Free()
00049 #define STATS_DELCHUNK() Stats_DelChunk()
00050 #else
00051 #define STATS_ALLOC()
00052 #define STATS_NEWCHUNK()
00053 #define STATS_FREE()
00054 #define STATS_DELCHUNK()
00055 #endif
00056
00057 #ifdef AK_DYNA_BLK_SCRUB_MEM
00058 #define SCRUB_NEW_CHUNK() memset(&memory, 0xCC, sizeof(T)*uPoolChunkSize)
00059 #define SCRUB_NEW_ALLOC(pItem) memset(pItem, 0xAA, sizeof(T))
00060 #define SCRUB_FREE_BLOCK(pObj) memset(pObj, 0xDD, sizeof(T))
00061 #else
00062 #define SCRUB_NEW_CHUNK()
00063 #define SCRUB_NEW_ALLOC(pItem)
00064 #define SCRUB_FREE_BLOCK(pObj)
00065 #endif
00066
00067 template < typename T, AkUInt32 uPoolChunkSize, class TAlloc = ArrayPoolDefault>
00068 class AkDynaBlkPool
00069 {
00070 enum { kChunkMemoryBytes = sizeof(T)*uPoolChunkSize };
00071
00072 struct FreeBlock
00073 {
00074 FreeBlock* pNextItem;
00075 char padding[ sizeof(T) - sizeof(FreeBlock*) ];
00076 };
00077 typedef AkListBare< FreeBlock, AkListBareNextItem, AkCountPolicyWithCount, AkLastPolicyNoLast > tFreeList;
00078
00079 struct PoolChunk
00080 {
00081 PoolChunk() : pNextLightItem(NULL)
00082 {
00083 SCRUB_NEW_CHUNK();
00084 for( AkUInt32 i=0; i<uPoolChunkSize; ++i )
00085 {
00086 FreeBlock* pBlk = reinterpret_cast<FreeBlock*>( &memory ) + i;
00087 freeList.AddFirst(pBlk);
00088 }
00089 }
00090
00091 inline bool BelongsTo( FreeBlock* pMem ) const { return (AkUInt8*)pMem >= memory && (AkUInt8*)pMem < (memory+kChunkMemoryBytes); }
00092 inline bool AllFree() const { return freeList.Length() == uPoolChunkSize; }
00093 inline bool AllAllocd() const { return freeList.IsEmpty(); }
00094
00095 AkUInt8 memory[ kChunkMemoryBytes ];
00096 PoolChunk* pNextLightItem;
00097 tFreeList freeList;
00098 };
00099 typedef AkListBareLight< PoolChunk > tChunkList;
00100
00101 public:
00102
00103 T* New()
00104 {
00105 T* ptr = Alloc();
00106 if (ptr)
00107 AkPlacementNew(ptr) T;
00108 return ptr;
00109 }
00110
00111 void Delete(T* ptr)
00112 {
00113 ptr->~T();
00114 Free(ptr);
00115 }
00116
00117 private:
00118 T* Alloc()
00119 {
00120 FreeBlock* pItem = NULL;
00121 PoolChunk* pChunk = NULL;
00122
00123 pChunk = m_chunkList.First();
00124 while (pChunk != NULL && pChunk->AllAllocd())
00125 pChunk = pChunk->pNextLightItem;
00126
00127 if (pChunk == NULL)
00128 {
00129 pChunk = (PoolChunk *) TAlloc::Alloc( sizeof( PoolChunk ) );
00130 AkPlacementNew(pChunk) PoolChunk();
00131 STATS_NEWCHUNK();
00132 if (pChunk != NULL)
00133 m_chunkList.AddFirst(pChunk);
00134 }
00135
00136 if (pChunk != NULL)
00137 {
00138 pItem = pChunk->freeList.First();
00139 AKASSERT(pItem != NULL);
00140 pChunk->freeList.RemoveFirst();
00141 SCRUB_NEW_ALLOC(pItem);
00142 STATS_ALLOC();
00143 }
00144
00145 return reinterpret_cast<T*>(pItem);
00146 }
00147
00148 void Free( T* pObj )
00149 {
00150 SCRUB_FREE_BLOCK((void*)pObj);
00151
00152 FreeBlock* pItem = reinterpret_cast<FreeBlock*>(pObj);
00153
00154 PoolChunk* pPrevChunk = NULL;
00155 PoolChunk* pChunk = m_chunkList.First();
00156 while (pChunk != NULL && !pChunk->BelongsTo(pItem))
00157 {
00158 pPrevChunk = pChunk;
00159 pChunk = pChunk->pNextLightItem;
00160 }
00161
00162 AKASSERT(pChunk != NULL);
00163 pChunk->freeList.AddFirst(pItem);
00164 STATS_FREE();
00165
00166 if (pChunk->AllFree())
00167 {
00168 m_chunkList.RemoveItem(pChunk, pPrevChunk);
00169 pChunk->~PoolChunk();
00170 TAlloc::Free( pChunk );
00171 STATS_DELCHUNK();
00172 }
00173 }
00174
00175 tChunkList m_chunkList;
00176
00177 #ifdef AK_DYNA_BLK_STATS
00178 void Stats_Alloc()
00179 {
00180 uCurrentUsedBytes += sizeof(T);
00181 uPeakUsedBytes = AkMax(uCurrentUsedBytes, uPeakUsedBytes);
00182 }
00183 void Stats_NewChunk()
00184 {
00185 uCurrentAllocdBytes += sizeof(PoolChunk);
00186 uPeakAllocdBytes = AkMax(uCurrentAllocdBytes, uPeakAllocdBytes);
00187 }
00188 void Stats_Free()
00189 {
00190 uCurrentUsedBytes -= sizeof(T);
00191 }
00192 void Stats_DelChunk()
00193 {
00194 uCurrentAllocdBytes -= sizeof(PoolChunk);
00195 }
00196 public:
00197 AkUInt32 uPeakUsedBytes;
00198 AkUInt32 uPeakAllocdBytes;
00199 AkUInt32 uCurrentAllocdBytes;
00200 AkUInt32 uCurrentUsedBytes;
00201 #endif
00202 };
00203
00204
00205 #endif
介绍一下自己的项目。我们会竭力为您提供帮助。
来注册自己的项目,我们帮您快速入门,不带任何附加条件!
开始 Wwise 之旅