mirror of
https://github.com/ptitSeb/Serious-Engine
synced 2024-11-25 03:40:26 +01:00
203 lines
5.0 KiB
C++
203 lines
5.0 KiB
C++
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
|
|
|
|
|
|
#ifndef SE_INCL_ALLOCATIONARRAY_CPP
|
|
#define SE_INCL_ALLOCATIONARRAY_CPP
|
|
#ifdef PRAGMA_ONCE
|
|
#pragma once
|
|
#endif
|
|
|
|
#include <Engine/Templates/StaticStackArray.h>
|
|
#include <Engine/Templates/StaticStackArray.cpp>
|
|
#include <Engine/Templates/StaticArray.cpp>
|
|
|
|
extern BOOL _bAllocationArrayParanoiaCheck;
|
|
|
|
/*
|
|
* Default constructor.
|
|
*/
|
|
template<class Type>
|
|
inline CAllocationArray<Type>::CAllocationArray(void) :
|
|
CStaticArray<Type>(),
|
|
aa_aiFreeElements()
|
|
{
|
|
aa_ctAllocationStep = 256;
|
|
}
|
|
|
|
/*
|
|
* Destructor.
|
|
*/
|
|
template<class Type>
|
|
inline CAllocationArray<Type>::~CAllocationArray(void) {
|
|
};
|
|
|
|
/* Destroy all objects, and reset the array to initial (empty) state. */
|
|
template<class Type>
|
|
inline void CAllocationArray<Type>::Clear(void) {
|
|
// delete the objects themselves
|
|
CStaticArray<Type>::Clear();
|
|
// clear array of free indices
|
|
aa_aiFreeElements.Clear();
|
|
}
|
|
|
|
/*
|
|
* Set how many elements to allocate when stack overflows.
|
|
*/
|
|
template<class Type>
|
|
inline void CAllocationArray<Type>::SetAllocationStep(INDEX ctStep)
|
|
{
|
|
ASSERT(ctStep>0);
|
|
aa_ctAllocationStep = ctStep;
|
|
};
|
|
|
|
/*
|
|
* Create a given number of objects.
|
|
*/
|
|
template<class Type>
|
|
inline void CAllocationArray<Type>::New(INDEX iCount) {
|
|
// never call this!
|
|
ASSERT(FALSE);
|
|
};
|
|
|
|
/*
|
|
* Destroy all objects.
|
|
*/
|
|
template<class Type>
|
|
inline void CAllocationArray<Type>::Delete(void) {
|
|
// never call this!
|
|
ASSERT(FALSE);
|
|
}
|
|
|
|
/* Alocate a new object. */
|
|
template<class Type>
|
|
inline INDEX CAllocationArray<Type>::Allocate(void)
|
|
{
|
|
// if there are no more free indices
|
|
if (aa_aiFreeElements.Count()==0) {
|
|
// remember old size
|
|
INDEX ctOldSize = CStaticArray<Type>::Count();
|
|
// expand the array by the allocation step
|
|
Expand(ctOldSize+aa_ctAllocationStep);
|
|
// create new free indices
|
|
INDEX *piNewFree = aa_aiFreeElements.Push(aa_ctAllocationStep);
|
|
// fill them up
|
|
for(INDEX iNew=0; iNew<aa_ctAllocationStep; iNew++) {
|
|
piNewFree[iNew] = ctOldSize+iNew;
|
|
}
|
|
}
|
|
// pop one free index from the top of stack, and use that one
|
|
return aa_aiFreeElements.Pop();
|
|
}
|
|
/* Free object with given index. */
|
|
template<class Type>
|
|
inline void CAllocationArray<Type>::Free(INDEX iToFree)
|
|
{
|
|
#ifndef NDEBUG
|
|
// must be within pool limits
|
|
ASSERT(iToFree>=0 && iToFree<CStaticArray<Type>::Count());
|
|
// must not be free
|
|
if (_bAllocationArrayParanoiaCheck) {
|
|
ASSERT(IsAllocated(iToFree));
|
|
}
|
|
#endif
|
|
// push its index on top of the free stack
|
|
aa_aiFreeElements.Push() = iToFree;
|
|
}
|
|
|
|
/* Free all objects, but keep pool space. */
|
|
template<class Type>
|
|
inline void CAllocationArray<Type>::FreeAll(void)
|
|
{
|
|
// clear the free array
|
|
aa_aiFreeElements.PopAll();
|
|
// push as much free elements as there is pool space
|
|
INDEX ctSize = CStaticArray<Type>::Count();
|
|
INDEX *piNewFree = aa_aiFreeElements.Push(ctSize);
|
|
// fill them up
|
|
for(INDEX iNew=0; iNew<ctSize; iNew++) {
|
|
piNewFree[iNew] = iNew;
|
|
}
|
|
}
|
|
|
|
// check if an index is allocated (slow!)
|
|
template<class Type>
|
|
inline BOOL CAllocationArray<Type>::IsAllocated(INDEX i)
|
|
{
|
|
// must be within pool limits
|
|
ASSERT(i>=0 && i<CStaticArray<Type>::Count());
|
|
// for each free index
|
|
INDEX ctFree = aa_aiFreeElements.Count();
|
|
for(INDEX iFree=0; iFree<ctFree; iFree++) {
|
|
// if it is that one
|
|
if (aa_aiFreeElements[iFree]==i) {
|
|
// it is not allocated
|
|
return FALSE;
|
|
}
|
|
}
|
|
// if not found as free, it is allocated
|
|
return TRUE;
|
|
}
|
|
|
|
/* Random access operator. */
|
|
template<class Type>
|
|
inline Type &CAllocationArray<Type>::operator[](INDEX iObject)
|
|
{
|
|
#ifndef NDEBUG
|
|
ASSERT(this!=NULL);
|
|
// must be within pool limits
|
|
ASSERT(iObject>=0 && iObject<CStaticArray<Type>::Count());
|
|
// must not be free
|
|
if (_bAllocationArrayParanoiaCheck) {
|
|
ASSERT(IsAllocated(iObject));
|
|
}
|
|
#endif
|
|
return CStaticArray<Type>::operator[](iObject);
|
|
}
|
|
template<class Type>
|
|
inline const Type &CAllocationArray<Type>::operator[](INDEX iObject) const
|
|
{
|
|
#ifndef NDEBUG
|
|
ASSERT(this!=NULL);
|
|
// must be within pool limits
|
|
ASSERT(iObject>=0 && iObject<CStaticArray<Type>::Count());
|
|
// must not be free
|
|
if (_bAllocationArrayParanoiaCheck) {
|
|
ASSERT(IsAllocated(iObject));
|
|
}
|
|
#endif
|
|
return CStaticArray<Type>::operator[](iObject);
|
|
}
|
|
/* Get number of allocated objects in array. */
|
|
template<class Type>
|
|
INDEX CAllocationArray<Type>::Count(void) const
|
|
{
|
|
ASSERT(this!=NULL);
|
|
// it is pool size without the count of free elements
|
|
return CStaticArray<Type>::Count()-aa_aiFreeElements.Count();
|
|
}
|
|
|
|
/* Get index of a object from it's pointer. */
|
|
template<class Type>
|
|
INDEX CAllocationArray<Type>::Index(Type *ptObject)
|
|
{
|
|
ASSERT(this!=NULL);
|
|
INDEX i = CStaticArray<Type>::Index(ptMember);
|
|
ASSERT(IsAllocated(i));
|
|
return i;
|
|
}
|
|
|
|
/* Assignment operator. */
|
|
template<class Type>
|
|
CAllocationArray<Type> &CAllocationArray<Type>::operator=(
|
|
const CAllocationArray<Type> &aaOriginal)
|
|
{
|
|
ASSERT(this!=NULL);
|
|
(CStaticArray<Type>&)(*this) = (CStaticArray<Type>&)aaOriginal;
|
|
aa_aiFreeElements = aaOriginal.aa_aiFreeElements;
|
|
aa_ctAllocationStep = aaOriginal.aa_ctAllocationStep;
|
|
}
|
|
|
|
|
|
#endif /* include-once check. */
|
|
|