⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tobjdictionary.h

📁 五行MMORPG引擎系统V1.0
💻 H
字号:
//tObjDictionary.h
/*/////////////////////////////////////////////////////////////////

	对象 Dictionary类模板
	与IDDictionary不一样,这里在进行allocEntry、freeEntry时,将调用
	对象的构造函数、析构函数

	Entry结构 需要符合
	{
		_T*		pData;
		Entry*	pHashNext;	//必须
		//...
	}

   李亦
	liease@163.com 4040719
	2006-7-18
/*/////////////////////////////////////////////////////////////////
#ifndef _TOBJDICTIONARY_H_
#define _TOBJDICTIONARY_H_


#ifndef _PLATFORM_H_
#include "platform/platform.h"
#endif

#ifndef _DATACHUNKER_H_
#include "core/dataChunker.h"
#endif



template<class _T>
class OBJDictionary;


//////////////////////////////////////////
//字典条目
template<class _T>
struct OBJDictionaryEntry
{
	friend class OBJDictionary<_T>;
//private:
	_T			object;
	//U32		dwID;
	OBJDictionaryEntry<_T>*	pHashNext;
};


//////////////////////////////////////////
//ID型字典管理
template<class _T>
class OBJDictionary
{
protected:
	U32	m_dwAmount;		//单元总数

	
	U32							m_dwHashSize;
	OBJDictionaryEntry<_T>	**m_pHashTable;

protected:
	static FreeListChunker< OBJDictionaryEntry<_T> >		gs_gameChunker;


   static void		FreeEntry(OBJDictionaryEntry<_T> *entry);
   static OBJDictionaryEntry<_T>	*AllocEntry();


	void AddEntry(OBJDictionaryEntry<_T>* pEntry);
	void IncAmount(); 
	void DecAmount(); 
	void Resize(const U32 newSize);

   _T*	_New(U32 dwID);

public:
   OBJDictionary(U32 dwSize);
   ~OBJDictionary();

	void FreeHashTable();


   _T*	New(BOOL bAutoReg);
   _T*	Insert(U32 dwID);
   _T*	Reg(U32 dwID);
   void	Remove(U32 dwID);
   void	Remove(_T* pObject);
   void	Unreg(U32 dwID);
   void	Unreg(_T* pObject);
   _T*	Get(U32 dwID);
};



//////////////////////////////////////////////////////////////
//以下为模板实现

template<class _T>
FreeListChunker< OBJDictionaryEntry<_T> >	OBJDictionary<_T>::gs_gameChunker;





////////////////////////////////////////////////
//构造/析构函数
template<class _T>
OBJDictionary<_T>::OBJDictionary(U32 dwSize)
{
	m_dwAmount	 = 0;
   m_pHashTable = NULL;
	m_dwHashSize = 0;
	
	Resize(dwSize);
}


template<class _T>
OBJDictionary<_T>::~OBJDictionary()
{
	FreeHashTable();
	dFree(m_pHashTable);
	m_dwAmount = 0;
}


template<class _T>
void OBJDictionary<_T>::FreeHashTable()
{
	OBJDictionaryEntry<_T>	*walk,
									*temp;

   for(U32 i = 0; i < m_dwHashSize; i++)
   {
      for(walk = m_pHashTable[i]; walk;)
      {
         temp = walk;
         walk = temp->pHashNext;

			FreeEntry(temp);
         //gs_gameChunker.free(temp);
      }
		m_pHashTable[i] = NULL;
   }
}


template<class _T>
inline void	OBJDictionary<_T>::FreeEntry(OBJDictionaryEntry<_T> *pEntry)
{
	pEntry->object.OnDeleteAtDictionary();
	destructInPlace(&pEntry->object);
	gs_gameChunker.free(pEntry);
}

template<class _T>
OBJDictionaryEntry<_T>	*OBJDictionary<_T>::AllocEntry()
{
	OBJDictionaryEntry<_T>	*pNew;

	pNew					= gs_gameChunker.alloc();
	constructInPlace(&pNew->object);
	return pNew;
}




template<class _T>
void  OBJDictionary<_T>::AddEntry(OBJDictionaryEntry<_T>* pEntry)
{
	if(pEntry == NULL)
		return;

	_T *field = pEntry;

	U32 bucket = pEntry->object.GetID() % m_dwHashSize;
	field->pHashNext				= m_pHashTable[bucket];
	m_pHashTable[bucket] = field;
	
	IncAmount();
}


template<class _T>
void OBJDictionary<_T>::IncAmount()
{
	m_dwAmount++;
	if(m_dwAmount > m_dwHashSize * 2)
	{
		Resize(m_dwHashSize*4 - 1);
	}
}


template<class _T>
void OBJDictionary<_T>::Resize(const U32 newSize)
{
   OBJDictionaryEntry<_T> *head = NULL, *walk, *temp;
   U32 i;
   U32 dwKey;

	if(m_pHashTable)
	{
		//先把数据备份起来
		for(i = 0; i < m_dwHashSize; i++) 
		{
			walk = m_pHashTable[i];
			while(walk)
			{
				temp = walk->pHashNext;
				walk->pHashNext = head;
				head = walk;
				walk = temp;
			}
		}

		//生成新的Hash空间
		m_pHashTable = (OBJDictionaryEntry<_T> **) dRealloc(m_pHashTable, newSize * sizeof(OBJDictionaryEntry<_T>*));
	}//if(m_pHashTable)
	else
	{	
		m_pHashTable	= (OBJDictionaryEntry<_T> **) dMalloc(newSize * sizeof(OBJDictionaryEntry<_T>*));
		head				= NULL;
	}


   for(i = 0; i < newSize; i++) 
	{
      m_pHashTable[i] = 0;
   }

	//重新关联单元
   m_dwHashSize	= newSize;
   walk				= head;
   while(walk) 
	{
      temp = walk;

      walk	= walk->pHashNext;
      dwKey	= temp->object.GetID() % newSize;
      temp->pHashNext		= m_pHashTable[dwKey];
      m_pHashTable[dwKey]	= temp;
   }
}


template<class _T>
inline void OBJDictionary<_T>::DecAmount()
{
	if(m_dwAmount > 0)
		m_dwAmount--;
}


template<class _T>
void OBJDictionary<_T>::Remove(U32 dwID)
{
   //U32 bucket = HashPointer(slotName) % m_dwHashSize;
   U32 bucket = dwID % m_dwHashSize;
   OBJDictionaryEntry<_T> **walk = &m_pHashTable[bucket];

   while(*walk && (*walk)->object.GetID() != dwID)
      walk = &((*walk)->pHashNext);

   OBJDictionaryEntry<_T> *field = *walk;
   if(field)
   {
      *walk = field->pHashNext;
		FreeEntry(field);
      //gs_gameChunker.free(field);
		DecAmount();
   }
   
}

template<class _T>
inline void OBJDictionary<_T>::Remove(_T* pObject)
{
	AssertWarn(pObject,"pObject不能为空");
	Remove(pObject->GetID());
}


template<class _T>
void OBJDictionary<_T>::Unreg(U32 dwID)
{
	_T*	pData = Get(dwID) ;
	if(pData != NULL)
	{
		pData->unregisterObject();
		pData->OnUnreg();
		Remove(dwID);
	}
}


template<class _T>
inline void OBJDictionary<_T>::Unreg(_T* pObject)
{
	AssertWarn(pObject,"pObject不能为空");
	Unreg(pObject->GetID());
}



template<class _T>
_T *OBJDictionary<_T>::Get(U32 dwID)
{
   //U32 bucket = HashPointer(slotName) % m_dwHashSize;
   U32 bucket = dwID % m_dwHashSize;


   for(OBJDictionaryEntry<_T> *walk = m_pHashTable[bucket];walk;walk = walk->pHashNext)
	{
		if(walk->object.GetID() == dwID)
		{
			return &walk->object;
		}
	}
	return NULL;
}

template<class _T>
_T* OBJDictionary<_T>::Reg(U32 dwID)
{
	_T*	pData = Get(dwID) ;
	if(pData != NULL)
		return pData;

	pData = _New(dwID);

	if(pData->OnReg())
	{	
		pData->registerObject();
		return pData;
	}

	return NULL;
}


template<class _T>
_T *OBJDictionary<_T>::Insert(U32 dwID)
{
	_T*	pData = Get(dwID) ;
	if(pData != NULL)
		return pData;

	return _New(dwID);
}


template<class _T>
_T *OBJDictionary<_T>::_New(U32 dwID)
{
   U32 bucket = dwID % m_dwHashSize;
	OBJDictionaryEntry<_T>*	pNew;

	pNew		= AllocEntry();

	pNew->pHashNext	= m_pHashTable[bucket];
	m_pHashTable[bucket]	= pNew;

	pNew->object.SetID(dwID);
	IncAmount();
	return &pNew->object;
}


template<class _T>
_T *OBJDictionary<_T>::New(BOOL bAutoReg)
{
	OBJDictionaryEntry<_T>*	pNew;
	U32		dwID;

	for(dwID=1; dwID; dwID++)
	{
		if(Get(dwID) == NULL)
		{	
			if(bAutoReg)
				return Reg(dwID);
			return _New(dwID);
		}
	}
	return NULL;
}



#endif //_TOBJDICTIONARY_H_

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -