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