VTreeNode.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471
  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/VTreeNode.h"
  24. #include "console/simObject.h"
  25. #include "platform/platform.h"
  26. //-----------------------------------------------------------------------------
  27. VTreeNode::VTreeNode( void )
  28. {
  29. mParentNode = NULL;
  30. mChildNode = NULL;
  31. mSiblingPrevNode = NULL;
  32. mSiblingNextNode = NULL;
  33. }
  34. VTreeNode::~VTreeNode( void )
  35. {
  36. // Delete Children.
  37. clear();
  38. // Detach.
  39. remove();
  40. }
  41. //-----------------------------------------------------------------------------
  42. //
  43. // Reference Methods.
  44. //
  45. //-----------------------------------------------------------------------------
  46. //-----------------------------------------------------------------------------
  47. //
  48. // VTreeNode::clear();
  49. //
  50. // Delete all child nodes.
  51. //
  52. //-----------------------------------------------------------------------------
  53. void VTreeNode::clear( void )
  54. {
  55. if ( !mChildNode )
  56. {
  57. return;
  58. }
  59. while ( mChildNode )
  60. {
  61. // Fetch Child Node.
  62. ITreeNode *node = mChildNode;
  63. // Clear It.
  64. node->clear();
  65. // Detach It.
  66. node->remove();
  67. // Delete It.
  68. SimObject *object = dynamic_cast<SimObject*>( node );
  69. if ( object )
  70. {
  71. object->deleteObject();
  72. }
  73. else
  74. {
  75. delete node;
  76. }
  77. }
  78. }
  79. //-----------------------------------------------------------------------------
  80. //
  81. // ITreeNode Methods.
  82. //
  83. //-----------------------------------------------------------------------------
  84. //-----------------------------------------------------------------------------
  85. //
  86. // VTreeNode::getRoot();
  87. //
  88. // Returns the root object.
  89. //
  90. //-----------------------------------------------------------------------------
  91. ITreeNode *VTreeNode::getRoot( void )
  92. {
  93. ITreeNode *parent = this;
  94. while ( parent->mParentNode )
  95. {
  96. parent = parent->mParentNode;
  97. }
  98. return parent;
  99. }
  100. //-----------------------------------------------------------------------------
  101. //
  102. // VTreeNode::getParent();
  103. //
  104. // Returns the parent object.
  105. //
  106. //-----------------------------------------------------------------------------
  107. ITreeNode *VTreeNode::getParent( void )
  108. {
  109. return mParentNode;
  110. }
  111. //-----------------------------------------------------------------------------
  112. //
  113. // VTreeNode::getChild();
  114. //
  115. // Returns the first child object.
  116. //
  117. //-----------------------------------------------------------------------------
  118. ITreeNode *VTreeNode::getChild( void )
  119. {
  120. return mChildNode;
  121. }
  122. //-----------------------------------------------------------------------------
  123. //
  124. // VTreeNode::getChild();
  125. //
  126. // Returns the first child object.
  127. //
  128. //-----------------------------------------------------------------------------
  129. ITreeNode *VTreeNode::getLastChild( void )
  130. {
  131. // Any Nodes?
  132. if ( !mChildNode )
  133. {
  134. // Null.
  135. return NULL;
  136. }
  137. // Front Node.
  138. ITreeNode *lastNode = mChildNode;
  139. // Fetch Last Node.
  140. while ( lastNode->mSiblingNextNode )
  141. {
  142. lastNode = lastNode->mSiblingNextNode;
  143. }
  144. // Return.
  145. return lastNode;
  146. }
  147. //-----------------------------------------------------------------------------
  148. //
  149. // VTreeNode::getPrevSibling();
  150. //
  151. // Returns the previous object in the linked list.
  152. //
  153. //-----------------------------------------------------------------------------
  154. ITreeNode *VTreeNode::getPrevSibling( void )
  155. {
  156. return mSiblingPrevNode;
  157. }
  158. //-----------------------------------------------------------------------------
  159. //
  160. // VTreeNode::getNextSibling();
  161. //
  162. // Returns the next object in the linked list.
  163. //
  164. //-----------------------------------------------------------------------------
  165. ITreeNode *VTreeNode::getNextSibling( void )
  166. {
  167. return mSiblingNextNode;
  168. }
  169. //-----------------------------------------------------------------------------
  170. //
  171. // VTreeNode::size();
  172. //
  173. // Returns the number of child objects. Only includes top level.
  174. //
  175. //-----------------------------------------------------------------------------
  176. int VTreeNode::size( void )
  177. {
  178. int size = 0;
  179. ITreeNode *node = mChildNode;
  180. while ( node )
  181. {
  182. size++;
  183. node = node->mSiblingNextNode;
  184. }
  185. return size;
  186. }
  187. //-----------------------------------------------------------------------------
  188. //
  189. // VTreeNode::at( pIndex );
  190. //
  191. // Returns the object at the given index.
  192. //
  193. //-----------------------------------------------------------------------------
  194. ITreeNode *VTreeNode::at( const int pIndex )
  195. {
  196. int index = 0;
  197. ITreeNode *node = mChildNode;
  198. while ( node )
  199. {
  200. if ( index++ == pIndex )
  201. {
  202. return node;
  203. }
  204. node = node->mSiblingNextNode;
  205. }
  206. return NULL;
  207. }
  208. //-----------------------------------------------------------------------------
  209. //
  210. // VTreeNode::getIndex();
  211. //
  212. // Returns the index of the object in relation to the sibling nodes.
  213. //
  214. //-----------------------------------------------------------------------------
  215. int VTreeNode::getIndex( void )
  216. {
  217. if ( !inTree() )
  218. {
  219. // No Index.
  220. return 0;
  221. }
  222. ITreeNode *walk = NULL;
  223. if ( mParentNode )
  224. {
  225. walk = mParentNode->mChildNode;
  226. }
  227. else
  228. {
  229. walk = this;
  230. while ( walk->mSiblingPrevNode )
  231. {
  232. // Walk Up.
  233. walk = walk->mSiblingPrevNode;
  234. }
  235. }
  236. for ( int i = 0; walk; walk = walk->mSiblingNextNode, i++ )
  237. {
  238. if ( walk == this )
  239. {
  240. return i;
  241. }
  242. }
  243. AssertFatal( false, "VTreeNode::getIndex() - Node List Broken?" );
  244. return 0;
  245. }
  246. //-----------------------------------------------------------------------------
  247. //
  248. // VTreeNode::addTo( pNode );
  249. //
  250. // Attach this node to the back of the target node.
  251. //
  252. //-----------------------------------------------------------------------------
  253. void VTreeNode::addTo( ITreeNode *pNode )
  254. {
  255. if ( inTree() )
  256. {
  257. // Already In Tree.
  258. return;
  259. }
  260. // Set Parent.
  261. mParentNode = pNode;
  262. if ( !pNode->mChildNode )
  263. {
  264. // Store Child Node.
  265. pNode->mChildNode = this;
  266. }
  267. else
  268. {
  269. // Front Node.
  270. ITreeNode *headNode = pNode->mChildNode;
  271. // Fetch Head Node.
  272. while ( headNode->mSiblingNextNode )
  273. {
  274. headNode = headNode->mSiblingNextNode;
  275. }
  276. // Reference Next Node.
  277. headNode->mSiblingNextNode = this;
  278. // Reference Previous Node.
  279. mSiblingPrevNode = headNode;
  280. }
  281. // Callback.
  282. onAttach();
  283. }
  284. //-----------------------------------------------------------------------------
  285. //
  286. // VTreeNode::addToFront( pNode );
  287. //
  288. // Attach this node to the front of the target node.
  289. //
  290. //-----------------------------------------------------------------------------
  291. void VTreeNode::addToFront( ITreeNode *pNode )
  292. {
  293. if ( inTree() )
  294. {
  295. // Already In Tree.
  296. return;
  297. }
  298. // Set Parent.
  299. mParentNode = pNode;
  300. if ( !pNode->mChildNode )
  301. {
  302. // Store Child Node.
  303. pNode->mChildNode = this;
  304. }
  305. else
  306. {
  307. // First Node.
  308. ITreeNode *childNode = pNode->mChildNode;
  309. // Reference Previous Node.
  310. childNode->mSiblingPrevNode = this;
  311. // Reference Next Node.
  312. mSiblingNextNode = childNode;
  313. // Store Child Node.
  314. pNode->mChildNode = this;
  315. }
  316. // Callback.
  317. onAttach();
  318. }
  319. //-----------------------------------------------------------------------------
  320. //
  321. // VTreeNode::remove();
  322. //
  323. // Detach this node from the current parent node.
  324. //
  325. //-----------------------------------------------------------------------------
  326. void VTreeNode::remove( void )
  327. {
  328. if ( !inTree() )
  329. {
  330. return;
  331. }
  332. // Callback.
  333. onDetach();
  334. if ( mParentNode && mParentNode->mChildNode == this )
  335. {
  336. // Update Parent Reference.
  337. mParentNode->mChildNode = mSiblingNextNode;
  338. }
  339. if ( mSiblingNextNode )
  340. {
  341. // Update Previous Node.
  342. mSiblingNextNode->mSiblingPrevNode = mSiblingPrevNode;
  343. }
  344. if ( mSiblingPrevNode )
  345. {
  346. // Update Next Node.
  347. mSiblingPrevNode->mSiblingNextNode = mSiblingNextNode;
  348. }
  349. // Remove References.
  350. mParentNode = mSiblingPrevNode = mSiblingNextNode = NULL;
  351. }
  352. //-----------------------------------------------------------------------------
  353. //
  354. // VTreeNode::moveTo( pNode );
  355. //
  356. // Detach this node and attach it to the target node.
  357. //
  358. //-----------------------------------------------------------------------------
  359. void VTreeNode::moveTo( ITreeNode *pNode )
  360. {
  361. if ( inTree() )
  362. {
  363. // Remove from Tree.
  364. remove();
  365. }
  366. // Add to tree.
  367. addTo( pNode );
  368. }
  369. //-----------------------------------------------------------------------------
  370. //
  371. // VTreeNode::onAttach();
  372. //
  373. // This method will be called when this node, or a parent node, is attached to
  374. // a node.
  375. //
  376. //-----------------------------------------------------------------------------
  377. void VTreeNode::onAttach( void )
  378. {
  379. // Notify Children.
  380. for ( ITreeNode *node = mChildNode; node != NULL; node = node->mSiblingNextNode )
  381. {
  382. node->onAttach();
  383. }
  384. }
  385. //-----------------------------------------------------------------------------
  386. //
  387. // VTreeNode::onDetach();
  388. //
  389. // This method will be called when this node, or a parent node, is detached.
  390. //
  391. //-----------------------------------------------------------------------------
  392. void VTreeNode::onDetach( void )
  393. {
  394. // Notify Children.
  395. for ( ITreeNode *node = mChildNode; node != NULL; node = node->mSiblingNextNode )
  396. {
  397. node->onDetach();
  398. }
  399. }
  400. //-----------------------------------------------------------------------------
  401. //
  402. // VTreeNode::inTree();
  403. //
  404. // Returns true if the node is the a member of a node tree.
  405. //
  406. //-----------------------------------------------------------------------------
  407. bool VTreeNode::inTree( void )
  408. {
  409. return !( mParentNode == NULL &&
  410. mSiblingPrevNode == NULL &&
  411. mSiblingNextNode == NULL );
  412. }