arcChain.I 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531
  1. // Filename: arcChain.I
  2. // Created by: drose (05Jan01)
  3. //
  4. ////////////////////////////////////////////////////////////////////
  5. //
  6. // PANDA 3D SOFTWARE
  7. // Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
  8. //
  9. // All use of this software is subject to the terms of the Panda 3d
  10. // Software license. You should have received a copy of this license
  11. // along with this source code; you will also find a current copy of
  12. // the license at http://www.panda3d.org/license.txt .
  13. //
  14. // To contact the maintainers of this program write to
  15. // [email protected] .
  16. //
  17. ////////////////////////////////////////////////////////////////////
  18. ////////////////////////////////////////////////////////////////////
  19. // Function: ArcChain::ArcComponent::Constructor
  20. // Access: Public
  21. // Description: Constructs an ArcComponent that references a node.
  22. // This kind of ArcComponent may *only* be at the head
  23. // of the chain; i.e. _next must always be NULL.
  24. ////////////////////////////////////////////////////////////////////
  25. INLINE_GRAPH ArcChain::ArcComponent::
  26. ArcComponent(Node *node) :
  27. _next(NULL)
  28. {
  29. MemoryUsage::update_type(this, get_class_type());
  30. _p._node = node;
  31. nassertv(node != (Node *)NULL);
  32. _p._node->ref();
  33. }
  34. ////////////////////////////////////////////////////////////////////
  35. // Function: ArcChain::ArcComponent::Constructor
  36. // Access: Public
  37. // Description: Constructs an ArcComponent that references an arc.
  38. // This kind of ArcComponent must be in the middle or
  39. // tail of the chain; it may not be at the head of the
  40. // chain; i.e. _next must never be NULL.
  41. ////////////////////////////////////////////////////////////////////
  42. INLINE_GRAPH ArcChain::ArcComponent::
  43. ArcComponent(NodeRelation *arc, ArcComponent *next) :
  44. _next(next)
  45. {
  46. MemoryUsage::update_type(this, get_class_type());
  47. _p._arc = arc;
  48. nassertv(_next != (ArcComponent *)NULL);
  49. nassertv(arc != (NodeRelation *)NULL);
  50. _p._arc->ref();
  51. _p._arc->ref_parent();
  52. }
  53. ////////////////////////////////////////////////////////////////////
  54. // Function: ArcChain::ArcComponent::Copy Constructor
  55. // Access: Public
  56. // Description:
  57. ////////////////////////////////////////////////////////////////////
  58. INLINE_GRAPH ArcChain::ArcComponent::
  59. ArcComponent(const ArcComponent &copy) :
  60. _next(copy._next)
  61. {
  62. MemoryUsage::update_type(this, get_class_type());
  63. if (has_arc()) {
  64. _p._arc = copy._p._arc;
  65. nassertv(_p._arc != (NodeRelation *)NULL);
  66. _p._arc->ref();
  67. _p._arc->ref_parent();
  68. } else {
  69. _p._node = copy._p._node;
  70. nassertv(_p._node != (Node *)NULL);
  71. _p._node->ref();
  72. }
  73. }
  74. ////////////////////////////////////////////////////////////////////
  75. // Function: ArcChain::ArcComponent::Destructor
  76. // Access: Public
  77. // Description:
  78. ////////////////////////////////////////////////////////////////////
  79. INLINE_GRAPH ArcChain::ArcComponent::
  80. ~ArcComponent() {
  81. if (has_arc()) {
  82. nassertv(_p._arc != (NodeRelation *)NULL);
  83. _p._arc->unref_parent();
  84. unref_delete(_p._arc);
  85. } else {
  86. nassertv(_p._node != (Node *)NULL);
  87. unref_delete(_p._node);
  88. }
  89. }
  90. ////////////////////////////////////////////////////////////////////
  91. // Function: ArcChain::ArcComponent::has_arc
  92. // Access: Public
  93. // Description: Returns true if this component stores an arc, false
  94. // if it stores a node.
  95. ////////////////////////////////////////////////////////////////////
  96. INLINE_GRAPH bool ArcChain::ArcComponent::
  97. has_arc() const {
  98. return (_next != (ArcComponent *)NULL);
  99. }
  100. ////////////////////////////////////////////////////////////////////
  101. // Function: ArcChain::ArcComponent::get_arc
  102. // Access: Public
  103. // Description: Returns the arc referenced by this component. It is
  104. // an error to call this unless has_arc() has already
  105. // returned true.
  106. ////////////////////////////////////////////////////////////////////
  107. INLINE_GRAPH NodeRelation *ArcChain::ArcComponent::
  108. get_arc() const {
  109. nassertr(has_arc(), (NodeRelation *)NULL);
  110. return _p._arc;
  111. }
  112. ////////////////////////////////////////////////////////////////////
  113. // Function: ArcChain::ArcComponent::get_node
  114. // Access: Public
  115. // Description: Returns the node referenced by this component. If
  116. // this component references a node (i.e. has_arc() is
  117. // false), this will return that node; if the component
  118. // references an arc (has_arc() is true), this will
  119. // return the child node of the arc.
  120. ////////////////////////////////////////////////////////////////////
  121. INLINE_GRAPH Node *ArcChain::ArcComponent::
  122. get_node() const {
  123. if (has_arc()) {
  124. return _p._arc->get_child();
  125. } else {
  126. return _p._node;
  127. }
  128. }
  129. ////////////////////////////////////////////////////////////////////
  130. // Function: ArcChain::ArcComponent::is_top_node
  131. // Access: Public
  132. // Description: Returns true if this component represents the top
  133. // node in the chain. This is the one component at the
  134. // top of the chain that represents a node; the rest of
  135. // the chain represents arcs.
  136. ////////////////////////////////////////////////////////////////////
  137. INLINE_GRAPH bool ArcChain::ArcComponent::
  138. is_top_node() const {
  139. return (_next == (ArcComponent *)NULL);
  140. }
  141. ////////////////////////////////////////////////////////////////////
  142. // Function: ArcChain::ArcComponent::is_top_arc
  143. // Access: Public
  144. // Description: Returns true if this component represents the top arc
  145. // in the chain. This is the component just below the
  146. // top of the chain; the highest component in the chain
  147. // that still represents an arc.
  148. ////////////////////////////////////////////////////////////////////
  149. INLINE_GRAPH bool ArcChain::ArcComponent::
  150. is_top_arc() const {
  151. return (_next != (ArcComponent *)NULL && _next->is_top_node());
  152. }
  153. ////////////////////////////////////////////////////////////////////
  154. // Function: ArcChain::ArcComponent::get_next
  155. // Access: Public
  156. // Description: Returns the next component in the chain.
  157. ////////////////////////////////////////////////////////////////////
  158. INLINE_GRAPH ArcChain::ArcComponent *ArcChain::ArcComponent::
  159. get_next() const {
  160. return _next;
  161. }
  162. ////////////////////////////////////////////////////////////////////
  163. // Function: ArcChain::ArcComponent::set_next
  164. // Access: Public
  165. // Description: Changes the next component in the chain. This breaks
  166. // the chain at this component and relinks it to another
  167. // chain.
  168. ////////////////////////////////////////////////////////////////////
  169. INLINE_GRAPH void ArcChain::ArcComponent::
  170. set_next(ArcComponent *next) {
  171. nassertv(next != (ArcComponent *)NULL);
  172. nassertv(_next != (ArcComponent *)NULL);
  173. _next = next;
  174. }
  175. ////////////////////////////////////////////////////////////////////
  176. // Function: ArcChain::ForwardIterator::Constructor
  177. // Access: Public
  178. // Description: This is an STL-style iterator that can be used to
  179. // traverse the full list of arcs traversed so far by
  180. // the ArcChain. Its primary purpose is as a
  181. // parameter to wrt() so we can compute a correct
  182. // relative wrt to the particular instance we've reached
  183. // so far.
  184. ////////////////////////////////////////////////////////////////////
  185. INLINE_GRAPH ArcChain::ForwardIterator::
  186. ForwardIterator(ArcChain::ArcComponent *comp) : _comp(comp) {
  187. }
  188. ////////////////////////////////////////////////////////////////////
  189. // Function: ArcChain::ForwardIterator::Dereference Operator
  190. // Access: Public
  191. // Description:
  192. ////////////////////////////////////////////////////////////////////
  193. INLINE_GRAPH NodeRelation *ArcChain::ForwardIterator::
  194. operator * () const {
  195. nassertr(_comp != (ArcComponent *)NULL, NULL);
  196. return _comp->get_arc();
  197. }
  198. ////////////////////////////////////////////////////////////////////
  199. // Function: ArcChain::ForwardIterator::Increment Operator
  200. // Access: Public
  201. // Description:
  202. ////////////////////////////////////////////////////////////////////
  203. INLINE_GRAPH void ArcChain::ForwardIterator::
  204. operator ++() {
  205. nassertv(_comp != (ArcComponent *)NULL);
  206. if (_comp->is_top_arc()) {
  207. // We only visit arcs, not nodes. When we reach the end of the
  208. // list of arcs (i.e. the "top" arc), we stop.
  209. _comp = (ArcComponent *)NULL;
  210. } else {
  211. _comp = _comp->get_next();
  212. }
  213. }
  214. ////////////////////////////////////////////////////////////////////
  215. // Function: ArcChain::ForwardIterator::Equality Operator
  216. // Access: Public
  217. // Description:
  218. ////////////////////////////////////////////////////////////////////
  219. INLINE_GRAPH bool ArcChain::ForwardIterator::
  220. operator == (const ArcChain::ForwardIterator &other) const {
  221. return _comp == other._comp;
  222. }
  223. ////////////////////////////////////////////////////////////////////
  224. // Function: ArcChain::ForwardIterator::Inequality Operator
  225. // Access: Public
  226. // Description:
  227. ////////////////////////////////////////////////////////////////////
  228. INLINE_GRAPH bool ArcChain::ForwardIterator::
  229. operator != (const ArcChain::ForwardIterator &other) const {
  230. return _comp != other._comp;
  231. }
  232. ////////////////////////////////////////////////////////////////////
  233. // Function: ArcChain::Default Constructor
  234. // Access: Public
  235. // Description: This constructs an empty ArcChain with no nodes. It
  236. // cannot be extended, since you cannot add arcs without
  237. // first specifying the top node. Use the constructor
  238. // that receives a node if you ever want to do anything
  239. // with this chain.
  240. ////////////////////////////////////////////////////////////////////
  241. INLINE_GRAPH ArcChain::
  242. ArcChain() {
  243. }
  244. ////////////////////////////////////////////////////////////////////
  245. // Function: ArcChain::Constructor
  246. // Access: Public
  247. // Description: This constructs an empty ArcChain with a single node.
  248. // This chain may now be extended by repeatedly calling
  249. // push_back() with each arc below that node in
  250. // sequence.
  251. //
  252. // If the Node pointer is NULL, this quietly creates an
  253. // empty ArcChain.
  254. ////////////////////////////////////////////////////////////////////
  255. INLINE_GRAPH ArcChain::
  256. ArcChain(Node *top_node) {
  257. if (top_node != (Node *)NULL) {
  258. _head = new ArcComponent(top_node);
  259. }
  260. }
  261. ////////////////////////////////////////////////////////////////////
  262. // Function: ArcChain::Copy Constructor
  263. // Access: Public
  264. // Description:
  265. ////////////////////////////////////////////////////////////////////
  266. INLINE_GRAPH ArcChain::
  267. ArcChain(const ArcChain &copy) :
  268. _head(copy._head)
  269. {
  270. }
  271. ////////////////////////////////////////////////////////////////////
  272. // Function: ArcChain::Copy Assignment Operator
  273. // Access: Public
  274. // Description:
  275. ////////////////////////////////////////////////////////////////////
  276. INLINE_GRAPH void ArcChain::
  277. operator = (const ArcChain &copy) {
  278. _head = copy._head;
  279. }
  280. ////////////////////////////////////////////////////////////////////
  281. // Function: ArcChain::is_empty
  282. // Access: Public
  283. // Description: Returns true if the ArcChain contains no nodes and no
  284. // arcs.
  285. ////////////////////////////////////////////////////////////////////
  286. INLINE_GRAPH bool ArcChain::
  287. is_empty() const {
  288. return (_head == (ArcComponent *)NULL);
  289. }
  290. ////////////////////////////////////////////////////////////////////
  291. // Function: ArcChain::is_singleton
  292. // Access: Public
  293. // Description: Returns true if the ArcChain contains exactly one
  294. // node, and no arcs.
  295. ////////////////////////////////////////////////////////////////////
  296. INLINE_GRAPH bool ArcChain::
  297. is_singleton() const {
  298. return (_head != (ArcComponent *)NULL && _head->is_top_node());
  299. }
  300. ////////////////////////////////////////////////////////////////////
  301. // Function: ArcChain::has_arcs
  302. // Access: Public
  303. // Description: Returns true if the ArcChain contains at least one
  304. // arc, and therefore at least two nodes. This is the
  305. // same thing as asking get_num_arcs() > 0, but is
  306. // easier to compute.
  307. ////////////////////////////////////////////////////////////////////
  308. INLINE_GRAPH bool ArcChain::
  309. has_arcs() const {
  310. return (_head != (ArcComponent *)NULL && !_head->is_top_node());
  311. }
  312. ////////////////////////////////////////////////////////////////////
  313. // Function: ArcChain::get_num_arcs
  314. // Access: Public
  315. // Description: Returns the number of arcs in the path.
  316. ////////////////////////////////////////////////////////////////////
  317. INLINE_GRAPH int ArcChain::
  318. get_num_arcs() const {
  319. if (!has_arcs()) {
  320. return 0;
  321. }
  322. return get_num_nodes() - 1;
  323. }
  324. ////////////////////////////////////////////////////////////////////
  325. // Function: ArcChain::node
  326. // Access: Public
  327. // Description: Returns the bottom node of the path, or NULL if the
  328. // path is empty.
  329. ////////////////////////////////////////////////////////////////////
  330. INLINE_GRAPH Node *ArcChain::
  331. node() const {
  332. if (is_empty()) {
  333. return (Node *)NULL;
  334. }
  335. return _head->get_node();
  336. }
  337. ////////////////////////////////////////////////////////////////////
  338. // Function: ArcChain::arc
  339. // Access: Public
  340. // Description: Returns the bottom arc of the path, or NULL if the
  341. // path is empty or is a singleton.
  342. ////////////////////////////////////////////////////////////////////
  343. INLINE_GRAPH NodeRelation *ArcChain::
  344. arc() const {
  345. if (!has_arcs()) {
  346. // A singleton or empty list.
  347. return (NodeRelation *)NULL;
  348. }
  349. return _head->get_arc();
  350. }
  351. ////////////////////////////////////////////////////////////////////
  352. // Function: ArcChain::begin
  353. // Access: Public
  354. // Description: Returns an iterator that can be used to traverse the
  355. // list of arcs.
  356. ////////////////////////////////////////////////////////////////////
  357. INLINE_GRAPH ArcChain::const_iterator ArcChain::
  358. begin() const {
  359. if (empty()) {
  360. return ForwardIterator();
  361. } else {
  362. return ForwardIterator(_head);
  363. }
  364. }
  365. ////////////////////////////////////////////////////////////////////
  366. // Function: ArcChain::end
  367. // Access: Public
  368. // Description: Returns an iterator that can be used to traverse the
  369. // list of arcs.
  370. ////////////////////////////////////////////////////////////////////
  371. INLINE_GRAPH ArcChain::const_iterator ArcChain::
  372. end() const {
  373. return ForwardIterator();
  374. }
  375. ////////////////////////////////////////////////////////////////////
  376. // Function: ArcChain::empty
  377. // Access: Public
  378. // Description: Returns true if the list of arcs returned by begin()
  379. // .. end() is empty (i.e. begin() == end()), false
  380. // otherwise. This is the same as !has_arcs().
  381. ////////////////////////////////////////////////////////////////////
  382. INLINE_GRAPH bool ArcChain::
  383. empty() const {
  384. return (_head == (ArcComponent *)NULL || _head->is_top_node());
  385. }
  386. ////////////////////////////////////////////////////////////////////
  387. // Function: ArcChain::push_back
  388. // Access: Public
  389. // Description: Appends the indicated arc onto the end of the chain.
  390. ////////////////////////////////////////////////////////////////////
  391. INLINE_GRAPH void ArcChain::
  392. push_back(NodeRelation *arc) {
  393. // It is invalid to push an arc onto a chain that does not already
  394. // have at least a top node.
  395. nassertv(_head != (ArcComponent *)NULL);
  396. _head = new ArcComponent(arc, _head);
  397. }
  398. ////////////////////////////////////////////////////////////////////
  399. // Function: ArcChain::pop_back
  400. // Access: Public
  401. // Description: Removes the last arc from the end of the chain.
  402. ////////////////////////////////////////////////////////////////////
  403. INLINE_GRAPH void ArcChain::
  404. pop_back() {
  405. nassertv(_head != (ArcComponent *)NULL);
  406. _head = _head->get_next();
  407. // It is invalid to pop off the top node of the chain.
  408. nassertv(_head != (ArcComponent *)NULL);
  409. }
  410. ////////////////////////////////////////////////////////////////////
  411. // Function: ArcChain::back
  412. // Access: Public
  413. // Description: Returns the last arc in the chain.
  414. ////////////////////////////////////////////////////////////////////
  415. INLINE_GRAPH NodeRelation *ArcChain::
  416. back() const {
  417. nassertr(_head != (ArcComponent *)NULL, (NodeRelation *)NULL);
  418. return _head->get_arc();
  419. }
  420. ////////////////////////////////////////////////////////////////////
  421. // Function: ArcChain::operator ==
  422. // Access: Public
  423. // Description: Returns true if the two chains are equivalent; that
  424. // is, if they contain the same list of arcs in the same
  425. // order.
  426. ////////////////////////////////////////////////////////////////////
  427. INLINE_GRAPH bool ArcChain::
  428. operator == (const ArcChain &other) const {
  429. return (compare_to(other) == 0);
  430. }
  431. ////////////////////////////////////////////////////////////////////
  432. // Function: ArcChain::operator !=
  433. // Access: Public
  434. // Description: Returns true if the two chains are not equivalent.
  435. ////////////////////////////////////////////////////////////////////
  436. INLINE_GRAPH bool ArcChain::
  437. operator != (const ArcChain &other) const {
  438. return !operator == (other);
  439. }
  440. ////////////////////////////////////////////////////////////////////
  441. // Function: ArcChain::operator <
  442. // Access: Public
  443. // Description: Returns true if this ArcChain sorts before the other
  444. // one, false otherwise. The sorting order of two
  445. // nonequivalent ArcChains is consistent but undefined,
  446. // and is useful only for storing ArcChains in a sorted
  447. // container like an STL set.
  448. ////////////////////////////////////////////////////////////////////
  449. INLINE_GRAPH bool ArcChain::
  450. operator < (const ArcChain &other) const {
  451. return (compare_to(other) < 0);
  452. }
  453. ////////////////////////////////////////////////////////////////////
  454. // Function: ArcChain::compare_to
  455. // Access: Public
  456. // Description: Returns a number less than zero if this ArcChain
  457. // sorts before the other one, greater than zero if it
  458. // sorts after, or zero if they are equivalent.
  459. //
  460. // Two ArcChains are considered equivalent if they
  461. // consist of exactly the same list of arcs in the same
  462. // order. Otherwise, they are different; different
  463. // ArcChains will be ranked in a consistent but
  464. // undefined ordering; the ordering is useful only for
  465. // placing the ArcChains in a sorted container like an
  466. // STL set.
  467. ////////////////////////////////////////////////////////////////////
  468. INLINE_GRAPH int ArcChain::
  469. compare_to(const ArcChain &other) const {
  470. return r_compare_to(_head, other._head);
  471. }
  472. ////////////////////////////////////////////////////////////////////
  473. // Function: ArcChain::output
  474. // Access: Public
  475. // Description: Writes a sensible description of the ArcChain to the
  476. // indicated output stream.
  477. ////////////////////////////////////////////////////////////////////
  478. INLINE_GRAPH void ArcChain::
  479. output(ostream &out) const {
  480. if (_head == (ArcComponent *)NULL) {
  481. out << "(empty)";
  482. } else {
  483. r_output(out, _head);
  484. }
  485. }
  486. INLINE_GRAPH ostream &operator << (ostream &out, const ArcChain &arc_chain) {
  487. arc_chain.output(out);
  488. return out;
  489. }