/* orxonox - the future of 3D-vertical-scrollers Copyright (C) 2004 orx This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. ### File Specific: main-programmer: Benjamin Grauer co-programmer: ... */ /*! @file array.h @brief Contains the Array Class that handles arrays of classes. this class creates a Array of a semi-Dynamic length. beware, that after finalizing the array may not be resized again. */ #ifndef _ARRAY_H #define _ARRAY_H #include "debug.h" //! Array Class that handles dynamic-type arrays. template class Array { public: Array (); ~Array(); void finalizeArray (); void addEntry (T entry); void addEntry(T entry0, T entry1, T entry2); /** @returns The array */ inline T* getArray () const { return this->array; }; inline const T getEntry(unsigned int number) const; /** * @returns The Count of entries in the Array*/ inline unsigned int getCount()const { return this->entryCount; }; inline int getIndex(T* entry) const; inline bool isFinalized() const { return this->finalized; } void debug() const ; private: //! One entry of the Array struct Entry { T value; //!< The value of this Entry. Entry* next; //!< Pointer to the Next entry. }; T* array; //!< The array that will be produced when finalizing the Array. unsigned int entryCount; //!< The count of Entries in this Array. bool finalized; //!< If this variable is set to true, the Array can not be changed anymore. true if finalized, false else (initially). Entry* firstEntry; //!< Pointer to the first Entry of this Array Entry* currentEntry; //!< Pointer to the current Entry of this Array. The one Entry we are working with. }; /** * creates a new Array */ template Array::Array () { PRINTF(5)("crating new Array\n"); this->firstEntry = new Entry; this->firstEntry->next =NULL; this->currentEntry = this->firstEntry; this->finalized = false; this->entryCount = 0; //0 means one entry } template const T Array::getEntry(unsigned int number) const { if (this->finalized && number < this->entryCount) return this->array[number]; } /** * deletes an Array. It does this by first deleting all the array-entries, and then delete the array[] itself */ template Array::~Array() { PRINTF(5)("deleting array\n"); if (!this->finalized) { Entry* walker = this->firstEntry; Entry* previous; while (walker) { previous = walker; walker = walker->next; delete previous; } } if (this->finalized) delete[] this->array; } /** * finalizes an array. This Function creates the array, and makes it ready to be sent to the application. */ template void Array::finalizeArray () { if (this->finalized) return; PRINTF(5)("Finalizing array. Length: %i\n", entryCount); if (!(this->array = new T [this->entryCount])) PRINTF(1)("could not allocate %i data Blocks\n", this->entryCount); Entry* walker = this->firstEntry; for (int i=0; i < this->entryCount; i++) { this->array[i] = walker->value; walker = walker->next; } walker = this->firstEntry; Entry* previous; while (walker) { previous = walker; walker = walker->next; delete previous; } this->firstEntry = NULL; this->finalized = true; } /** * adds a new Entry to the Array * @param entry Entry to add. */ template void Array::addEntry (T entry) { if (!this->finalized) { PRINTF(5)("adding new Entry to Array: %f\n", entry); this->currentEntry->value = entry; this->currentEntry->next = new Entry; this->currentEntry = currentEntry->next; this->currentEntry->next = NULL; ++this->entryCount; } else PRINTF(2)("adding failed, because array has already been finalized\n"); } /** * Adds 3 entries at once (convenience) */ template void Array::addEntry (T entry0, T entry1, T entry2) { this->addEntry(entry0); this->addEntry(entry1); this->addEntry(entry2); } /** * gets back the index of the entry in the array. value check * @param entry: the entry to look up * @returns the index in the array, -1 if not found */ template int Array::getIndex(T* entry) const { if( unlikely(this->finalized == false)) return -1; for(int i = 0; i < this->entryCount; ++i) { if( unlikely(*entry == this->array[i])) return i; } } /** * Simple debug info about the Array */ template void Array::debug () const { PRINT(0)("entryCount=%i, address=%p\n", this->entryCount, this->array); } #endif