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

📄 resarray.cpp

📁 这个是我第一次完成的一个简单的3D ALIEN SHOOTING GAME的RESOURCE MANAGER部分,大家可以看看,然后提点意见~THX
💻 CPP
字号:
// ResArray.cpp
//

// Author:			Lea Hayes
// Date Created:	10/03/2006
// Date Modified:	24/03/2006

#include "Common.h"
#include "ResArray.h"

using namespace Resources;


// ResourceArray - Construction and destruction.

ResourceArray::ResourceArray()
: m_pBegin(NULL)
, m_pEnd(NULL)
, m_pLast(NULL)
, m_nSize(NULL)
, m_bAutoFree(true)
{
	// Automatically update resource array structure where necessary.
	QueryUpdate();
}

ResourceArray::~ResourceArray()
{
	// Free resources from memory.
	Destroy();
}


// Function Name:	Destroy
//
// Author:			Lea Hayes
// Date Created:	10/03/2006
// Date Modified:	10/03/2006
//
// Description:		Free all resources from memory and clear array.
//
void ResourceArray::Destroy()
{
	// Iterate through each resource and free from memory.
	iterator itCur = Begin();
	LPLISTNODE pCurNode = NULL;

	while(itCur.IsValid())
	{
		// Preserve pointer to current element.
		pCurNode = itCur.m_pItem;

		// If resource is valid then free it from memory.
		if(itCur.IsResourceValid())
		{
			itCur->Destroy();
		}

		// Proceed to next element.
		itCur++;

		// Free node from memory.
		delete pCurNode;
	}

	// Reset attributes.
	m_pEnd = m_pLast = m_pBegin = NULL;
	m_nSize = NULL;
}

// Function Name:	ReleaseUnusedResources
//
// Author:			Lea Hayes
// Date Created:	12/03/2006
// Date Modified:	12/03/2006
//
// Description:		Release all unused resources.
//
void ResourceArray::ReleaseUnusedResources()
{
	// Iterate through each resource and free from memory.
	iterator itCur = Begin();
	LPLISTNODE pCurNode = NULL;

	while(itCur.IsValid())
	{
		// Preserve pointer to current element.
		pCurNode = itCur.m_pItem;

		// If resource is valid and is nolonger in use then release it
		// from memory.
		if(itCur.IsResourceValid() && !itCur->IsResourceBeingUsed())
		{
			itCur->Destroy();

			// Proceed to next element.
			itCur++;

			// Free node from memory.
			delete pCurNode;
		}
		else
		{
			// Proceed to next element.
			itCur++;
		}
	}

	// Reset attributes.
	m_pEnd = m_pLast = m_pBegin = NULL;
	m_nSize = NULL;
}


// ResourceArray - Resource handles and iterations.

const ResourceArray::ResHandle ResourceArray::NullHandle(NULL);
const ResourceArray::iterator ResourceArray::NullIterator(NULL);


// ResourceArray - Array manipulation.


// Function Name:	Insert
//
// Author:			Lea Hayes
// Date Created:	11/03/2006
// Date Modified:	11/03/2006
//
// Description:		Insert resource at specified location.
//
void ResourceArray::Insert(ResourceArray::iterator& itPos,
						   LPRESOURCE pRes)
{
	// Automatically update resource array structure where necessary.
	QueryUpdate();

	// Create new resource node and populate with resource.
	LPRESLISTNODE pNewNode = new ResListNode(pRes);
	pRes->Attach(this);

	// Link node into list.
	//

	// First assign the nodes previous and next pointers.
	pNewNode->m_pPrev = (*itPos)->m_pPrev;
	pNewNode->m_pNext = itPos;

	// If necessary attach beginning of list to node.
	if(m_pBegin == itPos.m_pItem)
	{
		m_pBegin = pNewNode;
	}

	// If the end of array node follows then attach this node to
	// the last node pointer. Otherwise if the last and end references
	// are identical then point last reference to that new node.
	//
	// Bug fix resulting from Test #003.
	//
	if(m_pEnd == itPos.m_pItem || m_pLast == m_pEnd)
	{
		m_pLast = pNewNode;
	}

	// Secondly assign the previous nodes' next reference to that of
	// the newly created node.
	if(!pNewNode->IsBeginNode())
	{
		pNewNode->m_pPrev->m_pNext = pNewNode;
	}

	// Finally assign the next nodes' previous reference to that of
	// the newly created node.
	pNewNode->m_pNext->m_pPrev = pNewNode;

	// Increment resource node size.
	m_nSize++;

	// Update all resource node indexes.
	UpdateIndexes();
}

// Function Name:	Append
//
// Author:			Lea Hayes
// Date Created:	11/03/2006
// Date Modified:	11/03/2006
//
// Description:		Append resource to end of array.
//
void ResourceArray::Append(LPRESOURCE pRes)
{
	// Insert resource at end of array.
	Insert(End(), pRes);
}

//// Function Name:	Aquire
////
//// Author:			Lea Hayes
//// Date Created:	12/03/2006
//// Date Modified:	12/03/2006
////
//// Description:		Aquire handle to resource.
////
//ResourceArray::ResHandle ResourceArray::Aquire(DWORD dwUniqueResID)
//{
//	// Retrieve resource by its unique resource ID.
//	iterator itCur = Begin();
//	iterator itEnd = End();
//
//	for(; itCur != itEnd; itCur++)
//	{
//		// If this unique resource ID matches then...
//		if(itCur->GetUniqueID() == dwUniqueResID)
//		{
//			// Aquire and return a resource handle.
//			return Aquire(itCur);
//		}
//	}
//
//	// Resource was not found.
//	return NullHandle;
//}

// Function Name:	Aquire
//
// Author:			Lea Hayes
// Date Created:	12/03/2006
// Date Modified:	12/03/2006
//
// Description:		Aquire handle to resource.
//
ResourceArray::ResHandle ResourceArray::Aquire(ResHandle& handle)
{
	// If resource handle is invalid then return a null handle.
	if(!handle.IsResourceValid())
		return NullHandle;

	// Aquire resource handle.
	handle->m_dwUsage++;

	// Return handle.
	return handle;
}

// Function Name:	Aquire
//
// Author:			Lea Hayes
// Date Created:	12/03/2006
// Date Modified:	12/03/2006
//
// Description:		Aquire handle to resource.
//
ResourceArray::ResHandle ResourceArray::AquireByIndex(size_t nIndex)
{
	// Generate a resource handle and aquire it.
	return Aquire(ResHandle(Begin() + nIndex));
}

// Function Name:	Release
//
// Author:			Lea Hayes
// Date Created:	11/03/2006
// Date Modified:	11/03/2006
//
// Description:		Release resource from array at specified location.
//
void ResourceArray::Release(iterator& itPos)
{
	// If resource is not valid then skip.
	if(!itPos.IsValid() || itPos == End())
		return;

	// Assume that the resource is nolonger required and then attempt to
	// proove that assumption wrong.
	bool bDestroy = true;

	// If resource is still in use then...
	if(itPos->IsResourceBeingUsed())
	{
		// Decrement usage counter and then determine whether or not the
		// resource is still in use.

		bDestroy = --itPos->m_dwUsage == 0;
	}

	// If resource is not to be destroyed then skip function.
	if(!bDestroy || !IsAutoFreeUnused())
		return;

	// Iterate through each resource and free from memory.
	LPLISTNODE pCurNode = itPos.m_pItem;

	// Before node is destroyed left and right nodes must be attached
	// together in some way.
	if(pCurNode->m_pPrev != NULL)
		pCurNode->m_pPrev->m_pNext = pCurNode->m_pNext;
	else
		m_pBegin = pCurNode->m_pNext;

	// There should always be a next node by this point because the
	// end node cannot be released directly.
	pCurNode->m_pNext->m_pPrev = pCurNode->m_pPrev;

	// If the node in question is referenced by the last pointer then
	// the last pointer must be maintained.
	if(m_pLast == pCurNode)
	{
		// Redirect the last node pointer to the element preeceding
		// the one being released.
		//
		// Bug fix resulting from Test #003.
		//
		if(pCurNode->m_pPrev != NULL)
			m_pLast = pCurNode->m_pPrev;
		else
			m_pLast = m_pEnd;
	}

	// If resource is valid then free it from memory.
	if(itPos.IsResourceValid())
	{
		itPos->Destroy();
	}

	// Free node from memory.
	delete pCurNode;

	itPos.m_pItem = NULL;

	// Decrement resource array size.
	m_nSize--;

	// Update all resource node indexes.
	UpdateIndexes();
}

// Function Name:	Release
//
// Author:			Lea Hayes
// Date Created:	11/03/2006
// Date Modified:	11/03/2006
//
// Description:		Release resource from array at specified location.
//
void ResourceArray::Release(size_t nIndex)
{
	// Release resource at index specified.
	Release(Begin() + nIndex);
}

// Function Name:	Release
//
// Author:			Lea Hayes
// Date Created:	11/03/2006
// Date Modified:	11/03/2006
//
// Description:		Release resource from array at specified location.
//
void ResourceArray::Release(LPRESOURCE pRes)
{
	// Find resource specified and release.
	iterator itRelease = Find(pRes);

	if(itRelease.IsValid())
	{
		Release(itRelease);
	}
}

// Function Name:	Find
//
// Author:			Lea Hayes
// Date Created:	11/03/2006
// Date Modified:	11/03/2006
//
// Description:		Retrieve iterator to resource specified; when not
//					found a NULL iterator is returned.
//
ResourceArray::iterator ResourceArray::Find(LPRESOURCE pRes)
{
	// If no resource has been specified then it will not be found
	// within the resource array; so suppress.

	if(pRes == NULL)
	{
		return NullIterator;
	}

	// Iterate through each resoucre until the specified resource is
	// found. If the resource is found then return an iterator to it.

	iterator itCur = Begin();
	iterator itEnd = End();

	for(; itCur != itEnd; itCur++)
	{
		if(pRes == (*itCur)->m_pRes)
		{
			// Return the resource iterator.
			return itCur;
		}
	}

	// Otherwise resource was not found.
	return NullIterator;
}

// Function Name:	Find
//
// Author:			Lea Hayes
// Date Created:	24/03/2006
// Date Modified:	24/03/2006
//
// Description:		Retrieve iterator to resource specified; when not
//					found a NULL iterator is returned.
//
ResourceArray::iterator ResourceArray::Find(DWORD dwUniqueID)
{
	// Iterate through each resource within the array specified.
	iterator itCur = Begin();
	iterator itEnd = End();

	for(; itCur != itEnd; itCur++)
	{
		// If resource has been found then return its handle.
		if(itCur->GetUniqueID() == dwUniqueID)
		{
			return itCur;
		}
	}

	// The resource was not found.
	return NullIterator;
}

// Function Name:	Find
//
// Author:			Lea Hayes
// Date Created:	12/03/2006
// Date Modified:	12/03/2006
//
// Description:		Retrieve iterator to resource specified; when not
//					found a NULL iterator is returned.
//
ResourceArray::iterator ResourceArray::Find(LPCSTR lpszFilePath)
{
	// Iterate through each resource within the array specified.
	iterator itCur = Begin();
	iterator itEnd = End();

	for(; itCur != itEnd; itCur++)
	{
		// If resource has been found then return its handle.
		if(!strcmp(itCur->GetFilePath(), lpszFilePath))
		{
			return itCur;
		}
	}

	// The resource was not found.
	return NullIterator;
}

// Function Name:	FindNext
//
// Author:			Lea Hayes
// Date Created:	24/03/2006
// Date Modified:	24/03/2006
//
// Description:		Retrieve iterator to next resource specified; when
//					not found a NULL iterator is returned.
//
ResourceArray::iterator ResourceArray::FindNext(const iterator& prev,
												DWORD dwUniqueResID)
{
	// Iterate through each resource within the array specified.
	iterator itCur = prev + 1;
	iterator itEnd = End();

	for(; itCur != itEnd; itCur++)
	{
		// If resource has been found then return its handle.
		if(itCur->GetUniqueID() == dwUniqueResID)
		{
			return itCur;
		}
	}

	// The resource was not found.
	return NullIterator;
}

// Function Name:	FindNext
//
// Author:			Lea Hayes
// Date Created:	24/03/2006
// Date Modified:	24/03/2006
//
// Description:		Retrieve iterator to next resource specified; when
//					not found a NULL iterator is returned.
//
ResourceArray::iterator ResourceArray::FindNext(const iterator& prev,
												LPCSTR lpszFilePath)
{
	// Iterate through each resource within the array specified.
	iterator itCur = prev + 1;
	iterator itEnd = End();

	for(; itCur != itEnd; itCur++)
	{
		// If resource has been found then return its handle.
		if(!strcmp(itCur->GetFilePath(), lpszFilePath))
		{
			return itCur;
		}
	}

	// The resource was not found.
	return NullIterator;
}


// ResourceArray - Link list nodes and helper functions.


// Function Name:	CreateDummyNode
//
// Author:			Lea Hayes
// Date Created:	10/03/2006
// Date Modified:	10/03/2006
//
// Description:		Create dummy node to represent end of list.
//
void ResourceArray::CreateDummyNode()
{
	// If list is already linked to one or more nodes then they
	// must first be destroyed.
	if(m_pBegin != NULL)
	{
		Destroy();
	}

	// Create dummy node and attach to list.
	m_pEnd = m_pLast = m_pBegin = new ListNode;
	m_nSize = NULL;
}

// Function Name:	QueryUpdate
//
// Author:			Lea Hayes
// Date Created:	11/03/2006
// Date Modified:	11/03/2006
//
// Description:		Check integrity of resource array.
//
void ResourceArray::QueryUpdate()
{
	// If necessary create the dummy end node.
	if(GetCount() == NULL && m_pBegin == NULL)
	{
		CreateDummyNode();
	}
}

// Function Name:	UpdateIndexes
//
// Author:			Lea Hayes
// Date Created:	11/03/2006
// Date Modified:	11/03/2006
//
// Description:		Update resource node index values.
//
void ResourceArray::UpdateIndexes()
{
	// Iterate through each resource and update its respective node
	// index value.

	iterator itCur = Begin();

	// i <= GetCount();		// Update dummy nodes index value as well.
	for(size_t i = 0; i <= GetCount(); i++, itCur++)
	{
		(*itCur)->m_nIndex = i;
	}
}


// ResourceArray - Properties.


// Function Name:	EnableAutoFreeUnused
//
// Author:			Lea Hayes
// Date Created:	12/03/2006
// Date Modified:	12/03/2006
//
// Description:		Update resource node index values.
//
bool ResourceArray::EnableAutoFreeUnused(bool bEnable /*=true*/)
{
	// If flag has not changed then skip.
	if(m_bAutoFree == bEnable)
		return bEnable;

	// Preserve current flag value for return.
	bool bPrevFlag = m_bAutoFree;

	// Update flag.
	m_bAutoFree = bEnable;

	// If auto free has been enabled then it is possible that
	// their are unused resources are being stored.
	if(m_bAutoFree)
	{
		// Release any unused resources.
		ReleaseUnusedResources();
	}

	// Return previous value.
	return bPrevFlag;
}

⌨️ 快捷键说明

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