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