arrayObject.cpp 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #include "platform/platform.h"
  23. #include "console/arrayObject.h"
  24. #include "console/consoleTypes.h"
  25. #include "console/engineAPI.h"
  26. #include "math/mMathFn.h"
  27. IMPLEMENT_CONOBJECT(ArrayObject);
  28. ConsoleDocClass( ArrayObject,
  29. "@brief Data structure for storing indexed sequences of key/value pairs.\n\n"
  30. "This is a powerful array class providing PHP style arrays in TorqueScript.\n\n"
  31. "The following features are supported:<ul>\n"
  32. "<li>array pointers: this allows you to move forwards or backwards through "
  33. "the array as if it was a list, including jumping to the start or end.</li>\n"
  34. "<li>sorting: the array can be sorted in either alphabetic or numeric mode, "
  35. "on the key or the value, and in ascending or descending order</li>\n"
  36. "<li>add/remove elements: elements can be pushed/popped from the start or "
  37. "end of the array, or can be inserted/erased from anywhere in the middle</li>\n"
  38. "<li>removal of duplicates: remove duplicate keys or duplicate values</li>\n"
  39. "<li>searching: search the array and return the index of a particular key or "
  40. "value</li>\n"
  41. "<li>counting: count the number of instaces of a particular value or key in "
  42. "the array, as well as the total number of elements</li>\n"
  43. "<li>advanced features: array append, array crop and array duplicate</li>\n"
  44. "</ul>\n\n"
  45. "Array element keys and values can be strings or numbers\n\n"
  46. "@ingroup Scripting"
  47. );
  48. bool ArrayObject::smDecreasing = false;
  49. bool ArrayObject::smCaseSensitive = false;
  50. const char* ArrayObject::smCompareFunction;
  51. S32 QSORT_CALLBACK ArrayObject::_valueCompare( const void* a, const void* b )
  52. {
  53. ArrayObject::Element *ea = (ArrayObject::Element *) (a);
  54. ArrayObject::Element *eb = (ArrayObject::Element *) (b);
  55. S32 result = smCaseSensitive ? dStrnatcmp(ea->value, eb->value) : dStrnatcasecmp(ea->value, eb->value);
  56. return ( smDecreasing ? -result : result );
  57. }
  58. S32 QSORT_CALLBACK ArrayObject::_valueNumCompare( const void* a, const void* b )
  59. {
  60. ArrayObject::Element *ea = (ArrayObject::Element *) (a);
  61. ArrayObject::Element *eb = (ArrayObject::Element *) (b);
  62. F32 aCol = dAtof(ea->value);
  63. F32 bCol = dAtof(eb->value);
  64. F32 result = aCol - bCol;
  65. S32 res = result < 0 ? -1 : (result > 0 ? 1 : 0);
  66. return ( smDecreasing ? -res : res );
  67. }
  68. S32 QSORT_CALLBACK ArrayObject::_keyCompare( const void* a, const void* b )
  69. {
  70. ArrayObject::Element *ea = (ArrayObject::Element *) (a);
  71. ArrayObject::Element *eb = (ArrayObject::Element *) (b);
  72. S32 result = smCaseSensitive ? dStrnatcmp(ea->key, eb->key) : dStrnatcasecmp(ea->key, eb->key);
  73. return ( smDecreasing ? -result : result );
  74. }
  75. S32 QSORT_CALLBACK ArrayObject::_keyNumCompare( const void* a, const void* b )
  76. {
  77. ArrayObject::Element *ea = (ArrayObject::Element *) (a);
  78. ArrayObject::Element *eb = (ArrayObject::Element *) (b);
  79. const char* aCol = ea->key;
  80. const char* bCol = eb->key;
  81. F32 result = dAtof(aCol) - dAtof(bCol);
  82. S32 res = result < 0 ? -1 : (result > 0 ? 1 : 0);
  83. return ( smDecreasing ? -res : res );
  84. }
  85. S32 QSORT_CALLBACK ArrayObject::_keyFunctionCompare( const void* a, const void* b )
  86. {
  87. ArrayObject::Element* ea = ( ArrayObject::Element* )( a );
  88. ArrayObject::Element* eb = ( ArrayObject::Element* )( b );
  89. const char* argv[ 3 ];
  90. argv[ 0 ] = smCompareFunction;
  91. argv[ 1 ] = ea->key;
  92. argv[ 2 ] = eb->key;
  93. S32 result = dAtoi( Con::execute( 3, argv ) );
  94. S32 res = result < 0 ? -1 : ( result > 0 ? 1 : 0 );
  95. return ( smDecreasing ? -res : res );
  96. }
  97. S32 QSORT_CALLBACK ArrayObject::_valueFunctionCompare( const void* a, const void* b )
  98. {
  99. ArrayObject::Element* ea = ( ArrayObject::Element* )( a );
  100. ArrayObject::Element* eb = ( ArrayObject::Element* )( b );
  101. const char* argv[ 3 ];
  102. argv[ 0 ] = smCompareFunction;
  103. argv[ 1 ] = ea->value;
  104. argv[ 2 ] = eb->value;
  105. S32 result = dAtoi( Con::execute( 3, argv ) );
  106. S32 res = result < 0 ? -1 : ( result > 0 ? 1 : 0 );
  107. return ( smDecreasing ? -res : res );
  108. }
  109. //-----------------------------------------------------------------------------
  110. ArrayObject::ArrayObject()
  111. : mCurrentIndex( NULL ),
  112. mCaseSensitive( false )
  113. {
  114. }
  115. //-----------------------------------------------------------------------------
  116. void ArrayObject::initPersistFields()
  117. {
  118. addField( "caseSensitive", TypeBool, Offset( mCaseSensitive, ArrayObject ),
  119. "Makes the keys and values case-sensitive.\n"
  120. "By default, comparison of key and value strings will be case-insensitive." );
  121. addProtectedField( "key", TypeCaseString, NULL, &_addKeyFromField, &emptyStringProtectedGetFn,
  122. "Helper field which allows you to add new key['keyname'] = value pairs." );
  123. Parent::initPersistFields();
  124. }
  125. //-----------------------------------------------------------------------------
  126. bool ArrayObject::_addKeyFromField( void *object, const char *index, const char *data )
  127. {
  128. static_cast<ArrayObject*>( object )->push_back( index, data );
  129. return false;
  130. }
  131. //-----------------------------------------------------------------------------
  132. S32 ArrayObject::getIndexFromValue( const String &value ) const
  133. {
  134. S32 foundIndex = -1;
  135. for ( S32 i = mCurrentIndex; i < mArray.size(); i++ )
  136. {
  137. if ( isEqual( mArray[i].value, value ) )
  138. {
  139. foundIndex = i;
  140. break;
  141. }
  142. }
  143. if( foundIndex < 0 )
  144. {
  145. for ( S32 i = 0; i < mCurrentIndex; i++ )
  146. {
  147. if ( isEqual( mArray[i].value, value ) )
  148. {
  149. foundIndex = i;
  150. break;
  151. }
  152. }
  153. }
  154. return foundIndex;
  155. }
  156. //-----------------------------------------------------------------------------
  157. S32 ArrayObject::getIndexFromKey( const String &key ) const
  158. {
  159. S32 foundIndex = -1;
  160. for ( S32 i = mCurrentIndex; i < mArray.size(); i++ )
  161. {
  162. if ( isEqual( mArray[i].key, key ) )
  163. {
  164. foundIndex = i;
  165. break;
  166. }
  167. }
  168. if( foundIndex < 0 )
  169. {
  170. for ( S32 i = 0; i < mCurrentIndex; i++ )
  171. {
  172. if ( isEqual( mArray[i].key, key ) )
  173. {
  174. foundIndex = i;
  175. break;
  176. }
  177. }
  178. }
  179. return foundIndex;
  180. }
  181. //-----------------------------------------------------------------------------
  182. S32 ArrayObject::getIndexFromKeyValue( const String &key, const String &value ) const
  183. {
  184. S32 foundIndex = -1;
  185. for ( S32 i = mCurrentIndex; i < mArray.size(); i++ )
  186. {
  187. if ( isEqual( mArray[i].key, key ) && isEqual( mArray[i].value, value ) )
  188. {
  189. foundIndex = i;
  190. break;
  191. }
  192. }
  193. if ( foundIndex < 0 )
  194. {
  195. for ( S32 i = 0; i < mCurrentIndex; i++ )
  196. {
  197. if ( isEqual( mArray[i].key, key ) && isEqual( mArray[i].value, value ) )
  198. {
  199. foundIndex = i;
  200. break;
  201. }
  202. }
  203. }
  204. return foundIndex;
  205. }
  206. //-----------------------------------------------------------------------------
  207. const String& ArrayObject::getKeyFromIndex( S32 index ) const
  208. {
  209. if ( index >= mArray.size() || index < 0 )
  210. return String::EmptyString;
  211. return mArray[index].key;
  212. }
  213. //-----------------------------------------------------------------------------
  214. const String& ArrayObject::getValueFromIndex( S32 index ) const
  215. {
  216. if( index >= mArray.size() || index < 0 )
  217. return String::EmptyString;
  218. return mArray[index].value;
  219. }
  220. //-----------------------------------------------------------------------------
  221. S32 ArrayObject::countValue( const String &value ) const
  222. {
  223. S32 count = 0;
  224. for ( S32 i = 0; i < mArray.size(); i++ )
  225. {
  226. if ( isEqual( mArray[i].value, value ) )
  227. count++;
  228. }
  229. return count;
  230. }
  231. //-----------------------------------------------------------------------------
  232. S32 ArrayObject::countKey( const String &key) const
  233. {
  234. S32 count = 0;
  235. for ( S32 i = 0; i < mArray.size(); i++ )
  236. {
  237. if ( isEqual( mArray[i].key, key ) )
  238. count++;
  239. }
  240. return count;
  241. }
  242. //-----------------------------------------------------------------------------
  243. void ArrayObject::push_back( const String &key, const String &value )
  244. {
  245. mArray.push_back( Element( key, value ) );
  246. }
  247. //-----------------------------------------------------------------------------
  248. void ArrayObject::push_front( const String &key, const String &value )
  249. {
  250. mArray.push_front( Element( key, value ) );
  251. }
  252. //-----------------------------------------------------------------------------
  253. void ArrayObject::insert( const String &key, const String &value, S32 index )
  254. {
  255. index = mClamp( index, 0, mArray.size() );
  256. mArray.insert( index, Element( key, value ) );
  257. }
  258. //-----------------------------------------------------------------------------
  259. void ArrayObject::pop_back()
  260. {
  261. if(mArray.size() <= 0)
  262. return;
  263. mArray.pop_back();
  264. if( mCurrentIndex >= mArray.size() )
  265. mCurrentIndex = mArray.size() - 1;
  266. }
  267. //-----------------------------------------------------------------------------
  268. void ArrayObject::pop_front()
  269. {
  270. if( mArray.size() <= 0 )
  271. return;
  272. mArray.pop_front();
  273. if( mCurrentIndex >= mArray.size() )
  274. mCurrentIndex = mArray.size() - 1;
  275. }
  276. //-----------------------------------------------------------------------------
  277. void ArrayObject::erase( S32 index )
  278. {
  279. if(index < 0 || index >= mArray.size())
  280. return;
  281. mArray.erase( index );
  282. }
  283. //-----------------------------------------------------------------------------
  284. void ArrayObject::empty()
  285. {
  286. mArray.clear();
  287. mCurrentIndex = 0;
  288. }
  289. //-----------------------------------------------------------------------------
  290. void ArrayObject::moveIndex(S32 prev, S32 index)
  291. {
  292. if(index >= mArray.size())
  293. push_back(mArray[prev].key, mArray[prev].value);
  294. else
  295. mArray[index] = mArray[prev];
  296. mArray[prev].value = String::EmptyString;
  297. mArray[prev].key = String::EmptyString;
  298. }
  299. //-----------------------------------------------------------------------------
  300. void ArrayObject::uniqueValue()
  301. {
  302. for(S32 i=0; i<mArray.size(); i++)
  303. {
  304. for(S32 j=i+1; j<mArray.size(); j++)
  305. {
  306. if ( isEqual( mArray[i].value, mArray[j].value ) )
  307. {
  308. erase(j);
  309. j--;
  310. }
  311. }
  312. }
  313. }
  314. //-----------------------------------------------------------------------------
  315. void ArrayObject::uniqueKey()
  316. {
  317. for(S32 i=0; i<mArray.size(); i++)
  318. {
  319. for(S32 j=i+1; j<mArray.size(); j++)
  320. {
  321. if( isEqual( mArray[i].key, mArray[j].key ) )
  322. {
  323. erase(j);
  324. j--;
  325. }
  326. }
  327. }
  328. }
  329. //-----------------------------------------------------------------------------
  330. void ArrayObject::duplicate(ArrayObject* obj)
  331. {
  332. empty();
  333. for(S32 i=0; i<obj->count(); i++)
  334. {
  335. const String& tempval = obj->getValueFromIndex(i);
  336. const String& tempkey = obj->getKeyFromIndex(i);
  337. push_back(tempkey, tempval);
  338. }
  339. mCurrentIndex = obj->getCurrent();
  340. }
  341. //-----------------------------------------------------------------------------
  342. void ArrayObject::crop( ArrayObject *obj )
  343. {
  344. for( S32 i = 0; i < obj->count(); i++ )
  345. {
  346. const String &tempkey = obj->getKeyFromIndex( i );
  347. for( S32 j = 0; j < mArray.size(); j++ )
  348. {
  349. if( isEqual( mArray[j].key, tempkey ) )
  350. {
  351. mArray.erase( j );
  352. j--;
  353. }
  354. }
  355. }
  356. }
  357. //-----------------------------------------------------------------------------
  358. void ArrayObject::append(ArrayObject* obj)
  359. {
  360. for(S32 i=0; i<obj->count(); i++)
  361. {
  362. const String& tempval = obj->getValueFromIndex(i);
  363. const String& tempkey = obj->getKeyFromIndex(i);
  364. push_back(tempkey, tempval);
  365. }
  366. }
  367. //-----------------------------------------------------------------------------
  368. void ArrayObject::setKey( const String &key, S32 index )
  369. {
  370. if ( index >= mArray.size() )
  371. return;
  372. mArray[index].key = key;
  373. }
  374. //-----------------------------------------------------------------------------
  375. void ArrayObject::setValue( const String &value, S32 index )
  376. {
  377. if ( index >= mArray.size() )
  378. return;
  379. mArray[index].value = value;
  380. }
  381. //-----------------------------------------------------------------------------
  382. void ArrayObject::sort( bool valsort, bool asc, bool numeric )
  383. {
  384. if ( mArray.size() <= 1 )
  385. return;
  386. smDecreasing = asc ? false : true;
  387. smCaseSensitive = isCaseSensitive();
  388. if ( numeric )
  389. {
  390. if ( valsort )
  391. dQsort( (void *)&(mArray[0]), mArray.size(), sizeof(Element), _valueNumCompare) ;
  392. else
  393. dQsort( (void *)&(mArray[0]), mArray.size(), sizeof(Element), _keyNumCompare );
  394. }
  395. else
  396. {
  397. if( valsort )
  398. dQsort( (void *)&(mArray[0]), mArray.size(), sizeof(Element), _valueCompare );
  399. else
  400. dQsort( (void *)&(mArray[0]), mArray.size(), sizeof(Element), _keyCompare );
  401. }
  402. }
  403. //-----------------------------------------------------------------------------
  404. void ArrayObject::sort( bool valsort, bool asc, const char* callbackFunctionName )
  405. {
  406. if( mArray.size() <= 1 )
  407. return;
  408. smDecreasing = asc ? false : true;
  409. smCompareFunction = callbackFunctionName;
  410. if( valsort )
  411. dQsort( ( void* ) &( mArray[ 0 ] ), mArray.size(), sizeof( Element ), _valueFunctionCompare ) ;
  412. else
  413. dQsort( ( void* ) &( mArray[ 0 ] ), mArray.size(), sizeof( Element ), _keyFunctionCompare );
  414. smCompareFunction = NULL;
  415. }
  416. //-----------------------------------------------------------------------------
  417. S32 ArrayObject::moveFirst()
  418. {
  419. mCurrentIndex = 0;
  420. return mCurrentIndex;
  421. }
  422. //-----------------------------------------------------------------------------
  423. S32 ArrayObject::moveLast()
  424. {
  425. if ( mArray.empty() )
  426. mCurrentIndex = 0;
  427. else
  428. mCurrentIndex = mArray.size() - 1;
  429. return mCurrentIndex;
  430. }
  431. //-----------------------------------------------------------------------------
  432. S32 ArrayObject::moveNext()
  433. {
  434. if ( mCurrentIndex >= mArray.size() - 1 )
  435. return -1;
  436. mCurrentIndex++;
  437. return mCurrentIndex;
  438. }
  439. //-----------------------------------------------------------------------------
  440. S32 ArrayObject::movePrev()
  441. {
  442. if ( mCurrentIndex <= 0 )
  443. return -1;
  444. mCurrentIndex--;
  445. return mCurrentIndex;
  446. }
  447. //-----------------------------------------------------------------------------
  448. void ArrayObject::setCurrent( S32 idx )
  449. {
  450. if ( idx < 0 || idx >= mArray.size() )
  451. {
  452. Con::errorf( "ArrayObject::setCurrent( %d ) is out of the array bounds!", idx );
  453. return;
  454. }
  455. mCurrentIndex = idx;
  456. }
  457. //-----------------------------------------------------------------------------
  458. void ArrayObject::echo()
  459. {
  460. Con::printf( "ArrayObject Listing:" );
  461. Con::printf( "Index Key Value" );
  462. for ( U32 i = 0; i < mArray.size(); i++ )
  463. {
  464. const String& key = mArray[i].key;
  465. const String& val = mArray[i].value;
  466. Con::printf( "%d [%s] => %s", i, key.c_str(), val.c_str() );
  467. }
  468. }
  469. //=============================================================================
  470. // Console Methods.
  471. //=============================================================================
  472. DefineEngineMethod( ArrayObject, getIndexFromValue, S32, ( const char* value ),,
  473. "Search the array from the current position for the element "
  474. "@param value Array value to search for\n"
  475. "@return Index of the first element found, or -1 if none\n" )
  476. {
  477. return object->getIndexFromValue( value );
  478. }
  479. DefineEngineMethod( ArrayObject, getIndexFromKey, S32, ( const char* key ),,
  480. "Search the array from the current position for the key "
  481. "@param value Array key to search for\n"
  482. "@return Index of the first element found, or -1 if none\n" )
  483. {
  484. return object->getIndexFromKey( key );
  485. }
  486. DefineEngineMethod( ArrayObject, getValue, const char*, ( S32 index ),,
  487. "Get the value of the array element at the submitted index.\n"
  488. "@param index 0-based index of the array element to get\n"
  489. "@return The value of the array element at the specified index, "
  490. "or \"\" if the index is out of range\n" )
  491. {
  492. return object->getValueFromIndex( index ).c_str();
  493. }
  494. DefineEngineMethod( ArrayObject, getKey, const char*, ( S32 index ),,
  495. "Get the key of the array element at the submitted index.\n"
  496. "@param index 0-based index of the array element to get\n"
  497. "@return The key associated with the array element at the "
  498. "specified index, or \"\" if the index is out of range\n" )
  499. {
  500. return object->getKeyFromIndex( index ).c_str();
  501. }
  502. DefineEngineMethod( ArrayObject, setKey, void, ( const char* key, S32 index ),,
  503. "Set the key at the given index.\n"
  504. "@param key New key value\n"
  505. "@param index 0-based index of the array element to update\n" )
  506. {
  507. object->setKey( key, index );
  508. }
  509. DefineEngineMethod( ArrayObject, setValue, void, ( const char* value, S32 index ),,
  510. "Set the value at the given index.\n"
  511. "@param value New array element value\n"
  512. "@param index 0-based index of the array element to update\n" )
  513. {
  514. object->setValue( value, index );
  515. }
  516. DefineEngineMethod( ArrayObject, count, S32, (),,
  517. "Get the number of elements in the array." )
  518. {
  519. return (S32)object->count();
  520. }
  521. DefineEngineMethod( ArrayObject, countValue, S32, ( const char* value ),,
  522. "Get the number of times a particular value is found in the array.\n"
  523. "@param value Array element value to count\n" )
  524. {
  525. return (S32)object->countValue( value );
  526. }
  527. DefineEngineMethod( ArrayObject, countKey, S32, ( const char* key ),,
  528. "Get the number of times a particular key is found in the array.\n"
  529. "@param key Key value to count\n" )
  530. {
  531. return (S32)object->countKey( key );
  532. }
  533. DefineEngineMethod( ArrayObject, add, void, ( const char* key, const char* value ), ( "" ),
  534. "Adds a new element to the end of an array (same as push_back()).\n"
  535. "@param key Key for the new element\n"
  536. "@param value Value for the new element\n" )
  537. {
  538. object->push_back( key, value );
  539. }
  540. DefineEngineMethod( ArrayObject, push_back, void, ( const char* key, const char* value ), ( "" ),
  541. "Adds a new element to the end of an array.\n"
  542. "@param key Key for the new element\n"
  543. "@param value Value for the new element\n" )
  544. {
  545. object->push_back( key, value );
  546. }
  547. DefineEngineMethod( ArrayObject, push_front, void, ( const char* key, const char* value ), ( "" ),
  548. "Adds a new element to the front of an array" )
  549. {
  550. object->push_front( key, value );
  551. }
  552. DefineEngineMethod( ArrayObject, insert, void, ( const char* key, const char* value, S32 index ),,
  553. "Adds a new element to a specified position in the array.\n"
  554. "- @a index = 0 will insert an element at the start of the array (same as push_front())\n"
  555. "- @a index = %array.count() will insert an element at the end of the array (same as push_back())\n\n"
  556. "@param key Key for the new element\n"
  557. "@param value Value for the new element\n"
  558. "@param index 0-based index at which to insert the new element" )
  559. {
  560. object->insert( key, value, index );
  561. }
  562. DefineEngineMethod( ArrayObject, pop_back, void, (),,
  563. "Removes the last element from the array" )
  564. {
  565. object->pop_back();
  566. }
  567. DefineEngineMethod( ArrayObject, pop_front, void, (),,
  568. "Removes the first element from the array" )
  569. {
  570. object->pop_front();
  571. }
  572. DefineEngineMethod( ArrayObject, erase, void, ( S32 index ),,
  573. "Removes an element at a specific position from the array.\n"
  574. "@param index 0-based index of the element to remove\n" )
  575. {
  576. object->erase( index );
  577. }
  578. DefineEngineMethod( ArrayObject, empty, void, (),,
  579. "Emptys all elements from an array" )
  580. {
  581. object->empty();
  582. }
  583. DefineEngineMethod( ArrayObject, uniqueValue, void, (),,
  584. "Removes any elements that have duplicated values (leaving the first instance)" )
  585. {
  586. object->uniqueValue();
  587. }
  588. DefineEngineMethod( ArrayObject, uniqueKey, void, (),,
  589. "Removes any elements that have duplicated keys (leaving the first instance)" )
  590. {
  591. object->uniqueKey();
  592. }
  593. DefineEngineMethod( ArrayObject, duplicate, bool, ( ArrayObject* target ),,
  594. "Alters array into an exact duplicate of the target array.\n"
  595. "@param target ArrayObject to duplicate\n" )
  596. {
  597. if ( target )
  598. {
  599. object->duplicate( target );
  600. return true;
  601. }
  602. return false;
  603. }
  604. DefineEngineMethod( ArrayObject, crop, bool, ( ArrayObject* target ),,
  605. "Removes elements with matching keys from array.\n"
  606. "@param target ArrayObject containing keys to remove from this array\n" )
  607. {
  608. if ( target )
  609. {
  610. object->crop( target );
  611. return true;
  612. }
  613. return false;
  614. }
  615. DefineEngineMethod( ArrayObject, append, bool, ( ArrayObject* target ),,
  616. "Appends the target array to the array object.\n"
  617. "@param target ArrayObject to append to the end of this array\n" )
  618. {
  619. if ( target )
  620. {
  621. object->append( target );
  622. return true;
  623. }
  624. return false;
  625. }
  626. DefineEngineMethod( ArrayObject, sort, void, ( bool ascending ), ( false ),
  627. "Alpha sorts the array by value\n\n"
  628. "@param ascending [optional] True for ascending sort, false for descending sort\n" )
  629. {
  630. object->sort( true, ascending, false );
  631. }
  632. DefineEngineMethod( ArrayObject, sorta, void, (),,
  633. "Alpha sorts the array by value in ascending order" )
  634. {
  635. object->sort( true, true, false );
  636. }
  637. DefineEngineMethod( ArrayObject, sortd, void, (),,
  638. "Alpha sorts the array by value in descending order" )
  639. {
  640. object->sort( true, false, false );
  641. }
  642. DefineEngineMethod( ArrayObject, sortk, void, ( bool ascending ), ( false ),
  643. "Alpha sorts the array by key\n\n"
  644. "@param ascending [optional] True for ascending sort, false for descending sort\n" )
  645. {
  646. object->sort( false, ascending, false );
  647. }
  648. DefineEngineMethod( ArrayObject, sortka, void, (),,
  649. "Alpha sorts the array by key in ascending order" )
  650. {
  651. object->sort( false, true, false );
  652. }
  653. DefineEngineMethod( ArrayObject, sortkd, void, (),,
  654. "Alpha sorts the array by key in descending order" )
  655. {
  656. object->sort( false, false, false );
  657. }
  658. DefineEngineMethod( ArrayObject, sortn, void, ( bool ascending ), ( false ),
  659. "Numerically sorts the array by value\n\n"
  660. "@param ascending [optional] True for ascending sort, false for descending sort\n" )
  661. {
  662. object->sort( true, ascending, true );
  663. }
  664. DefineEngineMethod( ArrayObject, sortna, void, (),,
  665. "Numerically sorts the array by value in ascending order" )
  666. {
  667. object->sort( true, true, true );
  668. }
  669. DefineEngineMethod( ArrayObject, sortnd, void, (),,
  670. "Numerically sorts the array by value in descending order" )
  671. {
  672. object->sort( true, false, true );
  673. }
  674. DefineEngineMethod( ArrayObject, sortnk, void, ( bool ascending ), ( false ),
  675. "Numerically sorts the array by key\n\n"
  676. "@param ascending [optional] True for ascending sort, false for descending sort\n" )
  677. {
  678. object->sort( false, ascending, true );
  679. }
  680. DefineEngineMethod( ArrayObject, sortnka, void, (),,
  681. "Numerical sorts the array by key in ascending order" )
  682. {
  683. object->sort( false, true, true );
  684. }
  685. DefineEngineMethod( ArrayObject, sortnkd, void, (),,
  686. "Numerical sorts the array by key in descending order" )
  687. {
  688. object->sort( false, false, true );
  689. }
  690. DefineEngineMethod( ArrayObject, sortf, void, ( const char* functionName ),,
  691. "Sorts the array by value in ascending order using the given callback function.\n"
  692. "@param functionName Name of a function that takes two arguments A and B and returns -1 if A is less, 1 if B is less, and 0 if both are equal.\n\n"
  693. "@tsexample\n"
  694. "function mySortCallback(%a, %b)\n"
  695. "{\n"
  696. " return strcmp( %a.name, %b.name );\n"
  697. "}\n\n"
  698. "%array.sortf( \"mySortCallback\" );\n"
  699. "@endtsexample\n" )
  700. {
  701. object->sort( true, true, functionName );
  702. }
  703. DefineEngineMethod( ArrayObject, sortfk, void, ( const char* functionName ),,
  704. "Sorts the array by key in ascending order using the given callback function.\n"
  705. "@param functionName Name of a function that takes two arguments A and B and returns -1 if A is less, 1 if B is less, and 0 if both are equal."
  706. "@see sortf\n" )
  707. {
  708. object->sort( false, true, functionName );
  709. }
  710. DefineEngineMethod( ArrayObject, sortfd, void, ( const char* functionName ),,
  711. "Sorts the array by value in descending order using the given callback function.\n"
  712. "@param functionName Name of a function that takes two arguments A and B and returns -1 if A is less, 1 if B is less, and 0 if both are equal."
  713. "@see sortf\n" )
  714. {
  715. object->sort( true, false, functionName );
  716. }
  717. DefineEngineMethod( ArrayObject, sortfkd, void, ( const char* functionName ),,
  718. "Sorts the array by key in descending order using the given callback function.\n"
  719. "@param functionName Name of a function that takes two arguments A and B and returns -1 if A is less, 1 if B is less, and 0 if both are equal."
  720. "@see sortf\n" )
  721. {
  722. object->sort( false, false, functionName );
  723. }
  724. DefineEngineMethod( ArrayObject, moveFirst, S32, (),,
  725. "Moves array pointer to start of array\n\n"
  726. "@return Returns the new array pointer" )
  727. {
  728. return object->moveFirst();
  729. }
  730. DefineEngineMethod( ArrayObject, moveLast, S32, (),,
  731. "Moves array pointer to end of array\n\n"
  732. "@return Returns the new array pointer" )
  733. {
  734. return object->moveLast();
  735. }
  736. DefineEngineMethod( ArrayObject, moveNext, S32, (),,
  737. "Moves array pointer to next position\n\n"
  738. "@return Returns the new array pointer, or -1 if already at the end" )
  739. {
  740. return object->moveNext();
  741. }
  742. DefineEngineMethod( ArrayObject, movePrev, S32, (),,
  743. "Moves array pointer to prev position\n\n"
  744. "@return Returns the new array pointer, or -1 if already at the start" )
  745. {
  746. return object->movePrev();
  747. }
  748. DefineEngineMethod( ArrayObject, getCurrent, S32, (),,
  749. "Gets the current pointer index" )
  750. {
  751. return object->getCurrent();
  752. }
  753. DefineEngineMethod( ArrayObject, setCurrent, void, ( S32 index ),,
  754. "Sets the current pointer index.\n"
  755. "@param index New 0-based pointer index\n" )
  756. {
  757. object->setCurrent( index );
  758. }
  759. DefineEngineMethod( ArrayObject, echo, void, (),,
  760. "Echos the array contents to the console" )
  761. {
  762. object->echo();
  763. }