📄 resarray.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 + -