www.pudn.com > GameEngine_src.rar > CPool.h
#ifndef CPool_h #define CPool_h #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #include#include #include #include template struct POOLNODE { POOLNODE() {} ~POOLNODE() {}; T t; POOLNODE *pNext; POOLNODE *pPrev; }; template class CPool { public: CPool(); CPool( int size ); ~CPool(); bool Init( int num ); void Free(); T *Alloc(); void Free( T *t ); void Begin() { m_pCur = m_pBusyPool; } bool IsNotNull() { return m_pCur != NULL; } void MoveNext() { m_pCur = m_pCur->pNext; } T *GetCur() { return (T *)m_pCur; } void FreeCur() //自删除 { m_TempNode.pNext = m_pCur->pNext; Free( (T *)m_pCur ); m_pCur = &m_TempNode; } T *Add( T &t ) { T *p = Alloc(); if ( p ) *p = t; return p; } void Delete( T &t ) { for ( Begin(); IsNotNull(); MoveNext() ) { if ( (*GetCur()) == t ) { FreeCur(); return; } } } void Clear() { for ( Begin(); IsNotNull(); MoveNext() ) FreeCur(); } int GetLength() { return m_NumBusy; } bool IsEmpty() { return m_NumBusy == 0; } private: POOLNODE *m_pIdlePool; POOLNODE *m_pBusyPool; POOLNODE *m_pPool; POOLNODE *m_pCur; int m_NumBusy; int m_NumIdle; POOLNODE m_TempNode; //用于在for循环中自删除 }; const int ALLOC_SIZE = 1024; ////////////////////////////////////////////////////////////// //构造,析构 ////////////////////////////////////////////////////////////// template CPool ::CPool() { m_pPool = NULL; m_pIdlePool = NULL; m_pBusyPool = NULL; m_pCur = NULL; m_NumBusy = 0; m_NumIdle = 0; } template CPool ::~CPool() { Clear(); Free(); } template CPool ::CPool( int size ) { m_pPool = NULL; m_pIdlePool = NULL; m_pBusyPool = NULL; m_pCur = NULL; m_NumBusy = 0; m_NumIdle = 0; Init( size ); } ////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////// template bool CPool ::Init( int num ) { if ( num < 1 ) num = ALLOC_SIZE; m_pPool = (POOLNODE *)malloc( sizeof(POOLNODE ) * num ); if ( m_pPool == NULL ) return false; m_pPool[0].pPrev = NULL; m_pPool[0].pNext = &m_pPool[1]; for ( int i = 1; i < num - 1; ++i ) { m_pPool[i].pPrev = &m_pPool[i-1]; m_pPool[i].pNext = &m_pPool[i+1]; } m_pPool[num-1].pPrev = &m_pPool[num-2]; m_pPool[num-1].pNext = NULL; m_pIdlePool = &m_pPool[0]; m_pBusyPool = NULL; m_NumIdle = num; m_NumBusy = 0; return true; } ////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////// template void CPool ::Free() { if ( m_pPool != NULL ) { free( m_pPool ); m_pPool = NULL; m_pIdlePool = NULL; m_pBusyPool = NULL; m_pCur = NULL; m_NumBusy = 0; m_NumIdle = 0; } } ////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////// template T * CPool ::Alloc() { if ( m_pIdlePool != NULL ) { POOLNODE *pNext; pNext = m_pIdlePool->pNext; m_pIdlePool->pNext = m_pBusyPool; if ( pNext != NULL ) pNext->pPrev = NULL; if ( m_pBusyPool != NULL ) m_pBusyPool->pPrev = m_pIdlePool; m_pBusyPool = m_pIdlePool; m_pIdlePool = pNext; ::new (m_pBusyPool) T; --m_NumIdle; ++m_NumBusy; return (T*)m_pBusyPool; } return NULL; } ////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////// template void CPool ::Free( T * t ) { #ifdef _DEBUG assert( t != NULL ); #endif t->~T(); POOLNODE *p = (POOLNODE *)t; if ( p->pPrev != NULL ) p->pPrev->pNext = p->pNext; else m_pBusyPool = p->pNext; if ( p->pNext != NULL ) p->pNext->pPrev = p->pPrev; p->pPrev = NULL; p->pNext = m_pIdlePool; if ( m_pIdlePool != NULL ) m_pIdlePool->pPrev = p; m_pIdlePool = p; ++m_NumIdle; --m_NumBusy; } #endif