arrayObject.cpp 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924
  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. ConsoleValue cValue = Con::executef((const char*)smCompareFunction, ea->key, eb->key);
  90. S32 result = cValue.getInt();
  91. S32 res = result < 0 ? -1 : ( result > 0 ? 1 : 0 );
  92. return ( smDecreasing ? -res : res );
  93. }
  94. S32 QSORT_CALLBACK ArrayObject::_valueFunctionCompare( const void* a, const void* b )
  95. {
  96. ArrayObject::Element* ea = ( ArrayObject::Element* )( a );
  97. ArrayObject::Element* eb = ( ArrayObject::Element* )( b );
  98. ConsoleValue cValue = Con::executef( (const char*)smCompareFunction, ea->value, eb->value );
  99. S32 result = cValue.getInt();
  100. S32 res = result < 0 ? -1 : ( result > 0 ? 1 : 0 );
  101. return ( smDecreasing ? -res : res );
  102. }
  103. //-----------------------------------------------------------------------------
  104. ArrayObject::ArrayObject()
  105. : mCaseSensitive( false ),
  106. mCurrentIndex( 0 )
  107. {
  108. }
  109. //-----------------------------------------------------------------------------
  110. void ArrayObject::initPersistFields()
  111. {
  112. addField( "caseSensitive", TypeBool, Offset( mCaseSensitive, ArrayObject ),
  113. "Makes the keys and values case-sensitive.\n"
  114. "By default, comparison of key and value strings will be case-insensitive." );
  115. addProtectedField( "key", TypeCaseString, 0, &_addKeyFromField, &emptyStringProtectedGetFn,
  116. "Helper field which allows you to add new key['keyname'] = value pairs." );
  117. Parent::initPersistFields();
  118. }
  119. //-----------------------------------------------------------------------------
  120. bool ArrayObject::_addKeyFromField( void *object, const char *index, const char *data )
  121. {
  122. static_cast<ArrayObject*>( object )->push_back( index, data );
  123. return false;
  124. }
  125. //-----------------------------------------------------------------------------
  126. S32 ArrayObject::getIndexFromValue( const String &value ) const
  127. {
  128. S32 currentIndex = mMax(mCurrentIndex, 0);
  129. S32 foundIndex = -1;
  130. for ( S32 i = currentIndex; i < mArray.size(); i++ )
  131. {
  132. if ( isEqual( mArray[i].value, value ) )
  133. {
  134. foundIndex = i;
  135. break;
  136. }
  137. }
  138. if( foundIndex < 0 )
  139. {
  140. for ( S32 i = 0; i < currentIndex; i++ )
  141. {
  142. if ( isEqual( mArray[i].value, value ) )
  143. {
  144. foundIndex = i;
  145. break;
  146. }
  147. }
  148. }
  149. return foundIndex;
  150. }
  151. //-----------------------------------------------------------------------------
  152. S32 ArrayObject::getIndexFromKey( const String &key ) const
  153. {
  154. S32 currentIndex = mMax(mCurrentIndex, 0);
  155. S32 foundIndex = -1;
  156. for ( S32 i = currentIndex; i < mArray.size(); i++ )
  157. {
  158. if ( isEqual( mArray[i].key, key ) )
  159. {
  160. foundIndex = i;
  161. break;
  162. }
  163. }
  164. if( foundIndex < 0 )
  165. {
  166. for ( S32 i = 0; i < currentIndex; i++ )
  167. {
  168. if ( isEqual( mArray[i].key, key ) )
  169. {
  170. foundIndex = i;
  171. break;
  172. }
  173. }
  174. }
  175. return foundIndex;
  176. }
  177. //-----------------------------------------------------------------------------
  178. S32 ArrayObject::getIndexFromKeyValue( const String &key, const String &value ) const
  179. {
  180. S32 currentIndex = mMax(mCurrentIndex, 0);
  181. S32 foundIndex = -1;
  182. for ( S32 i = currentIndex; i < mArray.size(); i++ )
  183. {
  184. if ( isEqual( mArray[i].key, key ) && isEqual( mArray[i].value, value ) )
  185. {
  186. foundIndex = i;
  187. break;
  188. }
  189. }
  190. if ( foundIndex < 0 )
  191. {
  192. for ( S32 i = 0; i < currentIndex; i++ )
  193. {
  194. if ( isEqual( mArray[i].key, key ) && isEqual( mArray[i].value, value ) )
  195. {
  196. foundIndex = i;
  197. break;
  198. }
  199. }
  200. }
  201. return foundIndex;
  202. }
  203. //-----------------------------------------------------------------------------
  204. const String& ArrayObject::getKeyFromIndex( S32 index ) const
  205. {
  206. if ( index >= mArray.size() || index < 0 )
  207. return String::EmptyString;
  208. return mArray[index].key;
  209. }
  210. //-----------------------------------------------------------------------------
  211. const String& ArrayObject::getValueFromIndex( S32 index ) const
  212. {
  213. if( index >= mArray.size() || index < 0 )
  214. return String::EmptyString;
  215. return mArray[index].value;
  216. }
  217. //-----------------------------------------------------------------------------
  218. S32 ArrayObject::countValue( const String &value ) const
  219. {
  220. S32 count = 0;
  221. for ( S32 i = 0; i < mArray.size(); i++ )
  222. {
  223. if ( isEqual( mArray[i].value, value ) )
  224. count++;
  225. }
  226. return count;
  227. }
  228. //-----------------------------------------------------------------------------
  229. S32 ArrayObject::countKey( const String &key) const
  230. {
  231. S32 count = 0;
  232. for ( S32 i = 0; i < mArray.size(); i++ )
  233. {
  234. if ( isEqual( mArray[i].key, key ) )
  235. count++;
  236. }
  237. return count;
  238. }
  239. //-----------------------------------------------------------------------------
  240. void ArrayObject::push_back( const String &key, const String &value )
  241. {
  242. mArray.push_back( Element( key, value ) );
  243. }
  244. //-----------------------------------------------------------------------------
  245. void ArrayObject::push_front( const String &key, const String &value )
  246. {
  247. mArray.push_front( Element( key, value ) );
  248. }
  249. //-----------------------------------------------------------------------------
  250. void ArrayObject::insert( const String &key, const String &value, S32 index )
  251. {
  252. index = mClamp( index, 0, mArray.size() );
  253. mArray.insert( index, Element( key, value ) );
  254. }
  255. //-----------------------------------------------------------------------------
  256. void ArrayObject::pop_back()
  257. {
  258. if(mArray.size() <= 0)
  259. return;
  260. mArray.pop_back();
  261. if( mCurrentIndex >= mArray.size() )
  262. mCurrentIndex = mArray.size() - 1;
  263. }
  264. //-----------------------------------------------------------------------------
  265. void ArrayObject::pop_front()
  266. {
  267. if( mArray.size() <= 0 )
  268. return;
  269. mArray.pop_front();
  270. if( mCurrentIndex >= mArray.size() )
  271. mCurrentIndex = mArray.size() - 1;
  272. }
  273. //-----------------------------------------------------------------------------
  274. void ArrayObject::erase( S32 index )
  275. {
  276. if(index < 0 || index >= mArray.size())
  277. return;
  278. mArray.erase( index );
  279. }
  280. //-----------------------------------------------------------------------------
  281. void ArrayObject::empty()
  282. {
  283. mArray.clear();
  284. mCurrentIndex = 0;
  285. }
  286. //-----------------------------------------------------------------------------
  287. void ArrayObject::moveIndex(S32 prev, S32 index)
  288. {
  289. if(index >= mArray.size())
  290. push_back(mArray[prev].key, mArray[prev].value);
  291. else
  292. mArray[index] = mArray[prev];
  293. mArray[prev].value = String::EmptyString;
  294. mArray[prev].key = String::EmptyString;
  295. }
  296. //-----------------------------------------------------------------------------
  297. void ArrayObject::uniqueValue()
  298. {
  299. for(S32 i=0; i<mArray.size(); i++)
  300. {
  301. for(S32 j=i+1; j<mArray.size(); j++)
  302. {
  303. if ( isEqual( mArray[i].value, mArray[j].value ) )
  304. {
  305. erase(j);
  306. j--;
  307. }
  308. }
  309. }
  310. }
  311. //-----------------------------------------------------------------------------
  312. void ArrayObject::uniqueKey()
  313. {
  314. for(S32 i=0; i<mArray.size(); i++)
  315. {
  316. for(S32 j=i+1; j<mArray.size(); j++)
  317. {
  318. if( isEqual( mArray[i].key, mArray[j].key ) )
  319. {
  320. erase(j);
  321. j--;
  322. }
  323. }
  324. }
  325. }
  326. //-----------------------------------------------------------------------------
  327. void ArrayObject::duplicate(ArrayObject* obj)
  328. {
  329. empty();
  330. for(S32 i=0; i<obj->count(); i++)
  331. {
  332. const String& tempval = obj->getValueFromIndex(i);
  333. const String& tempkey = obj->getKeyFromIndex(i);
  334. push_back(tempkey, tempval);
  335. }
  336. mCurrentIndex = obj->getCurrent();
  337. }
  338. //-----------------------------------------------------------------------------
  339. void ArrayObject::crop( ArrayObject *obj )
  340. {
  341. for( S32 i = 0; i < obj->count(); i++ )
  342. {
  343. const String &tempkey = obj->getKeyFromIndex( i );
  344. for( S32 j = 0; j < mArray.size(); j++ )
  345. {
  346. if( isEqual( mArray[j].key, tempkey ) )
  347. {
  348. mArray.erase( j );
  349. j--;
  350. }
  351. }
  352. }
  353. }
  354. //-----------------------------------------------------------------------------
  355. void ArrayObject::append(ArrayObject* obj)
  356. {
  357. for(S32 i=0; i<obj->count(); i++)
  358. {
  359. const String& tempval = obj->getValueFromIndex(i);
  360. const String& tempkey = obj->getKeyFromIndex(i);
  361. push_back(tempkey, tempval);
  362. }
  363. }
  364. //-----------------------------------------------------------------------------
  365. void ArrayObject::setKey( const String &key, S32 index )
  366. {
  367. if ( index >= mArray.size() )
  368. return;
  369. mArray[index].key = key;
  370. }
  371. //-----------------------------------------------------------------------------
  372. void ArrayObject::setValue( const String &value, S32 index )
  373. {
  374. if ( index >= mArray.size() )
  375. return;
  376. mArray[index].value = value;
  377. }
  378. //-----------------------------------------------------------------------------
  379. void ArrayObject::sort( bool valsort, bool asc, bool numeric )
  380. {
  381. if ( mArray.size() <= 1 )
  382. return;
  383. smDecreasing = asc ? false : true;
  384. smCaseSensitive = isCaseSensitive();
  385. if ( numeric )
  386. {
  387. if ( valsort )
  388. dQsort( (void *)&(mArray[0]), mArray.size(), sizeof(Element), _valueNumCompare) ;
  389. else
  390. dQsort( (void *)&(mArray[0]), mArray.size(), sizeof(Element), _keyNumCompare );
  391. }
  392. else
  393. {
  394. if( valsort )
  395. dQsort( (void *)&(mArray[0]), mArray.size(), sizeof(Element), _valueCompare );
  396. else
  397. dQsort( (void *)&(mArray[0]), mArray.size(), sizeof(Element), _keyCompare );
  398. }
  399. }
  400. //-----------------------------------------------------------------------------
  401. void ArrayObject::sort( bool valsort, bool asc, const char* callbackFunctionName )
  402. {
  403. if( mArray.size() <= 1 )
  404. return;
  405. smDecreasing = asc ? false : true;
  406. smCompareFunction = callbackFunctionName;
  407. if( valsort )
  408. dQsort( ( void* ) &( mArray[ 0 ] ), mArray.size(), sizeof( Element ), _valueFunctionCompare ) ;
  409. else
  410. dQsort( ( void* ) &( mArray[ 0 ] ), mArray.size(), sizeof( Element ), _keyFunctionCompare );
  411. smCompareFunction = NULL;
  412. }
  413. //-----------------------------------------------------------------------------
  414. S32 ArrayObject::moveFirst()
  415. {
  416. mCurrentIndex = 0;
  417. return mCurrentIndex;
  418. }
  419. //-----------------------------------------------------------------------------
  420. S32 ArrayObject::moveLast()
  421. {
  422. if ( mArray.empty() )
  423. mCurrentIndex = 0;
  424. else
  425. mCurrentIndex = mArray.size() - 1;
  426. return mCurrentIndex;
  427. }
  428. //-----------------------------------------------------------------------------
  429. S32 ArrayObject::moveNext()
  430. {
  431. if ( mCurrentIndex >= mArray.size() - 1 )
  432. return -1;
  433. mCurrentIndex++;
  434. return mCurrentIndex;
  435. }
  436. //-----------------------------------------------------------------------------
  437. S32 ArrayObject::movePrev()
  438. {
  439. if ( mCurrentIndex <= 0 )
  440. return -1;
  441. mCurrentIndex--;
  442. return mCurrentIndex;
  443. }
  444. //-----------------------------------------------------------------------------
  445. void ArrayObject::setCurrent( S32 idx )
  446. {
  447. if ( idx < 0 || idx >= mArray.size() )
  448. {
  449. Con::errorf( "ArrayObject::setCurrent( %d ) is out of the array bounds!", idx );
  450. return;
  451. }
  452. mCurrentIndex = idx;
  453. }
  454. //-----------------------------------------------------------------------------
  455. void ArrayObject::echo()
  456. {
  457. Con::printf( "ArrayObject Listing:" );
  458. Con::printf( "Index Key Value" );
  459. for ( U32 i = 0; i < mArray.size(); i++ )
  460. {
  461. const String& key = mArray[i].key;
  462. const String& val = mArray[i].value;
  463. Con::printf( "%d [%s] => %s", i, key.c_str(), val.c_str() );
  464. }
  465. }
  466. //=============================================================================
  467. // Console Methods.
  468. //=============================================================================
  469. DefineEngineMethod( ArrayObject, getIndexFromValue, S32, ( const char* value ),,
  470. "Search the array from the current position for the element "
  471. "@param value Array value to search for\n"
  472. "@return Index of the first element found, or -1 if none\n" )
  473. {
  474. return object->getIndexFromValue( value );
  475. }
  476. DefineEngineMethod( ArrayObject, getIndexFromKey, S32, ( const char* key ),,
  477. "Search the array from the current position for the key "
  478. "@param value Array key to search for\n"
  479. "@return Index of the first element found, or -1 if none\n" )
  480. {
  481. return object->getIndexFromKey( key );
  482. }
  483. DefineEngineMethod( ArrayObject, getValue, const char*, ( S32 index ),,
  484. "Get the value of the array element at the submitted index.\n"
  485. "@param index 0-based index of the array element to get\n"
  486. "@return The value of the array element at the specified index, "
  487. "or \"\" if the index is out of range\n" )
  488. {
  489. return object->getValueFromIndex( index ).c_str();
  490. }
  491. DefineEngineMethod( ArrayObject, getKey, const char*, ( S32 index ),,
  492. "Get the key of the array element at the submitted index.\n"
  493. "@param index 0-based index of the array element to get\n"
  494. "@return The key associated with the array element at the "
  495. "specified index, or \"\" if the index is out of range\n" )
  496. {
  497. return object->getKeyFromIndex( index ).c_str();
  498. }
  499. DefineEngineMethod( ArrayObject, setKey, void, ( const char* key, S32 index ),,
  500. "Set the key at the given index.\n"
  501. "@param key New key value\n"
  502. "@param index 0-based index of the array element to update\n" )
  503. {
  504. object->setKey( key, index );
  505. }
  506. DefineEngineMethod( ArrayObject, setValue, void, ( const char* value, S32 index ),,
  507. "Set the value at the given index.\n"
  508. "@param value New array element value\n"
  509. "@param index 0-based index of the array element to update\n" )
  510. {
  511. object->setValue( value, index );
  512. }
  513. DefineEngineMethod( ArrayObject, count, S32, (),,
  514. "Get the number of elements in the array." )
  515. {
  516. return (S32)object->count();
  517. }
  518. DefineEngineMethod( ArrayObject, countValue, S32, ( const char* value ),,
  519. "Get the number of times a particular value is found in the array.\n"
  520. "@param value Array element value to count\n" )
  521. {
  522. return (S32)object->countValue( value );
  523. }
  524. DefineEngineMethod( ArrayObject, countKey, S32, ( const char* key ),,
  525. "Get the number of times a particular key is found in the array.\n"
  526. "@param key Key value to count\n" )
  527. {
  528. return (S32)object->countKey( key );
  529. }
  530. DefineEngineMethod( ArrayObject, add, void, ( const char* key, const char* value ), ( "" ),
  531. "Adds a new element to the end of an array (same as push_back()).\n"
  532. "@param key Key for the new element\n"
  533. "@param value Value for the new element\n" )
  534. {
  535. object->push_back( key, value );
  536. }
  537. DefineEngineMethod( ArrayObject, push_back, void, ( const char* key, const char* value ), ( "" ),
  538. "Adds a new element to the end of an array.\n"
  539. "@param key Key for the new element\n"
  540. "@param value Value for the new element\n" )
  541. {
  542. object->push_back( key, value );
  543. }
  544. DefineEngineMethod( ArrayObject, push_front, void, ( const char* key, const char* value ), ( "" ),
  545. "Adds a new element to the front of an array" )
  546. {
  547. object->push_front( key, value );
  548. }
  549. DefineEngineMethod( ArrayObject, insert, void, ( const char* key, const char* value, S32 index ),,
  550. "Adds a new element to a specified position in the array.\n"
  551. "- @a index = 0 will insert an element at the start of the array (same as push_front())\n"
  552. "- @a index = %array.count() will insert an element at the end of the array (same as push_back())\n\n"
  553. "@param key Key for the new element\n"
  554. "@param value Value for the new element\n"
  555. "@param index 0-based index at which to insert the new element" )
  556. {
  557. object->insert( key, value, index );
  558. }
  559. DefineEngineMethod( ArrayObject, pop_back, void, (),,
  560. "Removes the last element from the array" )
  561. {
  562. object->pop_back();
  563. }
  564. DefineEngineMethod( ArrayObject, pop_front, void, (),,
  565. "Removes the first element from the array" )
  566. {
  567. object->pop_front();
  568. }
  569. DefineEngineMethod( ArrayObject, erase, void, ( S32 index ),,
  570. "Removes an element at a specific position from the array.\n"
  571. "@param index 0-based index of the element to remove\n" )
  572. {
  573. object->erase( index );
  574. }
  575. DefineEngineMethod( ArrayObject, empty, void, (),,
  576. "Emptys all elements from an array" )
  577. {
  578. object->empty();
  579. }
  580. DefineEngineMethod( ArrayObject, uniqueValue, void, (),,
  581. "Removes any elements that have duplicated values (leaving the first instance)" )
  582. {
  583. object->uniqueValue();
  584. }
  585. DefineEngineMethod( ArrayObject, uniqueKey, void, (),,
  586. "Removes any elements that have duplicated keys (leaving the first instance)" )
  587. {
  588. object->uniqueKey();
  589. }
  590. DefineEngineMethod( ArrayObject, duplicate, bool, ( ArrayObject* target ),,
  591. "Alters array into an exact duplicate of the target array.\n"
  592. "@param target ArrayObject to duplicate\n" )
  593. {
  594. if ( target )
  595. {
  596. object->duplicate( target );
  597. return true;
  598. }
  599. return false;
  600. }
  601. DefineEngineMethod( ArrayObject, crop, bool, ( ArrayObject* target ),,
  602. "Removes elements with matching keys from array.\n"
  603. "@param target ArrayObject containing keys to remove from this array\n" )
  604. {
  605. if ( target )
  606. {
  607. object->crop( target );
  608. return true;
  609. }
  610. return false;
  611. }
  612. DefineEngineMethod( ArrayObject, append, bool, ( ArrayObject* target ),,
  613. "Appends the target array to the array object.\n"
  614. "@param target ArrayObject to append to the end of this array\n" )
  615. {
  616. if ( target )
  617. {
  618. object->append( target );
  619. return true;
  620. }
  621. return false;
  622. }
  623. DefineEngineMethod( ArrayObject, sort, void, ( bool ascending ), ( false ),
  624. "Alpha sorts the array by value\n\n"
  625. "@param ascending [optional] True for ascending sort, false for descending sort\n" )
  626. {
  627. object->sort( true, ascending, false );
  628. }
  629. DefineEngineMethod( ArrayObject, sorta, void, (),,
  630. "Alpha sorts the array by value in ascending order" )
  631. {
  632. object->sort( true, true, false );
  633. }
  634. DefineEngineMethod( ArrayObject, sortd, void, (),,
  635. "Alpha sorts the array by value in descending order" )
  636. {
  637. object->sort( true, false, false );
  638. }
  639. DefineEngineMethod( ArrayObject, sortk, void, ( bool ascending ), ( false ),
  640. "Alpha sorts the array by key\n\n"
  641. "@param ascending [optional] True for ascending sort, false for descending sort\n" )
  642. {
  643. object->sort( false, ascending, false );
  644. }
  645. DefineEngineMethod( ArrayObject, sortka, void, (),,
  646. "Alpha sorts the array by key in ascending order" )
  647. {
  648. object->sort( false, true, false );
  649. }
  650. DefineEngineMethod( ArrayObject, sortkd, void, (),,
  651. "Alpha sorts the array by key in descending order" )
  652. {
  653. object->sort( false, false, false );
  654. }
  655. DefineEngineMethod( ArrayObject, sortn, void, ( bool ascending ), ( false ),
  656. "Numerically sorts the array by value\n\n"
  657. "@param ascending [optional] True for ascending sort, false for descending sort\n" )
  658. {
  659. object->sort( true, ascending, true );
  660. }
  661. DefineEngineMethod( ArrayObject, sortna, void, (),,
  662. "Numerically sorts the array by value in ascending order" )
  663. {
  664. object->sort( true, true, true );
  665. }
  666. DefineEngineMethod( ArrayObject, sortnd, void, (),,
  667. "Numerically sorts the array by value in descending order" )
  668. {
  669. object->sort( true, false, true );
  670. }
  671. DefineEngineMethod( ArrayObject, sortnk, void, ( bool ascending ), ( false ),
  672. "Numerically sorts the array by key\n\n"
  673. "@param ascending [optional] True for ascending sort, false for descending sort\n" )
  674. {
  675. object->sort( false, ascending, true );
  676. }
  677. DefineEngineMethod( ArrayObject, sortnka, void, (),,
  678. "Numerical sorts the array by key in ascending order" )
  679. {
  680. object->sort( false, true, true );
  681. }
  682. DefineEngineMethod( ArrayObject, sortnkd, void, (),,
  683. "Numerical sorts the array by key in descending order" )
  684. {
  685. object->sort( false, false, true );
  686. }
  687. DefineEngineMethod( ArrayObject, sortf, void, ( const char* functionName ),,
  688. "Sorts the array by value in ascending order using the given callback function.\n"
  689. "@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"
  690. "@tsexample\n"
  691. "function mySortCallback(%a, %b)\n"
  692. "{\n"
  693. " return strcmp( %a.name, %b.name );\n"
  694. "}\n\n"
  695. "%array.sortf( \"mySortCallback\" );\n"
  696. "@endtsexample\n" )
  697. {
  698. object->sort( true, true, functionName );
  699. }
  700. DefineEngineMethod( ArrayObject, sortfk, void, ( const char* functionName ),,
  701. "Sorts the array by key in ascending order using the given callback function.\n"
  702. "@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."
  703. "@see sortf\n" )
  704. {
  705. object->sort( false, true, functionName );
  706. }
  707. DefineEngineMethod( ArrayObject, sortfd, void, ( const char* functionName ),,
  708. "Sorts the array by value in descending order using the given callback function.\n"
  709. "@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."
  710. "@see sortf\n" )
  711. {
  712. object->sort( true, false, functionName );
  713. }
  714. DefineEngineMethod( ArrayObject, sortfkd, void, ( const char* functionName ),,
  715. "Sorts the array by key in descending order using the given callback function.\n"
  716. "@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."
  717. "@see sortf\n" )
  718. {
  719. object->sort( false, false, functionName );
  720. }
  721. DefineEngineMethod( ArrayObject, moveFirst, S32, (),,
  722. "Moves array pointer to start of array\n\n"
  723. "@return Returns the new array pointer" )
  724. {
  725. return object->moveFirst();
  726. }
  727. DefineEngineMethod( ArrayObject, moveLast, S32, (),,
  728. "Moves array pointer to end of array\n\n"
  729. "@return Returns the new array pointer" )
  730. {
  731. return object->moveLast();
  732. }
  733. DefineEngineMethod( ArrayObject, moveNext, S32, (),,
  734. "Moves array pointer to next position\n\n"
  735. "@return Returns the new array pointer, or -1 if already at the end" )
  736. {
  737. return object->moveNext();
  738. }
  739. DefineEngineMethod( ArrayObject, movePrev, S32, (),,
  740. "Moves array pointer to prev position\n\n"
  741. "@return Returns the new array pointer, or -1 if already at the start" )
  742. {
  743. return object->movePrev();
  744. }
  745. DefineEngineMethod( ArrayObject, getCurrent, S32, (),,
  746. "Gets the current pointer index" )
  747. {
  748. return object->getCurrent();
  749. }
  750. DefineEngineMethod( ArrayObject, setCurrent, void, ( S32 index ),,
  751. "Sets the current pointer index.\n"
  752. "@param index New 0-based pointer index\n" )
  753. {
  754. object->setCurrent( index );
  755. }
  756. DefineEngineMethod( ArrayObject, echo, void, (),,
  757. "Echos the array contents to the console" )
  758. {
  759. object->echo();
  760. }