AppEasy Core SDK  1.5.0
Cross platform mobile and desktop app and game development SDK - The easy way to make apps
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Defines
CzSlotArray.h
Go to the documentation of this file.
00001 // 
00002 //
00003 // AppEasy SDK - Cross Platform Multi-purpose Game and App Engine
00004 //
00005 // Developed by Matthew Hopwood of Pocketeers Limited - www.pocketeers.co.uk
00006 //
00007 // For updates, tutorials and more details check out www.appeasymobile.com
00008 //
00009 // This code is provided free of charge and without any warranty whatsoever. You must ensure that this whole notice is present in all files and derivatives, so the reader knows its origin.
00010 // If you use this SDK in your product then please ensure that you credit AppEasy's usage appropriately. Please see www.appeasymobile.com for licensing details and support
00011 //
00012 //
00013 
00014 #if !defined(_CCZ_SLOT_ARRAY_H_)
00015 #define _CCZ_SLOT_ARRAY_H_
00016 
00017 #include "CzUtil.h"
00018 #include "IzPlatformSys.h"
00019 
00020 /**
00021  @addtogroup Core
00022  @{
00023  */
00024 
00025 /**
00026  @class CzSlotArray
00027 
00028  @brief Basic resizable slot array
00029  
00030  A slot array differs from a normal array in that the array is not shrank and elements are not compacted when elements are removed. Instead array elements that are removed are marked 
00031  with NULL. With this, the Size of the array denotes the total number of items added to the array and not the number of valid elements. To get the number of valid elements call count()
00032 
00033  @tparam    T   Generic type parameter.
00034  */
00035 
00036 template <class T> class CzSlotArray
00037 {
00038     // Properties
00039 protected:
00040     int     Growth;         ///< Number of elements to grow array when we run out of space
00041 public:
00042     void    setGrowth(int growth)   { Growth = growth; }
00043     int     getSize() const         { return Size; }
00044     // Properties End
00045 protected:
00046     T*      Elements;       ///< Array elements
00047     int     Size;           ///< Max size of array
00048     int     LastFreedSlot;  ///< Slot that was last freed
00049 
00050 public:
00051     CzSlotArray()                       ///< Constructs an array with 4 elements and a groth of 4
00052     {
00053         LastFreedSlot = 0;
00054         Growth = 4;
00055         Size = 4;
00056         Elements = (T*)CZ_Malloc(sizeof(T) * Size);
00057         for (int t = 0; t < Size; t++)
00058             Elements[t] = NULL;
00059     }
00060     CzSlotArray(int size, int growth)   ///< Constructs an array of the specified size and growth
00061     {
00062         if (size == 0) size = 1;
00063         LastFreedSlot = 0;
00064         Growth = growth;
00065         Size = size;
00066         Elements = (T*)CZ_Malloc(sizeof(T) * Size);
00067         for (int t = 0; t < Size; t++)
00068             Elements[t] = NULL;
00069     }
00070     
00071     virtual ~CzSlotArray()
00072     {
00073         if (Elements != NULL)
00074             CZ_Free(Elements);
00075     }
00076 
00077     int count() const       ///< Gets the number of active elements, not the arrays size.
00078     {
00079         int count = 0;
00080         for (int t = 0; t < Size; t++)
00081         {
00082             if (Elements[t] != NULL)
00083                 count++;
00084         }
00085         return count;
00086     }
00087     bool add(T element)     ///< Finds a free slot and adds the element. If none free then the array size is grown.
00088     {
00089 //      LastFreedSlot = -1;
00090         if (LastFreedSlot >= 0)
00091         {
00092             Elements[LastFreedSlot] = element;
00093             if (LastFreedSlot < Size - 1 && Elements[LastFreedSlot + 1] == NULL)    // Optimisation - If next slot is free then set LastFreedSlot as the next slot
00094                 LastFreedSlot++;
00095             else
00096                 LastFreedSlot = -1;
00097             return true;
00098         }
00099         // find a free slot
00100         int t;
00101         for (t = 0; t < Size; t++)
00102         {
00103             if (Elements[t] == NULL)
00104             {
00105                 Elements[t] = element;
00106                 if (t < Size - 1 && Elements[t + 1] == NULL)    // Optimisation - If next slot is free then set LastFreedSlot as the next slot
00107                     LastFreedSlot = t + 1;
00108                 return true;
00109             }
00110         }
00111 
00112         // If we are not allowed to grow then return error
00113         if (Growth == 0)
00114             return false;
00115 
00116         // No free slots so grow the array
00117         grow(Growth);
00118         Elements[t] = element;
00119         LastFreedSlot = t + 1;
00120 
00121         return true;
00122     }
00123 
00124     void remove(T element)  ///< Removes the specified element from the array.
00125     {
00126         for (int t = 0; t < Size; t++)
00127         {
00128             if (Elements[t] == element)
00129             {
00130                 Elements[t] = NULL;
00131                 LastFreedSlot = t;
00132                 break;
00133             }
00134         }
00135     }
00136 
00137     void remove(int index)  ///< Removes the element at the specified index from the array.
00138     {
00139         if (index < 0 || index >= Size)
00140             return;
00141         Elements[index] = NULL;
00142         LastFreedSlot = index;
00143     }
00144 
00145     T element_at(int index) const   ///< Returns the element at the specified index.
00146     {
00147         if (index < 0 || index >= Size)
00148             return NULL;
00149         return Elements[index];
00150     }
00151 
00152     bool set(int index, T element)  ///< Sets the element at the specific index.
00153     {
00154         if (index < 0 || index >= Size)
00155             return false;
00156         Elements[index] = element;
00157         if (index == LastFreedSlot)
00158             LastFreedSlot = -1;
00159 
00160         return true;
00161     }
00162 
00163     void grow(int growth)   ///< Grow the array
00164     {
00165         if (growth <= 0)
00166             return;
00167         T* elements = (T*)CZ_Realloc(Elements, sizeof(T) * (Size + growth));
00168         if (elements == NULL)
00169         {
00170             elements = (T*)CZ_Malloc(sizeof(T) * Size);
00171             for (int t = 0; t < Size; t++)
00172                 elements[t] = Elements[t];
00173             CZ_Free(Elements);
00174             Elements = elements;
00175         }
00176         else
00177             Elements = elements;
00178         for (int t = 0; t < growth; t++)
00179             elements[t + Size] = NULL;
00180         Size += growth;
00181     }
00182 
00183     void growToSize(int new_size)   ///< Grow the array to the new size
00184     {
00185         if (new_size <= 0 || new_size <= Size)
00186             return;
00187         grow(new_size - Size);
00188     }
00189 
00190     void resize(int size)   ///< Change the size of the array, if new size is smaller than current size then it will be shrank
00191     {
00192         if (size <= 0 || size == Size)
00193             return;
00194 
00195         if (size > Size)
00196             grow(size - Size);
00197         else
00198         {
00199             T* elements = (T*)CZ_Realloc(Elements, sizeof(T) * size);
00200             if (elements == NULL)
00201             {
00202                 elements = (T*)CZ_Malloc(sizeof(T) * size);
00203                 for (int t = 0; t < size; t++)
00204                     elements[t] = Elements[t];
00205                 CZ_Free(Elements);
00206                 Elements = elements;
00207             }
00208             else
00209                 Elements = elements;
00210 
00211             Size = size;
00212             if (LastFreedSlot >= size)
00213                 LastFreedSlot = -1;
00214         }
00215     }
00216 
00217     int getLastUsedSlot() const ///< Returns the last used array index
00218     {
00219         for (int t = Size - 1; t >= 0; t--)
00220         {
00221             if (Elements[t] != NULL)
00222                 return t;
00223         }
00224 
00225         return Size - 1;
00226     }
00227 
00228     void clear(bool delete_elements = false)    ///< Clear the array, optionally deleting contents
00229     {
00230         for (int t = 0; t < Size; t++)
00231         {
00232             if (delete_elements)
00233             {
00234                 if (Elements[t] != NULL)
00235                     delete Elements[t];
00236             }
00237             Elements[t] = NULL;
00238         }
00239         LastFreedSlot = 0;
00240     }
00241 
00242     void compact()  ///< Shrink the array to its smallest possible size
00243     {
00244         int last_free = 0;
00245         for (int t = 0; t < Size; t++)
00246         {
00247             if (Elements[t] != NULL)
00248             {
00249                 for (int t2 = last_free; t2 < Size; t2++)
00250                 {
00251                     if (Elements[t2] == NULL)
00252                     {
00253                         last_free = t2;
00254                         Elements[last_free] = Elements[t];
00255                         Elements[t] = NULL;
00256                     }
00257                 }
00258             }
00259         }
00260     }
00261 };
00262 
00263 /// @}
00264 
00265 #endif  // _CCZ_SLOT_ARRAY_H_