2016-03-12 01:20:51 +01:00
|
|
|
/* Copyright (c) 2002-2012 Croteam Ltd.
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
|
|
it under the terms of version 2 of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation
|
|
|
|
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License along
|
|
|
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
|
|
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
|
2016-03-11 14:57:17 +01:00
|
|
|
|
|
|
|
#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
|
2016-03-29 03:03:54 +02:00
|
|
|
if ( this->da_BlocksList.IsEmpty()
|
|
|
|
|| &this->da_BlocksList.Head()==&this->da_BlocksList.Tail()) {
|
2016-03-11 14:57:17 +01:00
|
|
|
// 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)
|
|
|
|
{
|
2016-03-29 03:03:54 +02:00
|
|
|
return this->da_Pointers;
|
2016-03-11 14:57:17 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* 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. */
|
|
|
|
|