mirror of
https://github.com/ptitSeb/Serious-Engine
synced 2024-11-30 05:35:54 +01:00
165 lines
4.0 KiB
C++
165 lines
4.0 KiB
C++
|
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
|
||
|
|
||
|
#ifndef SE_INCL_DYNAMICSTACKARRAY_CPP
|
||
|
#define SE_INCL_DYNAMICSTACKARRAY_CPP
|
||
|
#ifdef PRAGMA_ONCE
|
||
|
#pragma once
|
||
|
#endif
|
||
|
|
||
|
#include <Engine/Templates/DynamicStackArray.h>
|
||
|
#include <Engine/Templates/DynamicArray.cpp>
|
||
|
|
||
|
/*
|
||
|
* Default constructor.
|
||
|
*/
|
||
|
template<class Type>
|
||
|
inline CDynamicStackArray<Type>::CDynamicStackArray(void) : CDynamicArray<Type>() {
|
||
|
da_ctUsed=0;
|
||
|
da_ctAllocationStep = 256;
|
||
|
// lock the array on construction
|
||
|
CDynamicArray<Type>::Lock();
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Destructor.
|
||
|
*/
|
||
|
template<class Type>
|
||
|
inline CDynamicStackArray<Type>::~CDynamicStackArray(void) {
|
||
|
// lock the array on destruction
|
||
|
CDynamicArray<Type>::Unlock();
|
||
|
};
|
||
|
|
||
|
/* Destroy all objects, and reset the array to initial (empty) state. */
|
||
|
template<class Type>
|
||
|
inline void CDynamicStackArray<Type>::Clear(void) {
|
||
|
CDynamicArray<Type>::Clear(); da_ctUsed = 0;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Set how many elements to allocate when stack overflows.
|
||
|
*/
|
||
|
template<class Type>
|
||
|
inline void CDynamicStackArray<Type>::SetAllocationStep(INDEX ctStep)
|
||
|
{
|
||
|
ASSERT(ctStep>0);
|
||
|
da_ctAllocationStep = ctStep;
|
||
|
};
|
||
|
|
||
|
/*
|
||
|
* Add new object(s) on top of stack.
|
||
|
*/
|
||
|
template<class Type>
|
||
|
inline Type &CDynamicStackArray<Type>::Push(void) {
|
||
|
// if there are no free elements in the array
|
||
|
if (CDynamicArray<Type>::Count()-da_ctUsed<1) {
|
||
|
// alocate a new block
|
||
|
CDynamicArray<Type>::New(da_ctAllocationStep);
|
||
|
}
|
||
|
// get the new element
|
||
|
da_ctUsed++;
|
||
|
ASSERT(da_ctUsed <= CDynamicArray<Type>::Count());
|
||
|
return CDynamicArray<Type>::operator[](da_ctUsed-1);
|
||
|
}
|
||
|
template<class Type>
|
||
|
inline Type *CDynamicStackArray<Type>::Push(INDEX ct) {
|
||
|
// if there are no free elements in the array
|
||
|
while(CDynamicArray<Type>::Count()-da_ctUsed<ct) {
|
||
|
// alocate a new block
|
||
|
CDynamicArray<Type>::New(da_ctAllocationStep);
|
||
|
}
|
||
|
// get new elements
|
||
|
da_ctUsed+=ct;
|
||
|
ASSERT(da_ctUsed <= CDynamicArray<Type>::Count());
|
||
|
return &CDynamicArray<Type>::operator[](da_ctUsed-ct);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Remove all objects from stack, but keep stack space.
|
||
|
*/
|
||
|
template<class Type>
|
||
|
inline void CDynamicStackArray<Type>::PopAll(void) {
|
||
|
// if there is only one block allocated
|
||
|
if ( da_BlocksList.IsEmpty()
|
||
|
|| &da_BlocksList.Head()==&da_BlocksList.Tail()) {
|
||
|
// just clear the counter
|
||
|
da_ctUsed = 0;
|
||
|
|
||
|
// if there is more than one block allocated
|
||
|
} else {
|
||
|
// remember how much was allocated, rounded up to allocation step
|
||
|
INDEX ctUsedBefore = CDynamicArray<Type>::Count();
|
||
|
// free all memory
|
||
|
CDynamicArray<Type>::Clear();
|
||
|
// allocate one big block
|
||
|
CDynamicArray<Type>::New(ctUsedBefore);
|
||
|
da_ctUsed = 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Random access operator.
|
||
|
*/
|
||
|
template<class Type>
|
||
|
inline Type &CDynamicStackArray<Type>::operator[](INDEX i) {
|
||
|
ASSERT(this!=NULL);
|
||
|
ASSERT(i<da_ctUsed); // check bounds
|
||
|
return CDynamicArray<Type>::operator[](i);
|
||
|
}
|
||
|
template<class Type>
|
||
|
inline const Type &CDynamicStackArray<Type>::operator[](INDEX i) const {
|
||
|
ASSERT(this!=NULL);
|
||
|
ASSERT(i<da_ctUsed); // check bounds
|
||
|
return CDynamicArray<Type>::operator[](i);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Get number of elements in array.
|
||
|
*/
|
||
|
template<class Type>
|
||
|
INDEX CDynamicStackArray<Type>::Count(void) const {
|
||
|
ASSERT(this!=NULL);
|
||
|
return da_ctUsed;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Get index of a member from it's pointer
|
||
|
*/
|
||
|
template<class Type>
|
||
|
INDEX CDynamicStackArray<Type>::Index(Type *ptMember) {
|
||
|
ASSERT(this!=NULL);
|
||
|
INDEX i = CDynamicArray<Type>::Index(ptMember);
|
||
|
ASSERTMSG(i<da_ctUsed, "CDynamicStackArray<>::Index(): Not a member of this array!");
|
||
|
return i;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Get array of pointers to elements (used for sorting elements by sorting pointers).
|
||
|
*/
|
||
|
template<class Type>
|
||
|
Type **CDynamicStackArray<Type>::GetArrayOfPointers(void)
|
||
|
{
|
||
|
return da_Pointers;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Assignment operator.
|
||
|
*/
|
||
|
template<class Type>
|
||
|
CDynamicStackArray<Type> &CDynamicStackArray<Type>::operator=(CDynamicStackArray<Type> &arOriginal)
|
||
|
{
|
||
|
ASSERT(this!=NULL);
|
||
|
ASSERT(&arOriginal!=NULL);
|
||
|
ASSERT(this!=&arOriginal);
|
||
|
|
||
|
// copy stack arrays
|
||
|
CDynamicArray<Type>::operator=(arOriginal);
|
||
|
// copy used count
|
||
|
da_ctUsed = arOriginal.da_ctUsed;
|
||
|
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
|
||
|
#endif /* include-once check. */
|
||
|
|