VObject.cpp
Engine/source/Verve/Core/VObject.cpp
Public Functions
Detailed Description
Public Functions
IMPLEMENT_CONOBJECT(VObject )
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/VObject.h" 25#include "Verve/Core/VController.h" 26#include "console/consoleTypes.h" 27 28//----------------------------------------------------------------------------- 29IMPLEMENT_CONOBJECT( VObject ); 30//----------------------------------------------------------------------------- 31 32VObject::VObject( void ) : 33 mController( NULL ), 34 mLabel( String::EmptyString ), 35 mEnabled( true ) 36{ 37 // Void. 38}; 39 40VObject::~VObject( void ) 41{ 42 // Remove. 43 remove(); 44} 45 46void VObject::initPersistFields( void ) 47{ 48 // Don't Use Parent Fields. 49 // Parent::initPersistFields(); 50 51 addProtectedField( "Enabled", TypeBool, Offset( mEnabled, VObject ), &setEnabled, &defaultProtectedGetFn, "Enable or Disable the object from playback." ); 52 addProtectedField( "Label", TypeRealString, Offset( mLabel, VObject ), &setLabel, &defaultProtectedGetFn, "The label this object is referenced by." ); 53} 54 55//----------------------------------------------------------------------------- 56// 57// Reference Methods. 58// 59//----------------------------------------------------------------------------- 60 61//----------------------------------------------------------------------------- 62// 63// VObject::getObject( pLabel ); 64// 65// Returns the object with the given label. If no object belongs to this object 66// with that label, then a NULL value is returned. 67// 68//----------------------------------------------------------------------------- 69VObject *VObject::getObject( const String &pLabel ) 70{ 71 VObject *node = ( VObject* )mChildNode; 72 while ( node ) 73 { 74 // Compare Names. 75 if ( node->getLabel().equal( pLabel, String::NoCase ) ) 76 { 77 // Valid. 78 return node; 79 } 80 81 // Next Sibling. 82 node = ( VObject* )node->mSiblingNextNode; 83 } 84 85 // Invalid. 86 return NULL; 87} 88 89//----------------------------------------------------------------------------- 90// 91// Property Methods. 92// 93//----------------------------------------------------------------------------- 94 95//----------------------------------------------------------------------------- 96// 97// VObject::isEnabled(); 98// 99// Returns whether this object is enabled. 100// 101//----------------------------------------------------------------------------- 102bool VObject::isEnabled( void ) 103{ 104 VObject *parent = dynamic_cast<VObject*>( getParent() ); 105 if ( parent && !parent->isEnabled() ) 106 { 107 return false; 108 } 109 110 return mEnabled; 111} 112 113//----------------------------------------------------------------------------- 114// 115// VObject::isControllerPlaying(); 116// 117// Returns whether the root controller is currently playing. 118// 119//----------------------------------------------------------------------------- 120bool VObject::isControllerPlaying( void ) 121{ 122 if ( getController() ) 123 { 124 return getController()->isPlaying(); 125 } 126 127 return false; 128} 129 130//----------------------------------------------------------------------------- 131// 132// VObject::isControllerPaused(); 133// 134// Returns whether the root controller is currently paused. 135// 136//----------------------------------------------------------------------------- 137bool VObject::isControllerPaused( void ) 138{ 139 if ( getController() ) 140 { 141 return getController()->isPaused(); 142 } 143 144 return false; 145} 146 147//----------------------------------------------------------------------------- 148// 149// VObject::isControllerStopped(); 150// 151// Returns whether the root controller is currently stopped. 152// 153//----------------------------------------------------------------------------- 154bool VObject::isControllerStopped( void ) 155{ 156 if ( getController() ) 157 { 158 return getController()->isStopped(); 159 } 160 161 return true; 162} 163 164//----------------------------------------------------------------------------- 165// 166// VObject::isControllerPlayingForward(); 167// 168// Returns whether the root controller is currently playing forward. 169// 170//----------------------------------------------------------------------------- 171bool VObject::isControllerPlayingForward( void ) 172{ 173 if ( getController() ) 174 { 175 return getController()->isPlayingForward(); 176 } 177 178 return true; 179} 180 181//----------------------------------------------------------------------------- 182// 183// VObject::isControllerLooping(); 184// 185// Returns whether the root controller is looping the sequence. 186// 187//----------------------------------------------------------------------------- 188bool VObject::isControllerLooping( void ) 189{ 190 if ( getController() ) 191 { 192 return getController()->isLooping(); 193 } 194 195 return true; 196} 197 198//----------------------------------------------------------------------------- 199// 200// VObject::getControllerTime(); 201// 202// Returns the current time of the root controller. 203// 204//----------------------------------------------------------------------------- 205S32 VObject::getControllerTime( void ) 206{ 207 if ( getController() ) 208 { 209 return getController()->getTime(); 210 } 211 212 return 0; 213} 214 215//----------------------------------------------------------------------------- 216// 217// VObject::getControllerTimeScale(); 218// 219// Returns the current timescale of the root controller. 220// 221//----------------------------------------------------------------------------- 222F32 VObject::getControllerTimeScale( void ) 223{ 224 if ( getController() ) 225 { 226 return getController()->getTimeScale(); 227 } 228 229 return 1.f; 230} 231 232//----------------------------------------------------------------------------- 233// 234// VObject::getControllerDuration(); 235// 236// Returns the duration of the root controller. 237// 238//----------------------------------------------------------------------------- 239S32 VObject::getControllerDuration( void ) 240{ 241 if ( getController() ) 242 { 243 return getController()->getDuration(); 244 } 245 246 return 0; 247} 248 249//----------------------------------------------------------------------------- 250// 251// VObject::setLabel( pLabel ); 252// 253// Set the label property. 254// 255// If the project was built using the VT_EDITOR preprocessor argument, then the 256// label will not be changed if the target name is already used in the parent 257// object. 258// 259//----------------------------------------------------------------------------- 260void VObject::setLabel( const String &pLabel ) 261{ 262#ifdef VT_EDITOR 263 if ( mParentNode ) 264 { 265 // Empty Label? 266 if ( mLabel.isEmpty() ) 267 { 268 // Set Uniqu Label. 269 setLabelUnique( pLabel ); 270 return; 271 } 272 273 for ( VObject *walk = ( VObject* )mChildNode; walk != NULL; walk = ( VObject* )walk->mSiblingNextNode ) 274 { 275 if ( walk != this ) 276 { 277 if ( pLabel == walk->getLabel() ) 278 { 279 // Exit. 280 return; 281 } 282 } 283 } 284 } 285#endif 286 287 // Set Label. 288 mLabel = pLabel; 289} 290 291//----------------------------------------------------------------------------- 292// 293// VObject::setLabelUnique( pLabel ); 294// 295// If the label that has been passed is already in use, then a new label will 296// be generated by appending an index to the label. For example: MyLabel 297// becomes MyLabel0 ... MyLabelN 298// 299//----------------------------------------------------------------------------- 300void VObject::setLabelUnique( const String &pLabel ) 301{ 302 if ( mParentNode && pLabel.isNotEmpty() ) 303 { 304 for ( VObject *walk = ( VObject* )mChildNode; walk != NULL; walk = ( VObject* )walk->mSiblingNextNode ) 305 { 306 if ( walk != this ) 307 { 308 if ( pLabel == walk->getLabel() ) 309 { 310 // Strip Trailing Number. 311 S32 i = -1; 312 String labelBase( String::GetTrailingNumber( pLabel, i ) ); 313 i++; 314 315 // Construct New Name. 316 String labelBuffer = String::ToString( "%s%d", labelBase.c_str(), i ); 317 318 // Set Name. 319 setLabelUnique( labelBuffer ); 320 321 // Exit. 322 return; 323 } 324 } 325 } 326 } 327 328 // Set Name. 329 mLabel = pLabel; 330} 331 332//----------------------------------------------------------------------------- 333// 334// Callback Methods. 335// 336//----------------------------------------------------------------------------- 337 338//----------------------------------------------------------------------------- 339// 340// VObject::onAttach(); 341// 342// Callback made when this object is attached to another node. 343// 344//----------------------------------------------------------------------------- 345void VObject::onAttach( void ) 346{ 347 VTreeNode::onAttach(); 348 349 // Store Controller. 350 mController = dynamic_cast<VController*>( getRoot() ); 351 352#ifdef VT_EDITOR 353 if ( isProperlyAdded() ) 354 { 355 Con::executef( this, "onAttach" ); 356 } 357#endif 358} 359 360//----------------------------------------------------------------------------- 361// 362// VObject::onDetach(); 363// 364// Callback made when this object is detached from a parent node. 365// 366//----------------------------------------------------------------------------- 367void VObject::onDetach( void ) 368{ 369 VTreeNode::onDetach(); 370 371 // Clear Controller. 372 mController = NULL; 373 374#ifdef VT_EDITOR 375 if ( isProperlyAdded() ) 376 { 377 Con::executef( this, "onDetach" ); 378 } 379#endif 380} 381 382#ifdef VT_EDITOR 383//----------------------------------------------------------------------------- 384// 385// Debug Methods. 386// 387//----------------------------------------------------------------------------- 388 389DefineEngineMethod( VObject, writeFile, bool, (String fileName), (""), "( string pFileName ) - Save to a given filename.\n" 390 "@param pFileName The target file to write to.\n" 391 "@return Returns true if the write was successful." ) 392{ 393 // Write Target File. 394 return VPersistence::writeFile(fileName.c_str(), object ); 395} 396 397DefineEngineMethod( VObject, readFile, bool, (String fileName), (""), "( string pFileName ) - Clears the object and loads the new data from the given filename.\n" 398 "@param pFileName The target file to read from.\n" 399 "@return Returns true if the read was successful." ) 400{ 401 // Read Target File. 402 return VPersistence::readFile(fileName.c_str(), object ); 403} 404 405DefineEngineMethod( VObject, getRoot, S32, (),, "( void ) - Get the root object.\n" 406 "@return Returns the SimObjectId for the root object." ) 407{ 408 // Fetch Object. 409 VObject *objectRef = ( VObject* )object->getRoot(); 410 411 // Return Object ID. 412 return ( objectRef ) ? objectRef->getId() : 0; 413} 414 415DefineEngineMethod( VObject, getParent, S32, (),, "( void ) - Get the parent object.\n" 416 "@return Returns the SimObjectId for the parent object." ) 417{ 418 // Fetch Object. 419 VObject *objectRef = ( VObject* )object->mParentNode; 420 421 // Return Object ID. 422 return ( objectRef ) ? objectRef->getId() : 0; 423} 424 425DefineEngineMethod( VObject, getIndex, S32, (),, "( void ) - Get the index of this object relative to its siblings.\n" 426 "@return Returns the index of this object." ) 427{ 428 return object->getIndex(); 429} 430 431DefineEngineMethod( VObject, getCount, S32, (),, "( void ) - Get the number of child objects.\n" 432 "@return Returns the number of child objects." ) 433{ 434 return object->size(); 435} 436 437DefineEngineMethod( VObject, getObject, S32, (S32 index), (0), "( int pIndex ) - Get the object corresponding to the given index.\n" 438 "@param pIndex The index of the object you wish to retrieve.\n" 439 "@return Returns the SimObjectID for the object." ) 440{ 441 // Fetch Object. 442 VObject *objectRef = ( VObject* )object->at(index); 443 444 // Return Object ID. 445 return ( objectRef ) ? objectRef->getId() : 0; 446} 447 448DefineEngineMethod( VObject, clear, void, (),, "( void ) - Detaches and deletes all of the child objects.\n" 449 "@return No return value." ) 450{ 451 // Clear Sequence Lists. 452 object->clear(); 453} 454 455DefineEngineMethod( VObject, addObject, void, (SimObject* simObj), (nullAsType<SimObject*>()), "( SimObject pObject ) - Add a child object to this node.\n" 456 "@param pObject The SimObjectID of the object to be added to this node.\n" 457 "@return No return value." ) 458{ 459 if (simObj == nullptr) 460 return; 461 462 VObject *child = dynamic_cast<VObject*>(simObj); 463 if ( child ) 464 { 465 child->addTo( object ); 466 } 467} 468 469DefineEngineMethod( VObject, removeObject, void, (SimObject* simObj), (nullAsType<SimObject*>()), "( SimObject pObject ) - Remove the target object from this node.\n" 470 "@param pObject The SimObjectID of the object to be removed from this node.\n" 471 "@return No return value." ) 472{ 473 if (simObj == nullptr) 474 return; 475 476 VObject *child = dynamic_cast<VObject*>(simObj); 477 if ( child && child->getParent() == object ) 478 { 479 child->remove(); 480 } 481} 482 483DefineEngineMethod( VObject, setLabelUnique, void, (String label), (""), "( string pLabel ) - Force this label to be unique.\n" 484 "@param pLabel The name you wish to reference this object by.\n" 485 "@return No return value." ) 486{ 487 // Set Label. 488 object->setLabelUnique(label); 489} 490#endif 491