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

📄 tobjnamedictionary.h

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

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

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

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


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

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



template<class _T>
class ObjNameDictionary;


//////////////////////////////////////////
//字典条目
template<class _T>
struct ObjNameDictionaryEntry
{
	friend class ObjNameDictionary<_T>;
//private:
	_T			object;
	ObjNameDictionaryEntry<_T>*	pHashNext;
};


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

	U32							m_dwHashSize;
	ObjNameDictionaryEntry<_T>	**m_pHashTable;

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


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


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


   _T*	_New(StringTableEntry pIDName);
	
public:
   ObjNameDictionary(U32 dwSize);
   ~ObjNameDictionary();

	void FreeHashTable();


   _T*	New(StringTableEntry pIDName);
   _T*	Insert(StringTableEntry pIDName);
   _T*	Reg(StringTableEntry pIDName);
   void	Remove(StringTableEntry pIDName);
   void	Remove(_T* pObject);
	void  Unreg(StringTableEntry pIDName);
	void  Unreg(_T* pObject);
   _T*	Get(StringTableEntry pIDName);
};



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

template<class _T>
FreeListChunker< ObjNameDictionaryEntry<_T> >	ObjNameDictionary<_T>::gs_gameChunker;





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


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


template<class _T>
void ObjNameDictionary<_T>::FreeHashTable()
{
	ObjNameDictionaryEntry<_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	ObjNameDictionary<_T>::FreeEntry(ObjNameDictionaryEntry<_T> *pEntry)
{
	pEntry->object.OnDeleteAtDictionary();
	destructInPlace(&pEntry->object);
	gs_gameChunker.free(pEntry);
}

template<class _T>
ObjNameDictionaryEntry<_T>	*ObjNameDictionary<_T>::AllocEntry()
{
	ObjNameDictionaryEntry<_T>	*pNew;

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




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

	_T *field = pEntry;

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


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


template<class _T>
void ObjNameDictionary<_T>::Resize(const U32 newSize)
{
   ObjNameDictionaryEntry<_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 = (ObjNameDictionaryEntry<_T> **) dRealloc(m_pHashTable, newSize * sizeof(ObjNameDictionaryEntry<_T>*));
	}//if(m_pHashTable)
	else
	{	
		m_pHashTable	= (ObjNameDictionaryEntry<_T> **) dMalloc(newSize * sizeof(ObjNameDictionaryEntry<_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;
      dwKey	= HashPointer(temp->object.GetIDName()) % newSize;
      temp->pHashNext		= m_pHashTable[dwKey];
      m_pHashTable[dwKey]	= temp;
   }
}


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


template<class _T>
void ObjNameDictionary<_T>::Remove(StringTableEntry pIDName)
{
   U32 bucket = HashPointer(pIDName) % m_dwHashSize;
   //U32 bucket = dwID % m_dwHashSize;
   ObjNameDictionaryEntry<_T> **walk = &m_pHashTable[bucket];

   while(*walk && (*walk)->object.GetIDName() != pIDName)
      walk = &((*walk)->pHashNext);

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

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


template<class _T>
void ObjNameDictionary<_T>::Unreg(StringTableEntry pIDName)
{
	_T*	pData = Get(pIDName) ;
	if(pData)
	{
		pData->unregisterObject();
		pData->OnUnreg();
		Remove(pIDName);
	}
   //U32 bucket = dwID % m_dwHashSize;
}

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


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


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

template<class _T>
_T *ObjNameDictionary<_T>::Insert(StringTableEntry pIDName)
{
	_T*	pData = Get(pIDName) ;
	if(pData != NULL)
		return pData;

   //U32 bucket = dwID % m_dwHashSize;
	return _New(pIDName);
}


template<class _T>
_T *ObjNameDictionary<_T>::Reg(StringTableEntry pIDName)
{
	_T*	pData = Get(pIDName) ;
	if(pData != NULL)
		return pData;

   //U32 bucket = dwID % m_dwHashSize;
	pData = _New(pIDName);
	if(pData->OnReg())
	{	
		pData->registerObject(pIDName);
		return pData;
	}

	return NULL;
}




template<class _T>
_T *ObjNameDictionary<_T>::_New(StringTableEntry pIDName)
{

   //U32 bucket = dwID % m_dwHashSize;
   U32 bucket = HashPointer(pIDName) % m_dwHashSize;
	ObjNameDictionaryEntry<_T>*	pNew;

	pNew		= AllocEntry();

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

	pNew->object.SetIDName(pIDName);
	IncAmount();
	return &pNew->object;
}


template<class _T>
_T *ObjNameDictionary<_T>::New(StringTableEntry pIDName)
{
	if(Get(pIDName))
		return NULL;

	return _New(pIDName);
}



#endif //_TOBJNAMEDICTIONARY_H_

⌨️ 快捷键说明

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