VObject.cpp 15 KB

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