Initial commit
This commit is contained in:
399
Include/ZUtil/ZReferenceBuffer.hpp
Normal file
399
Include/ZUtil/ZReferenceBuffer.hpp
Normal file
@@ -0,0 +1,399 @@
|
||||
/*
|
||||
ZReferenceBuffer.hpp
|
||||
Author: James Russell
|
||||
|
||||
Purpose : Acts as a means of storing arbitrary types of values in an array which gives back index-based references to
|
||||
pointers of those types of values. Handles, internally, the Buffer overflowing and looping back around
|
||||
the end of the storage array.
|
||||
|
||||
Changelog :
|
||||
2/11/10 - Creation (jcr2)
|
||||
2/13/10 - Should be working as advertised (jcr)
|
||||
3/04/10 - NOW working as advertised (jcr)
|
||||
|
||||
*/
|
||||
|
||||
#ifndef _ZREFERENCEBUFFER_H
|
||||
#define _ZREFERENCEBUFFER_H
|
||||
|
||||
#include <ZUtil/ZAlloc.hpp>
|
||||
#include <ZUtil/ZAssert.hpp>
|
||||
#include <ZSTL/ZArray.hpp>
|
||||
#include <ZSTL/ZList.hpp>
|
||||
|
||||
#define ZRB_DEFAULT_BUFFER_SIZE (10)
|
||||
#define ZRB_INVALID_HANDLE (-1)
|
||||
|
||||
typedef int ZReferenceBufferHandle;
|
||||
|
||||
template <typename T>
|
||||
class ZReferenceBuffer
|
||||
{
|
||||
protected:
|
||||
//The Current Index Value (next value to be assigned)
|
||||
int CurrentIndex;
|
||||
|
||||
//The Current Size of the Buffer (Storage Capacity)
|
||||
int BufferSize;
|
||||
|
||||
//The Current Number of Items contained in the Buffer
|
||||
int ItemCount;
|
||||
|
||||
//Indicator array used to indicate which indices of the Buffer are valid
|
||||
ZArray<int> Indicator;
|
||||
|
||||
//Buffer of T* Values
|
||||
ZArray<T*> Buffer;
|
||||
|
||||
//Checks if a given reference is valid
|
||||
inline bool IsValid(int index);
|
||||
|
||||
//Checks if a given reference is invalid
|
||||
inline bool IsInvalid(int index);
|
||||
|
||||
//Sets the Indicator of an index to valid
|
||||
inline void SetValid(int index);
|
||||
|
||||
//Sets the Indicator of an index to invalid
|
||||
inline void SetInvalid(int index);
|
||||
|
||||
public:
|
||||
|
||||
/*
|
||||
Default constructor.
|
||||
*/
|
||||
ZReferenceBuffer();
|
||||
|
||||
/*
|
||||
Constructor.
|
||||
|
||||
@param _size - The starting size of the reference buffer.
|
||||
*/
|
||||
ZReferenceBuffer(int _size);
|
||||
|
||||
/*
|
||||
Constructor.
|
||||
|
||||
@param _allocator - the allocator to use for allocations / deallocations in the reference buffer
|
||||
*/
|
||||
ZReferenceBuffer(ZArrayAllocator<T> *_allocator);
|
||||
|
||||
/*
|
||||
Constructor.
|
||||
|
||||
@param _size - The starting size of the reference buffer.
|
||||
@param _allocator - the allocator to use for allocations / deallocations in the reference buffer
|
||||
*/
|
||||
ZReferenceBuffer( int _size, ZArrayAllocator<T> *_allocator);
|
||||
|
||||
/*
|
||||
Destructor.
|
||||
*/
|
||||
~ZReferenceBuffer();
|
||||
|
||||
/*
|
||||
public ZReferenceBuffer::AddItem
|
||||
|
||||
Adds the item to the reference Buffer, returning a handle. Resizes the Buffer automatically to
|
||||
increase the size of the buffer if full.
|
||||
|
||||
@param _item - the item to add to the buffer
|
||||
|
||||
@return (ZReferenceBufferHandle) - a ZReferenceBufferHandle which can be used to reference item, Will never return NULL.
|
||||
*/
|
||||
ZReferenceBufferHandle AddItem(T _item);
|
||||
|
||||
/*
|
||||
public ZReferenceBuffer::GetItem
|
||||
|
||||
Gets an item in the Buffer given a reference handle.
|
||||
|
||||
@param _ref - the reference handle to the item you wish to get
|
||||
|
||||
@return (T&) - the item the handle refers to
|
||||
*/
|
||||
T& GetItem(ZReferenceBufferHandle _ref);
|
||||
|
||||
/*
|
||||
public ZReferenceBuffer::SetItem
|
||||
|
||||
Attempts to set the reference to map to the provided item. Used for updating references.
|
||||
|
||||
@param _ref - a valid reference handle to update. If NULL, will set the null handle, allowing a NULL reference to be valid.
|
||||
@param _item - the item to update the reference to
|
||||
|
||||
@return (T) - the overwritten value that ref pointed to
|
||||
*/
|
||||
T SetItem(ZReferenceBufferHandle _ref, T _item);
|
||||
|
||||
/*
|
||||
public ZReferenceBuffer::RemoveItem
|
||||
|
||||
Removes an item from the Buffer given a reference handle and invalidates the handle (until reassigned).
|
||||
|
||||
@param _ref - the reference handle to the item you wish to remove
|
||||
|
||||
@return (T) - the item removed
|
||||
*/
|
||||
T RemoveItem(ZReferenceBufferHandle _ref);
|
||||
|
||||
/*
|
||||
public ZReferenceBuffer::Remove
|
||||
|
||||
Removes all occurrences of an item from the Buffer given a pointer to the item.
|
||||
|
||||
@param _item - the item you wish to remove
|
||||
|
||||
@return (void)
|
||||
*/
|
||||
void Remove(T _item);
|
||||
|
||||
/*
|
||||
public ZReferenceBuffer::Size
|
||||
|
||||
Gets the current size of the buffer.
|
||||
|
||||
@return (int) - the size (capacity) of the buffer
|
||||
*/
|
||||
int Size();
|
||||
|
||||
/*
|
||||
public ZReferenceBuffer::Count
|
||||
|
||||
Returns the number of elements currently stored in the Buffer
|
||||
|
||||
@return (int) - the count (number of items) in the buffer
|
||||
*/
|
||||
int Count();
|
||||
|
||||
/*
|
||||
public ZReferenceBuffer::Items
|
||||
|
||||
Returns a ZList containing the elements of the reference Buffer.
|
||||
|
||||
@return (ZList<T>) - a list containing all the values currently in the buffer
|
||||
*/
|
||||
ZList<T> Items();
|
||||
|
||||
/*
|
||||
inline public ZReferenceBuffer::IsFull
|
||||
|
||||
Returns true if the Buffer is full, false otherwise.
|
||||
|
||||
@return (bool) - boolean indicating the buffer is full
|
||||
*/
|
||||
inline bool IsFull();
|
||||
|
||||
/*
|
||||
public ZReferenceBuffer::Resize
|
||||
|
||||
Resizes the Buffer to store _newSize number of elements. Already existing references remain valid. Returns true
|
||||
on success, false otherwise. Newsize must be greater than the current size of the reference Buffer.
|
||||
|
||||
@param _newSize - the ZNew capacity of the buffer
|
||||
|
||||
@return (bool) - boolean indicating success or failure
|
||||
*/
|
||||
bool Resize( int _newSize);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
ZReferenceBuffer<T>::ZReferenceBuffer( int _size, ZArrayAllocator<T>* _allocator)
|
||||
: CurrentIndex(1), BufferSize(_size+1), ItemCount(0), Allocator(_allocator)
|
||||
{
|
||||
this->Buffer.Resize(BufferSize);
|
||||
this->Indicator.Resize(this->BufferSize, false);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
ZReferenceBuffer<T>::ZReferenceBuffer( int _size)
|
||||
: CurrentIndex(1), BufferSize(_size+1), ItemCount(0)
|
||||
{
|
||||
this->Buffer.Resize(BufferSize);
|
||||
this->Indicator.Resize(this->BufferSize, false);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
ZReferenceBuffer<T>::ZReferenceBuffer(ZArrayAllocator<T>* _allocator)
|
||||
: CurrentIndex(1), BufferSize(ZRB_DEFAULT_BUFFER_SIZE+1), ItemCount(0), Allocator(_allocator)
|
||||
{
|
||||
this->Buffer.Resize(BufferSize);
|
||||
this->Indicator.Resize(this->BufferSize, false);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
ZReferenceBuffer<T>::ZReferenceBuffer()
|
||||
: CurrentIndex(1), BufferSize(ZRB_DEFAULT_BUFFER_SIZE+1), ItemCount(0)
|
||||
{
|
||||
this->Buffer.Resize(BufferSize);
|
||||
this->Indicator.Resize(this->BufferSize, false);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
ZReferenceBuffer<T>::~ZReferenceBuffer()
|
||||
{
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool ZReferenceBuffer<T>::IsValid(int _index)
|
||||
{
|
||||
if (_index >= 0)
|
||||
return this->Indicator[_index] != 0;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool ZReferenceBuffer<T>::IsInvalid(int _index)
|
||||
{
|
||||
return !IsValid(_index);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void ZReferenceBuffer<T>::SetValid( int _index)
|
||||
{
|
||||
this->Indicator[_index] = 1;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void ZReferenceBuffer<T>::SetInvalid( int _index)
|
||||
{
|
||||
this->Indicator[_index] = 0;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
ZReferenceBufferHandle ZReferenceBuffer<T>::AddItem(T _item)
|
||||
{
|
||||
int startIndex;
|
||||
int ref;
|
||||
|
||||
//CurrentIndex should only be zero if Buffer is full
|
||||
if (this->CurrentIndex == 0)
|
||||
return this->CurrentIndex;
|
||||
|
||||
ref = startIndex = this->CurrentIndex;
|
||||
|
||||
while (this->IsValid(this->CurrentIndex))
|
||||
{
|
||||
this->CurrentIndex++;
|
||||
ref = this->CurrentIndex;
|
||||
|
||||
if (this->CurrentIndex == startIndex)
|
||||
this->Resize(this->BufferSize * 2);
|
||||
|
||||
if (this->CurrentIndex >= this->BufferSize)
|
||||
ref = this->CurrentIndex = 1;
|
||||
}
|
||||
|
||||
if (ref != -1)
|
||||
{
|
||||
this->Buffer[ref] = _item;
|
||||
this->SetValid(ref);
|
||||
|
||||
this->ItemCount++;
|
||||
}
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T& ZReferenceBuffer<T>::GetItem(ZReferenceBufferHandle _ref)
|
||||
{
|
||||
ZASSERT(this->IsValid(_ref), "ERROR: ZReferenceBuffer::GetItemRef passed invalid reference!");
|
||||
|
||||
return this->Buffer[_ref];
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T ZReferenceBuffer<T>::RemoveItem(ZReferenceBufferHandle _ref)
|
||||
{
|
||||
T item;
|
||||
|
||||
ZASSERT( this->IsValid(_ref) , "ERROR: ZReferenceBuffer::RemoveItem passed invalid reference!" );
|
||||
|
||||
this->ItemCount--;
|
||||
this->SetInvalid(_ref);
|
||||
item = this->Buffer[_ref];
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void ZReferenceBuffer<T>::Remove(T _item)
|
||||
{
|
||||
for ( int i = 0; i < this->BufferSize; i++)
|
||||
if (this->Buffer[i] == _item)
|
||||
this->RemoveItem(i);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T ZReferenceBuffer<T>::SetItem(int _ref, T _item)
|
||||
{
|
||||
T ret;
|
||||
|
||||
ret = this->Buffer[_ref];
|
||||
this->Buffer[_ref] = _item;
|
||||
|
||||
this->SetValid(_ref);
|
||||
|
||||
this->ItemCount++;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
int ZReferenceBuffer<T>::Size()
|
||||
{
|
||||
return this->BufferSize;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
int ZReferenceBuffer<T>::Count()
|
||||
{
|
||||
return this->ItemCount;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool ZReferenceBuffer<T>::IsFull()
|
||||
{
|
||||
return (!this->CurrentIndex);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool ZReferenceBuffer<T>::Resize( int _newSize)
|
||||
{
|
||||
if (_newSize < this->BufferSize)
|
||||
return false;
|
||||
|
||||
this->BufferSize = _newSize + 1;
|
||||
|
||||
ZArray<T*> newBuffer;
|
||||
newBuffer.Resize(this->BufferSize);
|
||||
|
||||
for ( int i = 0; i < this->BufferSize; i++)
|
||||
newBuffer[i] = this->Buffer[i];
|
||||
|
||||
this->Indicator.Resize(this->BufferSize, false);
|
||||
|
||||
this->Buffer = newBuffer;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
ZList<T> ZReferenceBuffer<T>::Items()
|
||||
{
|
||||
int i;
|
||||
ZList<T> items;
|
||||
|
||||
for (i = 1; i < this->BufferSize; i++)
|
||||
{
|
||||
if (this->IsValid(i))
|
||||
items.PushBack(this->Buffer[i]);
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user