Hierarchy.h 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  1. /*
  2. ===========================================================================
  3. Doom 3 GPL Source Code
  4. Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
  5. This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
  6. Doom 3 Source Code is free software: you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation, either version 3 of the License, or
  9. (at your option) any later version.
  10. Doom 3 Source Code is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
  16. In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
  17. If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
  18. ===========================================================================
  19. */
  20. #ifndef __HIERARCHY_H__
  21. #define __HIERARCHY_H__
  22. /*
  23. ==============================================================================
  24. idHierarchy
  25. ==============================================================================
  26. */
  27. template< class type >
  28. class idHierarchy {
  29. public:
  30. idHierarchy();
  31. ~idHierarchy();
  32. void SetOwner( type *object );
  33. type * Owner( void ) const;
  34. void ParentTo( idHierarchy &node );
  35. void MakeSiblingAfter( idHierarchy &node );
  36. bool ParentedBy( const idHierarchy &node ) const;
  37. void RemoveFromParent( void );
  38. void RemoveFromHierarchy( void );
  39. type * GetParent( void ) const; // parent of this node
  40. type * GetChild( void ) const; // first child of this node
  41. type * GetSibling( void ) const; // next node with the same parent
  42. type * GetPriorSibling( void ) const; // previous node with the same parent
  43. type * GetNext( void ) const; // goes through all nodes of the hierarchy
  44. type * GetNextLeaf( void ) const; // goes through all leaf nodes of the hierarchy
  45. private:
  46. idHierarchy * parent;
  47. idHierarchy * sibling;
  48. idHierarchy * child;
  49. type * owner;
  50. idHierarchy<type> *GetPriorSiblingNode( void ) const; // previous node with the same parent
  51. };
  52. /*
  53. ================
  54. idHierarchy<type>::idHierarchy
  55. ================
  56. */
  57. template< class type >
  58. idHierarchy<type>::idHierarchy() {
  59. owner = NULL;
  60. parent = NULL;
  61. sibling = NULL;
  62. child = NULL;
  63. }
  64. /*
  65. ================
  66. idHierarchy<type>::~idHierarchy
  67. ================
  68. */
  69. template< class type >
  70. idHierarchy<type>::~idHierarchy() {
  71. RemoveFromHierarchy();
  72. }
  73. /*
  74. ================
  75. idHierarchy<type>::Owner
  76. Gets the object that is associated with this node.
  77. ================
  78. */
  79. template< class type >
  80. type *idHierarchy<type>::Owner( void ) const {
  81. return owner;
  82. }
  83. /*
  84. ================
  85. idHierarchy<type>::SetOwner
  86. Sets the object that this node is associated with.
  87. ================
  88. */
  89. template< class type >
  90. void idHierarchy<type>::SetOwner( type *object ) {
  91. owner = object;
  92. }
  93. /*
  94. ================
  95. idHierarchy<type>::ParentedBy
  96. ================
  97. */
  98. template< class type >
  99. bool idHierarchy<type>::ParentedBy( const idHierarchy &node ) const {
  100. if ( parent == &node ) {
  101. return true;
  102. } else if ( parent ) {
  103. return parent->ParentedBy( node );
  104. }
  105. return false;
  106. }
  107. /*
  108. ================
  109. idHierarchy<type>::ParentTo
  110. Makes the given node the parent.
  111. ================
  112. */
  113. template< class type >
  114. void idHierarchy<type>::ParentTo( idHierarchy &node ) {
  115. RemoveFromParent();
  116. parent = &node;
  117. sibling = node.child;
  118. node.child = this;
  119. }
  120. /*
  121. ================
  122. idHierarchy<type>::MakeSiblingAfter
  123. Makes the given node a sibling after the passed in node.
  124. ================
  125. */
  126. template< class type >
  127. void idHierarchy<type>::MakeSiblingAfter( idHierarchy &node ) {
  128. RemoveFromParent();
  129. parent = node.parent;
  130. sibling = node.sibling;
  131. node.sibling = this;
  132. }
  133. /*
  134. ================
  135. idHierarchy<type>::RemoveFromParent
  136. ================
  137. */
  138. template< class type >
  139. void idHierarchy<type>::RemoveFromParent( void ) {
  140. idHierarchy<type> *prev;
  141. if ( parent ) {
  142. prev = GetPriorSiblingNode();
  143. if ( prev ) {
  144. prev->sibling = sibling;
  145. } else {
  146. parent->child = sibling;
  147. }
  148. }
  149. parent = NULL;
  150. sibling = NULL;
  151. }
  152. /*
  153. ================
  154. idHierarchy<type>::RemoveFromHierarchy
  155. Removes the node from the hierarchy and adds it's children to the parent.
  156. ================
  157. */
  158. template< class type >
  159. void idHierarchy<type>::RemoveFromHierarchy( void ) {
  160. idHierarchy<type> *parentNode;
  161. idHierarchy<type> *node;
  162. parentNode = parent;
  163. RemoveFromParent();
  164. if ( parentNode ) {
  165. while( child ) {
  166. node = child;
  167. node->RemoveFromParent();
  168. node->ParentTo( *parentNode );
  169. }
  170. } else {
  171. while( child ) {
  172. child->RemoveFromParent();
  173. }
  174. }
  175. }
  176. /*
  177. ================
  178. idHierarchy<type>::GetParent
  179. ================
  180. */
  181. template< class type >
  182. type *idHierarchy<type>::GetParent( void ) const {
  183. if ( parent ) {
  184. return parent->owner;
  185. }
  186. return NULL;
  187. }
  188. /*
  189. ================
  190. idHierarchy<type>::GetChild
  191. ================
  192. */
  193. template< class type >
  194. type *idHierarchy<type>::GetChild( void ) const {
  195. if ( child ) {
  196. return child->owner;
  197. }
  198. return NULL;
  199. }
  200. /*
  201. ================
  202. idHierarchy<type>::GetSibling
  203. ================
  204. */
  205. template< class type >
  206. type *idHierarchy<type>::GetSibling( void ) const {
  207. if ( sibling ) {
  208. return sibling->owner;
  209. }
  210. return NULL;
  211. }
  212. /*
  213. ================
  214. idHierarchy<type>::GetPriorSiblingNode
  215. Returns NULL if no parent, or if it is the first child.
  216. ================
  217. */
  218. template< class type >
  219. idHierarchy<type> *idHierarchy<type>::GetPriorSiblingNode( void ) const {
  220. if ( !parent || ( parent->child == this ) ) {
  221. return NULL;
  222. }
  223. idHierarchy<type> *prev;
  224. idHierarchy<type> *node;
  225. node = parent->child;
  226. prev = NULL;
  227. while( ( node != this ) && ( node != NULL ) ) {
  228. prev = node;
  229. node = node->sibling;
  230. }
  231. if ( node != this ) {
  232. idLib::Error( "idHierarchy::GetPriorSibling: could not find node in parent's list of children" );
  233. }
  234. return prev;
  235. }
  236. /*
  237. ================
  238. idHierarchy<type>::GetPriorSibling
  239. Returns NULL if no parent, or if it is the first child.
  240. ================
  241. */
  242. template< class type >
  243. type *idHierarchy<type>::GetPriorSibling( void ) const {
  244. idHierarchy<type> *prior;
  245. prior = GetPriorSiblingNode();
  246. if ( prior ) {
  247. return prior->owner;
  248. }
  249. return NULL;
  250. }
  251. /*
  252. ================
  253. idHierarchy<type>::GetNext
  254. Goes through all nodes of the hierarchy.
  255. ================
  256. */
  257. template< class type >
  258. type *idHierarchy<type>::GetNext( void ) const {
  259. const idHierarchy<type> *node;
  260. if ( child ) {
  261. return child->owner;
  262. } else {
  263. node = this;
  264. while( node && node->sibling == NULL ) {
  265. node = node->parent;
  266. }
  267. if ( node ) {
  268. return node->sibling->owner;
  269. } else {
  270. return NULL;
  271. }
  272. }
  273. }
  274. /*
  275. ================
  276. idHierarchy<type>::GetNextLeaf
  277. Goes through all leaf nodes of the hierarchy.
  278. ================
  279. */
  280. template< class type >
  281. type *idHierarchy<type>::GetNextLeaf( void ) const {
  282. const idHierarchy<type> *node;
  283. if ( child ) {
  284. node = child;
  285. while ( node->child ) {
  286. node = node->child;
  287. }
  288. return node->owner;
  289. } else {
  290. node = this;
  291. while( node && node->sibling == NULL ) {
  292. node = node->parent;
  293. }
  294. if ( node ) {
  295. node = node->sibling;
  296. while ( node->child ) {
  297. node = node->child;
  298. }
  299. return node->owner;
  300. } else {
  301. return NULL;
  302. }
  303. }
  304. }
  305. #endif /* !__HIERARCHY_H__ */