I have 2 classes I use in my library for pulling unique indices, though I think I only use them for my particle system. For other things I just store instances in a vector where finding a unique ID isn't important.
h
//=========================================================
// Class allowing you to get a unique 0-based index, once
// done you can pass the ID back so it can be used again.
// This class has has a limit to how many unique IDs it can
// return, a return of -1 indicates a full list.
//=========================================================
class StaticIDHandler abstract
{
// Data members
i32 ecMax,
ecDelCount,
* ecDelList,
ecTop;
protected:
// Constructor(s)/Destructor
StaticIDHandler( u32 maxID );
~StaticIDHandler();
// Methods
i32 GetFreeID();
void AddFreeID( u32 ID );
};
//=========================================================
// Class allowing you to get a unique 0-based index, once
// done you can pass the ID back so it can be used again.
// This class automatically resizes the deletion list if it
// ever becomes too small.
//=========================================================
class DynamicIDHandler abstract
{
// Data members
i32 ecChunkSize,
ecMax,
ecDelCount,
* ecDelList,
ecTop;
protected:
// Constructor(s)/Destructor
DynamicIDHandler( u32 chunkSize = 500 );
~DynamicIDHandler();
public:
// Methods
i32 GetFreeID();
void AddFreeID( u32 ID );
};
cpp
//---------------------------------------------------------
// Constructor.
//---------------------------------------------------------
StaticIDHandler::StaticIDHandler( u32 maxID ) : ecMax(maxID - 1)
{
ecDelList = new i32[maxID];
ecDelCount = 0;
ecTop = -1;
}
//---------------------------------------------------------
// Destructor.
//---------------------------------------------------------
StaticIDHandler::~StaticIDHandler()
{
delete [] ecDelList;
}
//---------------------------------------------------------
// Get an unused ID, return -1 if there are none left.
//---------------------------------------------------------
i32 StaticIDHandler::GetFreeID()
{
if ( ecDelCount )
return ecDelList[--ecDelCount];
else
{
if ( ecTop < ecMax )
return ++ecTop;
else
return -1;
}
}
//---------------------------------------------------------
// Add an unused ID to the list.
//---------------------------------------------------------
void StaticIDHandler::AddFreeID( u32 ID )
{
ecDelList[ecDelCount++] = ID;
}
//---------------------------------------------------------
// Constructor.
//---------------------------------------------------------
DynamicIDHandler::DynamicIDHandler( u32 chunkSize ) : ecChunkSize(chunkSize), ecMax(chunkSize)
{
ecDelList = (i32*)malloc( chunkSize * sizeof(u32) );
ecDelCount = 0;
ecTop = -1;
}
//---------------------------------------------------------
// Destructor.
//---------------------------------------------------------
DynamicIDHandler::~DynamicIDHandler()
{
free( ecDelList );
}
//---------------------------------------------------------
// Get an unused ID, return -1 if there are none left.
//---------------------------------------------------------
i32 DynamicIDHandler::GetFreeID()
{
if ( ecDelCount )
return ecDelList[--ecDelCount];
else
return ++ecTop;
}
//---------------------------------------------------------
// Add an unused ID to the list.
//---------------------------------------------------------
void DynamicIDHandler::AddFreeID( u32 ID )
{
ecDelList[ecDelCount++] = ID;
// Resize?
if ( ecDelCount == ecMax )
{
ecMax += ecChunkSize;
ecDelList = (i32*)realloc( ecDelList, ecMax * sizeof(i32) );
}
}
I think I prefixed the variables because they were originally part of one of my particle classes and I prefixed
Effect
Counter as to avoid any potential clashes, but I guess that's redundant now and I'd rather not recompile everything.