VController.cpp 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161
  1. //-----------------------------------------------------------------------------
  2. // Verve
  3. // Copyright (C) 2014 - Violent Tulip
  4. //
  5. // Permission is hereby granted, free of charge, to any person obtaining a copy
  6. // of this software and associated documentation files (the "Software"), to
  7. // deal in the Software without restriction, including without limitation the
  8. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  9. // sell copies of the Software, and to permit persons to whom the Software is
  10. // furnished to do so, subject to the following conditions:
  11. //
  12. // The above copyright notice and this permission notice shall be included in
  13. // all copies or substantial portions of the Software.
  14. //
  15. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  20. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  21. // IN THE SOFTWARE.
  22. //-----------------------------------------------------------------------------
  23. #include "Verve/Core/VController.h"
  24. #include "Verve/Core/VObject.h"
  25. #include "Verve/Core/VGroup.h"
  26. #include "Verve/Core/VTrack.h"
  27. #include "Verve/Extension/Director/VDirectorGroup.h"
  28. #include "console/consoleObject.h"
  29. #include "console/consoleTypes.h"
  30. #include "math/mMathFn.h"
  31. //-----------------------------------------------------------------------------
  32. IMPLEMENT_CONOBJECT( VController );
  33. //-----------------------------------------------------------------------------
  34. VController::VController( void ) :
  35. mStatus( ( k_StatusInit | k_StatusStopped ) ),
  36. mTime( 0 ),
  37. mLastTime( 0 ),
  38. mTimeScale( 1.f ),
  39. mDuration( 5000 ),
  40. mLoop( false ),
  41. mLoopBackwards( false ),
  42. mLoopCount( -1 ),
  43. mLoopIndex( 0 ),
  44. mLoopDelay( 0 ),
  45. mLoopDelayTime( 0 ),
  46. mJump( k_JumpInvalid ),
  47. mJumpTime( 0 ),
  48. mResetOnCompletion( true )
  49. {
  50. // Don't Process Ticks.
  51. setProcessTicks( false );
  52. }
  53. VController::~VController( void )
  54. {
  55. // Void.
  56. }
  57. void VController::initPersistFields()
  58. {
  59. docsURL;
  60. addGroup( "Controller" );
  61. addProtectedField( "Time", TypeS32, Offset( mTime, VController ), &setTime, &defaultProtectedGetFn, "Current position of the Controller (in milliseconds)." );
  62. addProtectedField( "Duration", TypeS32, Offset( mDuration, VController ), &setDuration, &defaultProtectedGetFn, "Total length of the sequence (in milliseconds)." );
  63. addProtectedField( "TimeScale", TypeF32, Offset( mTimeScale, VController ), &setTimeScale, &defaultProtectedGetFn, "Speed of playback. A value > 0.0 will enable the Controller to play forwards, while a value < 0.0 will play backwards. If |TimeScale| > 1.0, then playback will be faster than normal, while |TimeScale| < 1.0 will be slower." );
  64. addField( "Loop", TypeBool, Offset( mLoop, VController ), "Instead of stopping once playback is complete, the Controller will reset and resume play." );
  65. addField( "LoopBackwards", TypeBool, Offset( mLoopBackwards, VController ), "When the sequence loops, reverse the direction of play." );
  66. addField( "LoopCount", TypeS32, Offset( mLoopCount, VController ), "The number of times the sequence loops before stopping. -1 will cause the sequence to loop indefinitely." );
  67. addField( "LoopDelay", TypeS32, Offset( mLoopDelay, VController ), "When the sequence loops, delay playback by this value (in milliseconds)." );
  68. addField( "ResetOnCompletion", TypeBool, Offset( mResetOnCompletion, VController ), "When the sequence is completed, reset the state of the Controller." );
  69. endGroup( "Controller" );
  70. // Parent Call.
  71. Parent::initPersistFields();
  72. }
  73. //-----------------------------------------------------------------------------
  74. //
  75. // ITickable Methods.
  76. //
  77. //-----------------------------------------------------------------------------
  78. //-----------------------------------------------------------------------------
  79. //
  80. // VController::processTick();
  81. //
  82. // This method controls the playback of the entire sequence. It integrates all
  83. // of the groups and handles sequence looping and jumping.
  84. //
  85. //-----------------------------------------------------------------------------
  86. void VController::processTick( void )
  87. {
  88. if ( mTimeScale == 0.f )
  89. {
  90. // Pause.
  91. pause();
  92. // Exit.
  93. return;
  94. }
  95. // Calculate Delta.
  96. const S32 time = Sim::getCurrentTime();
  97. S32 delta = ( time - mLastTime );
  98. mLastTime = time;
  99. // Reverse?
  100. if ( mTimeScale < 0.f )
  101. {
  102. // Negative Delta.
  103. delta *= -1;
  104. }
  105. if ( mLoopDelayTime > 0 )
  106. {
  107. // Update Delay Time.
  108. mLoopDelayTime -= getMin( mAbs( delta ), mLoopDelayTime );
  109. // Exit.
  110. return;
  111. }
  112. // Jump Delta?
  113. if ( mJump == k_JumpDelta )
  114. {
  115. // Jump.
  116. delta = mJumpTime;
  117. // Clear.
  118. mJump = k_JumpInvalid;
  119. mJumpTime = 0;
  120. }
  121. if ( ( isPlayingForward() && ( mTime + delta ) > mDuration )
  122. || ( !isPlayingForward() && ( mTime + delta ) < 0 ) )
  123. {
  124. // Clamp Delta.
  125. delta = ( ( mTimeScale > 0.f ) * mDuration ) - mTime;
  126. // Note: If we are playing forwards, we're at the end of the
  127. // sequence and we want to loop/reset the Controller, then we
  128. // need to handle that now.
  129. if ( delta == 0 )
  130. {
  131. onPostTick();
  132. }
  133. }
  134. // Valid Delta?
  135. if ( delta == 0 )
  136. {
  137. // Exit.
  138. return;
  139. }
  140. // Trigger Update.
  141. mControllerUpdateSignal.trigger( mTime, delta );
  142. // Update Time.
  143. mTime += delta;
  144. // Perform Post Tick.
  145. onPostTick();
  146. }
  147. //-----------------------------------------------------------------------------
  148. //
  149. // VController::onPostTick();
  150. //
  151. // This method is called onces a tick has been processed. It will perform the
  152. // the right checks to see if the Controller has finished playing. It also
  153. // handles special cases like Looping or Resetting the Controller.
  154. //
  155. //-----------------------------------------------------------------------------
  156. void VController::onPostTick( void )
  157. {
  158. // Jump Time?
  159. if ( mJump == k_JumpTime )
  160. {
  161. // Jump Post Update.
  162. reset( mJumpTime );
  163. // Clear.
  164. mJump = k_JumpInvalid;
  165. mJumpTime = 0;
  166. }
  167. // Sequence Completed?
  168. if ( isPlayingForward() && mTime >= mDuration
  169. || !isPlayingForward() && mTime <= 0 )
  170. {
  171. bool stopPlaying = true;
  172. if ( mLoop )
  173. {
  174. // Don't Stop.
  175. stopPlaying = false;
  176. if ( mLoopBackwards )
  177. {
  178. // Change Direction.
  179. setTimeScale( -1.f * mTimeScale );
  180. }
  181. else
  182. {
  183. // Reset Time.
  184. reset();
  185. }
  186. if ( mLoopDelay > 0 )
  187. {
  188. // Resume After Delay.
  189. mLoopDelayTime = mLoopDelay;
  190. }
  191. // At the Start of the Sequence?
  192. if ( mTime <= 0 && mLoopCount >= 0 )
  193. {
  194. // Stop Looping?
  195. stopPlaying = ( ++mLoopIndex >= mLoopCount );
  196. }
  197. // Callback.
  198. Con::executef( this, "onLoop" );
  199. // Loop Signal.
  200. postEvent( k_EventLoop );
  201. }
  202. // Stop?
  203. if ( stopPlaying )
  204. {
  205. // Stop Only.
  206. stop( mResetOnCompletion );
  207. }
  208. }
  209. }
  210. //-----------------------------------------------------------------------------
  211. //
  212. // Controller Methods.
  213. //
  214. //-----------------------------------------------------------------------------
  215. //-----------------------------------------------------------------------------
  216. //
  217. // VController::reset();
  218. //
  219. // Reset the Controller to the start of the sequence.
  220. //
  221. //-----------------------------------------------------------------------------
  222. void VController::reset( void )
  223. {
  224. // Reset.
  225. reset( ( isPlayingForward() ) ? 0 : mDuration );
  226. }
  227. //-----------------------------------------------------------------------------
  228. //
  229. // VController::reset( pTime );
  230. //
  231. // Reset the Controller to the target time. This is a very important method as
  232. // it allows tracks and events to reset their state as well as prepare
  233. // themselves for playback.
  234. //
  235. //-----------------------------------------------------------------------------
  236. void VController::reset( const S32 &pTime )
  237. {
  238. // Reset Time.
  239. mTime = pTime;
  240. mLastTime = Sim::getCurrentTime();
  241. // Reset Delay Time.
  242. mLoopDelayTime = 0;
  243. // Post Event.
  244. postEvent( k_EventReset );
  245. }
  246. //-----------------------------------------------------------------------------
  247. //
  248. // VController::play();
  249. //
  250. // Start playing the sequence from the current time and execute a number of
  251. // callbacks.
  252. //
  253. //-----------------------------------------------------------------------------
  254. void VController::play( void )
  255. {
  256. if ( isPlaying() || mTime < 0 || mTime > mDuration )
  257. {
  258. // Sanity!
  259. return;
  260. }
  261. // Reset Time.
  262. mLastTime = Sim::getCurrentTime();
  263. // Start Updating.
  264. setProcessTicks( true );
  265. if ( mStatus & k_StatusInit )
  266. {
  267. // Init Signal.
  268. postEvent( k_EventInit );
  269. // Clear Init Status.
  270. mStatus &= ~k_StatusInit;
  271. }
  272. // Update Status.
  273. updateStatus( k_StatusPlaying );
  274. // Play Signal.
  275. postEvent( k_EventPlay );
  276. // Callback.
  277. Con::executef( this, "onPlay" );
  278. }
  279. //-----------------------------------------------------------------------------
  280. //
  281. // VController::play( pTime );
  282. //
  283. // Start playing the sequence from the desired time.
  284. //
  285. //-----------------------------------------------------------------------------
  286. void VController::play( const S32 &pTime )
  287. {
  288. // Reset.
  289. reset( pTime );
  290. // Play.
  291. play();
  292. }
  293. //-----------------------------------------------------------------------------
  294. //
  295. // VController::pause();
  296. //
  297. // Cease playback of the sequence, but maintain the current time.
  298. //
  299. //-----------------------------------------------------------------------------
  300. void VController::pause( void )
  301. {
  302. // Stop Updating.
  303. setProcessTicks( false );
  304. // Update Status.
  305. updateStatus( k_StatusPaused );
  306. // Pause Signal.
  307. postEvent( k_EventPause );
  308. // Callback.
  309. Con::executef( this, "onPause" );
  310. }
  311. //-----------------------------------------------------------------------------
  312. //
  313. // VController::stop( pReset );
  314. //
  315. // Stop playback altogether and reset the Controller to the start of the
  316. // sequence.
  317. //
  318. //-----------------------------------------------------------------------------
  319. void VController::stop( const bool &pReset )
  320. {
  321. // Stop Updating.
  322. setProcessTicks( false );
  323. // Reset Loop Index.
  324. mLoopIndex = 0;
  325. // Update Status.
  326. updateStatus( ( k_StatusInit | k_StatusStopped ) );
  327. // Reset?
  328. if ( pReset )
  329. {
  330. // Reset.
  331. reset();
  332. }
  333. // Stop Signal.
  334. postEvent( k_EventStop );
  335. // Callback.
  336. Con::executef( this, "onStop" );
  337. }
  338. //-----------------------------------------------------------------------------
  339. //
  340. // VController::jump();
  341. //
  342. // Jump the Controller time forward 1 tick (32ms).
  343. //
  344. //-----------------------------------------------------------------------------
  345. void VController::jump( void )
  346. {
  347. // Jump 1 tick.
  348. jump( k_JumpDelta, ( isPlayingForward() ) ? TickMs : -TickMs );
  349. }
  350. //-----------------------------------------------------------------------------
  351. //
  352. // VController::jump( pType, pDelta );
  353. //
  354. // Jump the Controller time by the target Delta.
  355. //
  356. //-----------------------------------------------------------------------------
  357. void VController::jump( const eControllerJumpType &pType, const S32 &pDelta )
  358. {
  359. // Jump.
  360. mJump = pType;
  361. mJumpTime = pDelta;
  362. }
  363. //-----------------------------------------------------------------------------
  364. //
  365. // VController::updateStatus( pStatus );
  366. //
  367. // Clear the regular playback states and add the updated state.
  368. //
  369. //-----------------------------------------------------------------------------
  370. void VController::updateStatus( const S32 &pStatus )
  371. {
  372. // Clear Playback Status.
  373. mStatus &= ~( k_StatusPlaying | k_StatusPaused | k_StatusStopped );
  374. // Add New Status.
  375. mStatus |= pStatus;
  376. }
  377. //-----------------------------------------------------------------------------
  378. //
  379. // Reference Methods.
  380. //
  381. //-----------------------------------------------------------------------------
  382. //-----------------------------------------------------------------------------
  383. //
  384. // VController::getObject( pLabel );
  385. //
  386. // Returns the group with the given name. If no group belongs to the Controller
  387. // with that name, then a NULL value is returned.
  388. //
  389. //-----------------------------------------------------------------------------
  390. VGroup *VController::getObject( const String &pLabel )
  391. {
  392. VGroup *node = ( VGroup* )mChildNode;
  393. while ( node )
  394. {
  395. // Compare Names.
  396. if ( node->getLabel().equal( pLabel, String::NoCase ) )
  397. {
  398. // Valid.
  399. return node;
  400. }
  401. // Next Sibling.
  402. node = ( VGroup* )node->mSiblingNextNode;
  403. }
  404. // Invalid.
  405. return NULL;
  406. }
  407. //-----------------------------------------------------------------------------
  408. //
  409. // VController::getDirectorGroup();
  410. //
  411. // Returns the DirectorGroup reference if the Controller has a one.
  412. //
  413. //-----------------------------------------------------------------------------
  414. VDirectorGroup *VController::getDirectorGroup( void )
  415. {
  416. for ( ITreeNode *node = mChildNode; node != NULL; node = node->mSiblingNextNode )
  417. {
  418. if ( VDirectorGroup *group = dynamic_cast<VDirectorGroup*>( node ) )
  419. {
  420. // Return Group.
  421. return group;
  422. }
  423. }
  424. // Invalid Group.
  425. return NULL;
  426. }
  427. //-----------------------------------------------------------------------------
  428. //
  429. // VController::getDirectorTrack();
  430. //
  431. // Returns the DirectorTrack reference if the DirectorGroup has one.
  432. //
  433. //-----------------------------------------------------------------------------
  434. VDirectorTrack *VController::getDirectorTrack( void )
  435. {
  436. VDirectorGroup *group = getDirectorGroup();
  437. if ( !group )
  438. {
  439. // Invalid Track.
  440. return NULL;
  441. }
  442. // Return Track.
  443. return group->getDirectorTrack();
  444. }
  445. //-----------------------------------------------------------------------------
  446. //
  447. // VController::getDataValue( pFieldName, *pValue );
  448. //
  449. // Returns true if the field is a DataTable member and can be correctly
  450. // evaluated. If this is the case, then pValue will contain the result.
  451. //
  452. //-----------------------------------------------------------------------------
  453. bool VController::getDataValue( const String &pFieldName, String &pValue )
  454. {
  455. return mDataTable.getValue( this, pFieldName, pValue );
  456. }
  457. //-----------------------------------------------------------------------------
  458. //
  459. // VController::clearData();
  460. //
  461. // Clear the contents of the DataTable entirely.
  462. //
  463. //-----------------------------------------------------------------------------
  464. void VController::clearData( void )
  465. {
  466. while ( mDataTable.getCount() > 0 )
  467. {
  468. // Clear Item.
  469. clearData( 0 );
  470. }
  471. }
  472. //-----------------------------------------------------------------------------
  473. //
  474. // VController::clearData( pIndex );
  475. //
  476. // Clear the DataTable entry with the given index.
  477. //
  478. //-----------------------------------------------------------------------------
  479. void VController::clearData( const S32 &pIndex )
  480. {
  481. VDataTable::sDataItem data;
  482. if ( mDataTable.getItem( pIndex, &data ) )
  483. {
  484. // Clear Data.
  485. clearData( data.FieldName );
  486. }
  487. }
  488. //-----------------------------------------------------------------------------
  489. //
  490. // VController::clearData( pIndex );
  491. //
  492. // Clear the DataTable entry with the given field name.
  493. //
  494. //-----------------------------------------------------------------------------
  495. void VController::clearData( const String &pFieldName )
  496. {
  497. // Clear Dynamic Field.
  498. setDataField( pFieldName, NULL, "" );
  499. // Clear Item.
  500. mDataTable.clear( pFieldName );
  501. }
  502. //-----------------------------------------------------------------------------
  503. //
  504. // VController::sort();
  505. //
  506. // Sort each track in each of the child groups.
  507. //
  508. //-----------------------------------------------------------------------------
  509. void VController::sort( void )
  510. {
  511. for ( ITreeNode *group = mChildNode; group != NULL; group = group->mSiblingNextNode )
  512. {
  513. for ( ITreeNode *track = group->mChildNode; track != NULL; track = track->mSiblingNextNode )
  514. {
  515. // Sort Track.
  516. ( ( VTrack* )track )->sort();
  517. }
  518. }
  519. }
  520. //-----------------------------------------------------------------------------
  521. //
  522. // Write Methods.
  523. //
  524. //-----------------------------------------------------------------------------
  525. //-----------------------------------------------------------------------------
  526. //
  527. // VController::writeDataTable( pElement );
  528. //
  529. // Write the DataTable out to a TinyXML document.
  530. //
  531. //-----------------------------------------------------------------------------
  532. bool VController::writeDataTable( tinyxml2::XMLElement *pElement )
  533. {
  534. // Create Data Table Root.
  535. tinyxml2::XMLElement *dataTableRoot = pElement->GetDocument()->NewElement( "DataTable" );
  536. pElement->LinkEndChild( dataTableRoot );
  537. for ( VDataTable::VDataMap::Iterator itr = mDataTable.mDataMap.begin(); itr != mDataTable.mDataMap.end(); ++itr )
  538. {
  539. // Fetch Data.
  540. VDataTable::sDataItem *data = &itr->value;
  541. // Create Element.
  542. tinyxml2::XMLElement* dataElement = pElement->GetDocument()->NewElement( "DataItem" );
  543. // Apply Attributes.
  544. dataElement->SetAttribute( "Type", VDataTable::getDataTypeDescription( data->Type ) );
  545. dataElement->SetAttribute( "Name", data->FieldName.c_str() );
  546. dataElement->SetAttribute( "Value", getDataField( StringTable->insert( data->FieldName.c_str() ), NULL ) );
  547. // Add.
  548. dataTableRoot->LinkEndChild( dataElement );
  549. }
  550. return true;
  551. }
  552. //-----------------------------------------------------------------------------
  553. //
  554. // Read Methods.
  555. //
  556. //-----------------------------------------------------------------------------
  557. //-----------------------------------------------------------------------------
  558. //
  559. // VController::readDataTable( pElement );
  560. //
  561. // Read the DataTable from a TinyXML document.
  562. //
  563. //-----------------------------------------------------------------------------
  564. bool VController::readDataTable( tinyxml2::XMLElement *pElement )
  565. {
  566. tinyxml2::XMLElement *dataTableRoot = pElement->FirstChildElement( "DataTable" );
  567. if ( dataTableRoot )
  568. {
  569. for ( tinyxml2::XMLElement *child = dataTableRoot->FirstChildElement(); child != NULL; child = child->NextSiblingElement() )
  570. {
  571. // Get Field Data.
  572. const char *fieldType = child->Attribute( "Type" );
  573. const char *fieldName = child->Attribute( "Name" );
  574. const char *fieldValue = child->Attribute( "Value" );
  575. // Add Data Item.
  576. mDataTable.insert( VDataTable::getDataTypeEnum( fieldType ), fieldName );
  577. // Set Field Value.
  578. setDataField( StringTable->insert( fieldName ), NULL, fieldValue );
  579. }
  580. }
  581. // Valid Read.
  582. return true;
  583. }
  584. //-----------------------------------------------------------------------------
  585. //
  586. // Property Methods.
  587. //
  588. //-----------------------------------------------------------------------------
  589. //-----------------------------------------------------------------------------
  590. //
  591. // VController::postEvent( pEvent );
  592. //
  593. // Process an event signal to all event subscribers. This method is used to
  594. // signal changes in the Controller's status.
  595. //
  596. // For a full list of possible events, see the 'eControllerEventType'
  597. // declaration in VController.h.
  598. //
  599. //-----------------------------------------------------------------------------
  600. void VController::postEvent( const eControllerEventType &pEvent )
  601. {
  602. // Signal Event.
  603. mControllerEventSignal.trigger( pEvent );
  604. }
  605. //-----------------------------------------------------------------------------
  606. //
  607. // VController::setTimeScale( pTimeScale );
  608. //
  609. // Set the speed of playback. In effect, a value of 0.5 will double the real
  610. // time taken to complete the playback of the sequence, while a value of 2.0
  611. // will halve the time needed.
  612. //
  613. //-----------------------------------------------------------------------------
  614. void VController::setTimeScale( const F32 &pTimeScale )
  615. {
  616. // Need an Update?
  617. const bool update = ( pTimeScale != 0.f && ( mTimeScale == 0.f || ( ( mTimeScale > 0.f ) != ( pTimeScale > 0.f ) ) ) );
  618. // Store.
  619. mTimeScale = pTimeScale;
  620. // Update $timeScale Variable.
  621. Con::setFloatVariable( "timeScale", mFabs( mTimeScale ) );
  622. if ( update )
  623. {
  624. // Reset.
  625. reset( mTime );
  626. }
  627. }
  628. //-----------------------------------------------------------------------------
  629. //
  630. // Console Methods.
  631. //
  632. //-----------------------------------------------------------------------------
  633. DefineEngineMethod( VController, readFile, bool, (String fileName), (""), "( string pFileName ) - Clears the object and loads the new data from the given filename.\n"
  634. "@param pFileName The target file to read from.\n"
  635. "@return Returns true if the read was successful." )
  636. {
  637. // Clear Sequence Lists.
  638. object->clear();
  639. // Clear Data Table.
  640. object->clearData();
  641. // Read Target File.
  642. if ( !VPersistence::readFile( fileName, object ) )
  643. {
  644. // Re-Clear.
  645. object->clear();
  646. // Invalid Read.
  647. return false;
  648. }
  649. // Initial Sort.
  650. object->sort();
  651. // Reset.
  652. object->reset();
  653. // Valid Read.
  654. return true;
  655. }
  656. DefineEngineMethod( VController, clear, void, (), , "( void ) - Detaches and deletes all of the child objects.\n"
  657. "@return No return value." )
  658. {
  659. // Clear Sequence Lists.
  660. object->clear();
  661. // Clear Data Table.
  662. object->clearData();
  663. }
  664. DefineEngineMethod( VController, reset, void, (S32 time), (-1), "( [int pTime] ) - Reset the Controller's and child object's state.\n"
  665. "@param pTime The target time to reset to.\n"
  666. "@return No return value." )
  667. {
  668. if (time != -1)
  669. {
  670. // Reset Sequence.
  671. object->reset(time);
  672. return;
  673. }
  674. // Default Reset.
  675. object->reset();
  676. }
  677. DefineEngineMethod( VController, isPlaying, bool, (), , "( void ) - Is the sequence currently playing?\n"
  678. "@return Returns true if the Controller is playing." )
  679. {
  680. // Is Playing?
  681. return ( object->isPlaying() );
  682. }
  683. DefineEngineMethod( VController, play, void, (S32 time), (-1), "( [int pTime] ) - Play the sequence. If a value for pTime is specified, the Controller is reset and played from that time.\n"
  684. "@param pTime The time to start playing the sequence from.\n"
  685. "@return No return value." )
  686. {
  687. S32 startTime = object->getTime();
  688. if (time != -1)
  689. {
  690. startTime = time;
  691. }
  692. // Play From Specified Time.
  693. object->play( startTime );
  694. }
  695. DefineEngineMethod( VController, step, void, (),, "( void ) - Step forward one frame.\n"
  696. "@return No return value." )
  697. {
  698. if ( object->isPlaying() )
  699. {
  700. // Sanity!
  701. return;
  702. }
  703. // Play.
  704. object->play( object->getTime() );
  705. // Jump.
  706. object->jump();
  707. // Step Forward One Frame.
  708. object->processTick();
  709. // Stop.
  710. object->stop( false );
  711. }
  712. DefineEngineMethod( VController, isPaused, bool, (), , "( void ) - Is the sequence currently paused?\n"
  713. "@return Returns true if the Controller is paused." )
  714. {
  715. // Is Paused?
  716. return ( object->isPaused() );
  717. }
  718. DefineEngineMethod( VController, pause, void, (), , "( void ) - Pause the sequence. Playback can resume by calling VController::play().\n"
  719. "@return No return value." )
  720. {
  721. // Pause Sequence.
  722. object->pause();
  723. }
  724. DefineEngineMethod( VController, isStopped, bool, (), , "( void ) - Is the sequence currently stopped?\n"
  725. "@return Returns true if the Controller is stopped." )
  726. {
  727. // Is Stopped?
  728. return ( object->isStopped() );
  729. }
  730. DefineEngineMethod( VController, stop, void, (bool reset), (true), "( [bool pReset] ) - Stop the sequence and optionally reset it.\n"
  731. "@param pReset Reset the Controller after stopping.\n"
  732. "@return No return value." )
  733. {
  734. // Stop Sequence.
  735. object->stop(reset);
  736. }
  737. DefineEngineMethod( VController, getTimeScale, F32, (), , "( void ) - Get the playback speed. A value > 0.0 will enable the Controller to play forwards, while a value < 0.0 will play backwards.\n"
  738. "@return Playback Speed." )
  739. {
  740. // Get Time Scale.
  741. return object->getTimeScale();
  742. }
  743. DefineEngineMethod( VController, setTimeScale, void, (float timeScale), (1), "( float pTimeScale ) - Set the playback speed. A value > 0.0 will enable the Controller to play forwards, while a value < 0.0 will play backwards. If |pTimeScale| > 1.0, then playback will be faster than normal, while |pTimeScale| < 1.0 will be slower.\n"
  744. "@param pTimeScale Playback speed.\n"
  745. "@return No return value." )
  746. {
  747. // Set Time Scale.
  748. object->setTimeScale(timeScale);
  749. }
  750. DefineEngineMethod( VController, isDataField, bool, (String fieldName), (""), "( string pFieldName ) - Is the field a member of the Data Table?\n"
  751. "@param pFieldName The name of the dynamic field you wish to check.\n"
  752. "@return Returns true if the field is a member of the Data Table." )
  753. {
  754. if (fieldName.isEmpty())
  755. {
  756. return false;
  757. }
  758. // Is Field.
  759. return object->getDataTable().getItem(fieldName);
  760. }
  761. DefineEngineMethod( VController, getDataFieldCount, S32, (), , "( void ) - Get the number of data elements in the Data Table.\n"
  762. "@return Returns the size of the Data Table." )
  763. {
  764. // Return Count.
  765. return object->getDataTable().getCount();
  766. }
  767. DefineEngineMethod( VController, getDataFieldName, const char *, (S32 index), (0), "( int pIndex ) - Get the name of the field given by the passed index.\n"
  768. "@param pIndex The index of the data field you wish to check.\n"
  769. "@return Returns the name of the field corresponding to the given index." )
  770. {
  771. VDataTable::sDataItem data;
  772. if ( !object->getDataTable().getItem(index, &data ) || data.Type == VDataTable::k_TypeInvalid )
  773. {
  774. // Invalid Field.
  775. return "";
  776. }
  777. // Return Field Name.
  778. return data.FieldName;
  779. }
  780. DefineEngineMethod( VController, getDataFieldValue, const char *, (String fieldName), (""), "( string pFieldName ) - Get the evaluated data from the data field.\n"
  781. "@param pFieldName The name of the field you wish to evaluate.\n"
  782. "@return Returns the evaluated data from the field." )
  783. {
  784. String fieldValue;
  785. if ( object->getDataValue(fieldName, fieldValue ) )
  786. {
  787. // Create Buffer.
  788. char *buffer = Con::getReturnBuffer( 256 );
  789. dStrcpy( buffer, fieldValue.c_str(), 256 );
  790. // Return Value.
  791. return buffer;
  792. }
  793. // Return NULL.
  794. return "0";
  795. }
  796. DefineEngineMethod( VController, getDataFieldType, const char *, (String fieldName), (""), "( string pFieldName ) - Get the type of data for the given field.\n"
  797. "@param pFieldName The name of the field you wish to check.\n"
  798. "@return Returns the data type." )
  799. {
  800. VDataTable::sDataItem data;
  801. if ( !object->getDataTable().getItem(fieldName, &data ) || data.Type == VDataTable::k_TypeInvalid )
  802. {
  803. // Invalid Field.
  804. return "";
  805. }
  806. // Return Field Type.
  807. return VDataTable::getDataTypeDescription( data.Type );
  808. }
  809. #ifdef VT_EDITOR
  810. //-----------------------------------------------------------------------------
  811. //
  812. // Debug Methods.
  813. //
  814. //-----------------------------------------------------------------------------
  815. DefineEngineMethod( VController, writeFile, bool, (String fileName), (""), "( string pFileName ) - Save to a given filename.\n"
  816. "@param pFileName The target file to write to.\n"
  817. "@return Returns true if the write was successful." )
  818. {
  819. // Write Target File.
  820. return VPersistence::writeFile(fileName.c_str(), object );
  821. }
  822. DefineEngineMethod( VController, readTemplate, bool, (String fileName), (""), "( string pFileName ) - Load data from given filename.\n"
  823. "@param pFileName The target file to read from.\n"
  824. "@return Returns true if the read was successful." )
  825. {
  826. // Read Target File.
  827. return VPersistence::readFile(fileName.c_str(), object );
  828. }
  829. DefineEngineMethod( VController, getCount, S32, (),, "( void ) - Get the number of child objects.\n"
  830. "@return Returns the number of child objects." )
  831. {
  832. // Size.
  833. return object->size();
  834. }
  835. DefineEngineMethod( VController, getObject, S32, (S32 index), (0), "( int pIndex ) - Get the object corresponding to the given index.\n"
  836. "@param pIndex The index of the object you wish to retrieve.\n"
  837. "@return Returns the SimObjectID for the object." )
  838. {
  839. // Fetch Object.
  840. VObject *objectRef = ( VObject* )object->at(index);
  841. // Return Group ID.
  842. return ( objectRef ) ? objectRef->getId() : 0;
  843. }
  844. DefineEngineMethod( VController, addObject, void, (SimObject* simObj), (nullAsType<SimObject*>()), "( SimObject pObject ) - Add a child object to this node.\n"
  845. "@param pObject The SimObjectID of the object to be added to this node.\n"
  846. "@return No return value." )
  847. {
  848. if (simObj == nullptr)
  849. return;
  850. VObject *child = dynamic_cast<VObject*>(simObj);
  851. if ( child )
  852. {
  853. // Add Child.
  854. child->addTo( object );
  855. }
  856. }
  857. DefineEngineMethod( VController, removeObject, void, (SimObject* simObj), (nullAsType<SimObject*>()), "( SimObject pObject ) - Remove the target object from this node.\n"
  858. "@param pObject The SimObjectID of the object to be removed from this node.\n"
  859. "@return No return value." )
  860. {
  861. if (simObj == nullptr)
  862. return;
  863. VObject *child = dynamic_cast<VObject*>(simObj);
  864. if ( child && child->getParent() == object )
  865. {
  866. child->remove();
  867. }
  868. }
  869. DefineEngineMethod( VController, sortGroups, void, (),, "( void ) - Sort Groups by their Labels.\n"
  870. "@return No return value." )
  871. {
  872. // Ensure that the Director Group is the First Group.
  873. VDirectorGroup *directorGroup = object->getDirectorGroup();
  874. if ( directorGroup && directorGroup != object->mChildNode )
  875. {
  876. // Detach.
  877. directorGroup->remove();
  878. // Add to the Front of the Controller.
  879. directorGroup->addToFront( object );
  880. }
  881. const S32 count = object->size();
  882. for ( S32 j = 0; j < count; j++ )
  883. {
  884. ITreeNode *node = object->mChildNode;
  885. if ( dynamic_cast<VDirectorGroup*>( node ) != NULL )
  886. {
  887. // Skip Director Group.
  888. node = node->mSiblingNextNode;
  889. }
  890. for ( ; node != NULL; node = node->mSiblingNextNode )
  891. {
  892. VGroup *groupA = ( VGroup* )node;
  893. VGroup *groupB = ( VGroup* )node->mSiblingNextNode;
  894. if ( !groupB )
  895. {
  896. // No Node.
  897. break;
  898. }
  899. // Swap?
  900. if ( groupA->getLabel().compare(groupB->getLabel()) > 0 )
  901. {
  902. // Get Outer Siblings.
  903. ITreeNode *prevNode = groupA->mSiblingPrevNode;
  904. ITreeNode *nextNode = groupB->mSiblingNextNode;
  905. if ( groupA->mParentNode && groupA->mParentNode->mChildNode == groupA )
  906. {
  907. // New Child Node.
  908. groupA->mParentNode->mChildNode = groupB;
  909. }
  910. //
  911. // Move A.
  912. groupA->mSiblingPrevNode = groupB;
  913. groupA->mSiblingNextNode = nextNode;
  914. if ( nextNode )
  915. {
  916. // Update Outer Sibling.
  917. nextNode->mSiblingPrevNode = groupA;
  918. }
  919. //
  920. // Move B.
  921. groupB->mSiblingPrevNode = prevNode;
  922. groupB->mSiblingNextNode = groupA;
  923. if ( prevNode )
  924. {
  925. // Update Outer Sibling.
  926. prevNode->mSiblingNextNode = groupB;
  927. }
  928. }
  929. }
  930. }
  931. }
  932. DefineEngineMethod( VController, sortTracks, void, (),, "( void ) - Sort Tracks by their Labels.\n"
  933. "@return No return value." )
  934. {
  935. for ( ITreeNode *group = object->mChildNode; group != NULL; group = group->mSiblingNextNode )
  936. {
  937. const S32 count = ( ( VGroup* )group )->size();
  938. for ( S32 j = 0; j < count; j++ )
  939. {
  940. for ( ITreeNode *node = group->mChildNode; node != NULL; node = node->mSiblingNextNode )
  941. {
  942. VTrack *trackA = ( VTrack* )node;
  943. VTrack *trackB = ( VTrack* )node->mSiblingNextNode;
  944. if ( !trackB )
  945. {
  946. // No Node.
  947. break;
  948. }
  949. // Swap?
  950. if ( trackA->getLabel().compare(trackB->getLabel()) > 0 )
  951. {
  952. // Get Outer Siblings.
  953. ITreeNode *prevNode = trackA->mSiblingPrevNode;
  954. ITreeNode *nextNode = trackB->mSiblingNextNode;
  955. if ( trackA->mParentNode && trackA->mParentNode->mChildNode == trackA )
  956. {
  957. // New Child Node.
  958. trackA->mParentNode->mChildNode = trackB;
  959. }
  960. //
  961. // Move A.
  962. trackA->mSiblingPrevNode = trackB;
  963. trackA->mSiblingNextNode = nextNode;
  964. if ( nextNode )
  965. {
  966. // Update Outer Sibling.
  967. nextNode->mSiblingPrevNode = trackA;
  968. }
  969. //
  970. // Move B.
  971. trackB->mSiblingPrevNode = prevNode;
  972. trackB->mSiblingNextNode = trackA;
  973. if ( prevNode )
  974. {
  975. // Update Outer Sibling.
  976. prevNode->mSiblingNextNode = trackB;
  977. }
  978. }
  979. }
  980. }
  981. }
  982. }
  983. DefineEngineMethod( VController, addDataField, void, (String fieldType, String fieldName), ("", ""), "( string pFieldType, string pFieldName ) - Add a new data entry to the Data Table.\n"
  984. "@param pFieldType The method of evaluating the field's data.\n"
  985. "@param pFieldName The name of the field to be added to the Data Table.\n"
  986. "@return No return value." )
  987. {
  988. // Insert Data.
  989. object->getDataTable().insert( VDataTable::getDataTypeEnum(fieldType), fieldName);
  990. }
  991. DefineEngineMethod( VController, removeDataField, void, (String fieldName), (""), "( string pFieldName ) - Remove a data entry from the Data Table.\n"
  992. "@param pFieldName The name of the field to be removed from the Data Table.\n"
  993. "@return No return value." )
  994. {
  995. // Clear Data Item.
  996. object->clearData(fieldName);
  997. }
  998. #endif