|
cocos2d for iPhone 1.0.0
2D engine for iOS and OS X
|
00001 /* Copyright (c) 2007 Scott Lembcke 00002 * 00003 * Permission is hereby granted, free of charge, to any person obtaining a copy 00004 * of this software and associated documentation files (the "Software"), to deal 00005 * in the Software without restriction, including without limitation the rights 00006 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00007 * copies of the Software, and to permit persons to whom the Software is 00008 * furnished to do so, subject to the following conditions: 00009 * 00010 * The above copyright notice and this permission notice shall be included in 00011 * all copies or substantial portions of the Software. 00012 * 00013 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00014 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00015 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00016 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00017 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00018 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 00019 * SOFTWARE. 00020 */ 00021 00038 #ifndef CC_ARRAY_H 00039 #define CC_ARRAY_H 00040 00041 #import <Foundation/Foundation.h> 00042 00043 #import <stdlib.h> 00044 #import <string.h> 00045 00046 00047 #pragma mark - 00048 #pragma mark ccArray for Objects 00049 00050 // Easy integration 00051 #define CCARRAYDATA_FOREACH(__array__, __object__) \ 00052 __object__=__array__->arr[0]; for(NSUInteger i=0, num=__array__->num; i<num; i++, __object__=__array__->arr[i]) \ 00053 00054 00055 typedef struct ccArray { 00056 NSUInteger num, max; 00057 id *arr; 00058 } ccArray; 00059 00061 static inline ccArray* ccArrayNew(NSUInteger capacity) { 00062 if (capacity == 0) 00063 capacity = 1; 00064 00065 ccArray *arr = (ccArray*)malloc( sizeof(ccArray) ); 00066 arr->num = 0; 00067 arr->arr = (id*) malloc( capacity * sizeof(id) ); 00068 arr->max = capacity; 00069 00070 return arr; 00071 } 00072 00073 static inline void ccArrayRemoveAllObjects(ccArray *arr); 00074 00076 static inline void ccArrayFree(ccArray *arr) 00077 { 00078 if( arr == nil ) return; 00079 00080 ccArrayRemoveAllObjects(arr); 00081 00082 free(arr->arr); 00083 free(arr); 00084 } 00085 00087 static inline void ccArrayDoubleCapacity(ccArray *arr) 00088 { 00089 arr->max *= 2; 00090 id *newArr = (id *)realloc( arr->arr, arr->max * sizeof(id) ); 00091 // will fail when there's not enough memory 00092 NSCAssert(newArr != NULL, @"ccArrayDoubleCapacity failed. Not enough memory"); 00093 arr->arr = newArr; 00094 } 00095 00097 static inline void ccArrayEnsureExtraCapacity(ccArray *arr, NSUInteger extra) 00098 { 00099 while (arr->max < arr->num + extra) 00100 ccArrayDoubleCapacity(arr); 00101 } 00102 00104 static inline void ccArrayShrink(ccArray *arr) 00105 { 00106 NSUInteger newSize; 00107 00108 //only resize when necessary 00109 if (arr->max > arr->num && !(arr->num==0 && arr->max==1)) 00110 { 00111 if (arr->num!=0) 00112 { 00113 newSize=arr->num; 00114 arr->max=arr->num; 00115 } 00116 else 00117 {//minimum capacity of 1, with 0 elements the array would be free'd by realloc 00118 newSize=1; 00119 arr->max=1; 00120 } 00121 00122 arr->arr = (id*) realloc(arr->arr,newSize * sizeof(id) ); 00123 NSCAssert(arr->arr!=NULL,@"could not reallocate the memory"); 00124 } 00125 } 00126 00128 static inline NSUInteger ccArrayGetIndexOfObject(ccArray *arr, id object) 00129 { 00130 for( NSUInteger i = 0; i < arr->num; i++) 00131 if( arr->arr[i] == object ) return i; 00132 00133 return NSNotFound; 00134 } 00135 00137 static inline BOOL ccArrayContainsObject(ccArray *arr, id object) 00138 { 00139 return ccArrayGetIndexOfObject(arr, object) != NSNotFound; 00140 } 00141 00143 static inline void ccArrayAppendObject(ccArray *arr, id object) 00144 { 00145 arr->arr[arr->num] = [object retain]; 00146 arr->num++; 00147 } 00148 00150 static inline void ccArrayAppendObjectWithResize(ccArray *arr, id object) 00151 { 00152 ccArrayEnsureExtraCapacity(arr, 1); 00153 ccArrayAppendObject(arr, object); 00154 } 00155 00158 static inline void ccArrayAppendArray(ccArray *arr, ccArray *plusArr) 00159 { 00160 for( NSUInteger i = 0; i < plusArr->num; i++) 00161 ccArrayAppendObject(arr, plusArr->arr[i]); 00162 } 00163 00165 static inline void ccArrayAppendArrayWithResize(ccArray *arr, ccArray *plusArr) 00166 { 00167 ccArrayEnsureExtraCapacity(arr, plusArr->num); 00168 ccArrayAppendArray(arr, plusArr); 00169 } 00170 00172 static inline void ccArrayInsertObjectAtIndex(ccArray *arr, id object, NSUInteger index) 00173 { 00174 NSCAssert(index<=arr->num, @"Invalid index. Out of bounds"); 00175 00176 ccArrayEnsureExtraCapacity(arr, 1); 00177 00178 NSUInteger remaining = arr->num - index; 00179 if( remaining > 0) 00180 memmove(&arr->arr[index+1], &arr->arr[index], sizeof(id) * remaining ); 00181 00182 arr->arr[index] = [object retain]; 00183 arr->num++; 00184 } 00185 00187 static inline void ccArraySwapObjectsAtIndexes(ccArray *arr, NSUInteger index1, NSUInteger index2) 00188 { 00189 NSCAssert(index1 < arr->num, @"(1) Invalid index. Out of bounds"); 00190 NSCAssert(index2 < arr->num, @"(2) Invalid index. Out of bounds"); 00191 00192 id object1 = arr->arr[index1]; 00193 00194 arr->arr[index1] = arr->arr[index2]; 00195 arr->arr[index2] = object1; 00196 } 00197 00199 static inline void ccArrayRemoveAllObjects(ccArray *arr) 00200 { 00201 while( arr->num > 0 ) 00202 [arr->arr[--arr->num] release]; 00203 } 00204 00207 static inline void ccArrayRemoveObjectAtIndex(ccArray *arr, NSUInteger index) 00208 { 00209 [arr->arr[index] release]; 00210 arr->num--; 00211 00212 NSUInteger remaining = arr->num - index; 00213 if(remaining>0) 00214 memmove(&arr->arr[index], &arr->arr[index+1], remaining * sizeof(id)); 00215 } 00216 00220 static inline void ccArrayFastRemoveObjectAtIndex(ccArray *arr, NSUInteger index) 00221 { 00222 [arr->arr[index] release]; 00223 NSUInteger last = --arr->num; 00224 arr->arr[index] = arr->arr[last]; 00225 } 00226 00227 static inline void ccArrayFastRemoveObject(ccArray *arr, id object) 00228 { 00229 NSUInteger index = ccArrayGetIndexOfObject(arr, object); 00230 if (index != NSNotFound) 00231 ccArrayFastRemoveObjectAtIndex(arr, index); 00232 } 00233 00236 static inline void ccArrayRemoveObject(ccArray *arr, id object) 00237 { 00238 NSUInteger index = ccArrayGetIndexOfObject(arr, object); 00239 if (index != NSNotFound) 00240 ccArrayRemoveObjectAtIndex(arr, index); 00241 } 00242 00245 static inline void ccArrayRemoveArray(ccArray *arr, ccArray *minusArr) 00246 { 00247 for( NSUInteger i = 0; i < minusArr->num; i++) 00248 ccArrayRemoveObject(arr, minusArr->arr[i]); 00249 } 00250 00253 static inline void ccArrayFullRemoveArray(ccArray *arr, ccArray *minusArr) 00254 { 00255 NSUInteger back = 0; 00256 00257 for( NSUInteger i = 0; i < arr->num; i++) { 00258 if( ccArrayContainsObject(minusArr, arr->arr[i]) ) { 00259 [arr->arr[i] release]; 00260 back++; 00261 } else 00262 arr->arr[i - back] = arr->arr[i]; 00263 } 00264 00265 arr->num -= back; 00266 } 00267 00269 static inline void ccArrayMakeObjectsPerformSelector(ccArray *arr, SEL sel) 00270 { 00271 for( NSUInteger i = 0; i < arr->num; i++) 00272 [arr->arr[i] performSelector:sel]; 00273 } 00274 00275 static inline void ccArrayMakeObjectsPerformSelectorWithObject(ccArray *arr, SEL sel, id object) 00276 { 00277 for( NSUInteger i = 0; i < arr->num; i++) 00278 [arr->arr[i] performSelector:sel withObject:object]; 00279 } 00280 00281 00282 #pragma mark - 00283 #pragma mark ccCArray for Values (c structures) 00284 00285 typedef ccArray ccCArray; 00286 00287 static inline void ccCArrayRemoveAllValues(ccCArray *arr); 00288 00290 static inline ccCArray* ccCArrayNew(NSUInteger capacity) { 00291 if (capacity == 0) 00292 capacity = 1; 00293 00294 ccCArray *arr = (ccCArray*)malloc( sizeof(ccCArray) ); 00295 arr->num = 0; 00296 arr->arr = (id*) malloc( capacity * sizeof(id) ); 00297 arr->max = capacity; 00298 00299 return arr; 00300 } 00301 00303 static inline void ccCArrayFree(ccCArray *arr) 00304 { 00305 if( arr == nil ) return; 00306 00307 ccCArrayRemoveAllValues(arr); 00308 00309 free(arr->arr); 00310 free(arr); 00311 } 00312 00314 static inline void ccCArrayDoubleCapacity(ccCArray *arr) 00315 { 00316 ccArrayDoubleCapacity(arr); 00317 } 00318 00320 static inline void ccCArrayEnsureExtraCapacity(ccCArray *arr, NSUInteger extra) 00321 { 00322 ccArrayEnsureExtraCapacity(arr,extra); 00323 } 00324 00326 static inline NSUInteger ccCArrayGetIndexOfValue(ccCArray *arr, void* value) 00327 { 00328 for( NSUInteger i = 0; i < arr->num; i++) 00329 if( arr->arr[i] == value ) return i; 00330 return NSNotFound; 00331 } 00332 00334 static inline BOOL ccCArrayContainsValue(ccCArray *arr, void* value) 00335 { 00336 return ccCArrayGetIndexOfValue(arr, value) != NSNotFound; 00337 } 00338 00340 static inline void ccCArrayInsertValueAtIndex( ccCArray *arr, void *value, NSUInteger index) 00341 { 00342 NSCAssert( index < arr->max, @"ccCArrayInsertValueAtIndex: invalid index"); 00343 00344 NSUInteger remaining = arr->num - index; 00345 00346 // last Value doesn't need to be moved 00347 if( remaining > 0) { 00348 // tex coordinates 00349 memmove( &arr->arr[index+1],&arr->arr[index], sizeof(void*) * remaining ); 00350 } 00351 00352 arr->num++; 00353 arr->arr[index] = (id) value; 00354 } 00355 00357 static inline void ccCArrayAppendValue(ccCArray *arr, void* value) 00358 { 00359 arr->arr[arr->num] = (id) value; 00360 arr->num++; 00361 } 00362 00364 static inline void ccCArrayAppendValueWithResize(ccCArray *arr, void* value) 00365 { 00366 ccCArrayEnsureExtraCapacity(arr, 1); 00367 ccCArrayAppendValue(arr, value); 00368 } 00369 00372 static inline void ccCArrayAppendArray(ccCArray *arr, ccCArray *plusArr) 00373 { 00374 for( NSUInteger i = 0; i < plusArr->num; i++) 00375 ccCArrayAppendValue(arr, plusArr->arr[i]); 00376 } 00377 00379 static inline void ccCArrayAppendArrayWithResize(ccCArray *arr, ccCArray *plusArr) 00380 { 00381 ccCArrayEnsureExtraCapacity(arr, plusArr->num); 00382 ccCArrayAppendArray(arr, plusArr); 00383 } 00384 00386 static inline void ccCArrayRemoveAllValues(ccCArray *arr) 00387 { 00388 arr->num = 0; 00389 } 00390 00395 static inline void ccCArrayRemoveValueAtIndex(ccCArray *arr, NSUInteger index) 00396 { 00397 for( NSUInteger last = --arr->num; index < last; index++) 00398 arr->arr[index] = arr->arr[index + 1]; 00399 } 00400 00406 static inline void ccCArrayFastRemoveValueAtIndex(ccCArray *arr, NSUInteger index) 00407 { 00408 NSUInteger last = --arr->num; 00409 arr->arr[index] = arr->arr[last]; 00410 } 00411 00415 static inline void ccCArrayRemoveValue(ccCArray *arr, void* value) 00416 { 00417 NSUInteger index = ccCArrayGetIndexOfValue(arr, value); 00418 if (index != NSNotFound) 00419 ccCArrayRemoveValueAtIndex(arr, index); 00420 } 00421 00425 static inline void ccCArrayRemoveArray(ccCArray *arr, ccCArray *minusArr) 00426 { 00427 for( NSUInteger i = 0; i < minusArr->num; i++) 00428 ccCArrayRemoveValue(arr, minusArr->arr[i]); 00429 } 00430 00434 static inline void ccCArrayFullRemoveArray(ccCArray *arr, ccCArray *minusArr) 00435 { 00436 NSUInteger back = 0; 00437 00438 for( NSUInteger i = 0; i < arr->num; i++) { 00439 if( ccCArrayContainsValue(minusArr, arr->arr[i]) ) { 00440 back++; 00441 } else 00442 arr->arr[i - back] = arr->arr[i]; 00443 } 00444 00445 arr->num -= back; 00446 } 00447 #endif // CC_ARRAY_H