AppEasy Core SDK
1.5.0
Cross platform mobile and desktop app and game development SDK - The easy way to make apps
|
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_