nodeTransitionCacheEntry.I 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389
  1. // Filename: nodeTransitionCacheEntry.I
  2. // Created by: drose (20Mar00)
  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. #include "config_graph.h"
  19. ////////////////////////////////////////////////////////////////////
  20. // Function: NodeTransitionCacheEntry::Constructor
  21. // Access: Public
  22. // Description:
  23. ////////////////////////////////////////////////////////////////////
  24. INLINE_GRAPH NodeTransitionCacheEntry::
  25. NodeTransitionCacheEntry(NodeTransition *trans) : _trans(trans) {
  26. }
  27. ////////////////////////////////////////////////////////////////////
  28. // Function: NodeTransitionCacheEntry::Copy Constructor
  29. // Access: Public
  30. // Description:
  31. ////////////////////////////////////////////////////////////////////
  32. INLINE_GRAPH NodeTransitionCacheEntry::
  33. NodeTransitionCacheEntry(const NodeTransitionCacheEntry &copy) :
  34. _trans(copy._trans),
  35. _computed(copy._computed),
  36. _verified(copy._verified)
  37. {
  38. }
  39. ////////////////////////////////////////////////////////////////////
  40. // Function: NodeTransitionCacheEntry::Copy Assignment Operator
  41. // Access: Public
  42. // Description:
  43. ////////////////////////////////////////////////////////////////////
  44. INLINE_GRAPH void NodeTransitionCacheEntry::
  45. operator = (const NodeTransitionCacheEntry &copy) {
  46. _trans = copy._trans;
  47. _computed = copy._computed;
  48. _verified = copy._verified;
  49. }
  50. ////////////////////////////////////////////////////////////////////
  51. // Function: NodeTransitionCacheEntry::is_identity
  52. // Access: Public
  53. // Description:
  54. ////////////////////////////////////////////////////////////////////
  55. INLINE_GRAPH bool NodeTransitionCacheEntry::
  56. is_identity() const {
  57. return (_trans == (NodeTransition *)NULL);
  58. // || _trans->is_identity();
  59. }
  60. ////////////////////////////////////////////////////////////////////
  61. // Function: NodeTransitionCacheEntry::compare_to
  62. // Access: Public
  63. // Description:
  64. ////////////////////////////////////////////////////////////////////
  65. INLINE_GRAPH int NodeTransitionCacheEntry::
  66. compare_to(const NodeTransitionCacheEntry &other) const {
  67. bool this_ident = is_identity();
  68. bool other_ident = other.is_identity();
  69. if (this_ident && other_ident) {
  70. return 0;
  71. }
  72. if (this_ident) {
  73. return -1;
  74. }
  75. if (other_ident) {
  76. return 1;
  77. }
  78. // This should be guaranteed by the above logic.
  79. nassertr(_trans != (NodeTransition *)NULL &&
  80. other._trans != (NodeTransition *)NULL, false);
  81. return _trans->compare_to(*other._trans);
  82. }
  83. ////////////////////////////////////////////////////////////////////
  84. // Function: NodeTransitionCacheEntry::generate_hash
  85. // Access: Public
  86. // Description: Adds the transition to the indicated hash generator.
  87. ////////////////////////////////////////////////////////////////////
  88. INLINE_GRAPH void NodeTransitionCacheEntry::
  89. generate_hash(GraphHashGenerator &hash) const {
  90. if (_trans != (NodeTransition *)NULL) {
  91. _trans->generate_hash(hash);
  92. }
  93. }
  94. ////////////////////////////////////////////////////////////////////
  95. // Function: NodeTransitionCacheEntry::clear
  96. // Access: Public
  97. // Description: Reinitializes the cache entry to its original state.
  98. ////////////////////////////////////////////////////////////////////
  99. INLINE_GRAPH void NodeTransitionCacheEntry::
  100. clear() {
  101. _trans.clear();
  102. _computed.clear();
  103. _verified.clear();
  104. }
  105. ////////////////////////////////////////////////////////////////////
  106. // Function: NodeTransitionCacheEntry::set_trans
  107. // Access: Public
  108. // Description: Changes the transition associated with the cache
  109. // entry without changing the associated time stamps.
  110. ////////////////////////////////////////////////////////////////////
  111. INLINE_GRAPH void NodeTransitionCacheEntry::
  112. set_trans(NodeTransition *trans) {
  113. _trans = trans;
  114. }
  115. ////////////////////////////////////////////////////////////////////
  116. // Function: NodeTransitionCacheEntry::clear_trans
  117. // Access: Public
  118. // Description: Removes the transitoin associated with the cache
  119. // entry without changing the associated time stamps.
  120. // This is of limited usefulness.
  121. ////////////////////////////////////////////////////////////////////
  122. INLINE_GRAPH void NodeTransitionCacheEntry::
  123. clear_trans() {
  124. _trans.clear();
  125. }
  126. ////////////////////////////////////////////////////////////////////
  127. // Function: NodeTransitionCacheEntry::has_trans
  128. // Access: Public
  129. // Description: Returns true if the cache entry has an associated
  130. // NodeTransition, false if it doesn't (and the
  131. // transition should be assumed to be identity).
  132. ////////////////////////////////////////////////////////////////////
  133. INLINE_GRAPH bool NodeTransitionCacheEntry::
  134. has_trans() const {
  135. return _trans != (NodeTransition *)NULL;
  136. }
  137. ////////////////////////////////////////////////////////////////////
  138. // Function: NodeTransitionCacheEntry::get_trans
  139. // Access: Public
  140. // Description: Returns the NodeTransition associated with the cache
  141. // entry, or NULL if there is no associated
  142. // NodeTransition (in which case it should be assumed to
  143. // be identity).
  144. ////////////////////////////////////////////////////////////////////
  145. INLINE_GRAPH NodeTransition *NodeTransitionCacheEntry::
  146. get_trans() const {
  147. return _trans;
  148. }
  149. ////////////////////////////////////////////////////////////////////
  150. // Function: NodeTransitionCacheEntry::is_cache_verified
  151. // Access: Public
  152. // Description:
  153. ////////////////////////////////////////////////////////////////////
  154. INLINE_GRAPH bool NodeTransitionCacheEntry::
  155. is_cache_verified(UpdateSeq as_of) const {
  156. if (wrt_cat.is_spam()) {
  157. wrt_cat.spam()
  158. << "NodeTransitionCacheEntry::is_cache_verified(" << as_of
  159. << "), _verified = " << _verified << ", result = "
  160. << (as_of <= _verified) << "\n";
  161. }
  162. return as_of <= _verified;
  163. }
  164. ////////////////////////////////////////////////////////////////////
  165. // Function: NodeTransitionCacheEntry::is_freshly_computed
  166. // Access: Public
  167. // Description:
  168. ////////////////////////////////////////////////////////////////////
  169. INLINE_GRAPH bool NodeTransitionCacheEntry::
  170. is_freshly_computed(UpdateSeq changed) const {
  171. return changed < _computed;
  172. }
  173. ////////////////////////////////////////////////////////////////////
  174. // Function: NodeTransitionCacheEntry::set_computed_verified
  175. // Access: Public
  176. // Description:
  177. ////////////////////////////////////////////////////////////////////
  178. INLINE_GRAPH void NodeTransitionCacheEntry::
  179. set_computed_verified(UpdateSeq now) {
  180. _computed = now;
  181. _verified = now;
  182. }
  183. ////////////////////////////////////////////////////////////////////
  184. // Function: NodeTransitionCacheEntry::Typecast Operator
  185. // Access: Public
  186. // Description: This typecast operator allows the cache entry to be
  187. // directly assigned to a NodeTransition pointer. It's
  188. // primarily useful for using the code in
  189. // setTransitionHelpers.h interchangeably between
  190. // NodeTransitions and NodeTransitionCaches.
  191. ////////////////////////////////////////////////////////////////////
  192. INLINE_GRAPH NodeTransitionCacheEntry::
  193. operator const PT(NodeTransition) &() const {
  194. return _trans;
  195. }
  196. ////////////////////////////////////////////////////////////////////
  197. // Function: NodeTransitionCacheEntry::get_computed
  198. // Access: Public
  199. // Description: Returns the timestamp at which this cache entry was
  200. // computed.
  201. ////////////////////////////////////////////////////////////////////
  202. INLINE_GRAPH UpdateSeq NodeTransitionCacheEntry::
  203. get_computed() const {
  204. return _computed;
  205. }
  206. ////////////////////////////////////////////////////////////////////
  207. // Function: NodeTransitionCacheEntry::get_verified
  208. // Access: Public
  209. // Description: Returns the last timestamp at which this cache entry
  210. // was verified; i.e. when the graph was last walked up
  211. // to the root to ensure the cache entry is still valid.
  212. ////////////////////////////////////////////////////////////////////
  213. INLINE_GRAPH UpdateSeq NodeTransitionCacheEntry::
  214. get_verified() const {
  215. return _verified;
  216. }
  217. ////////////////////////////////////////////////////////////////////
  218. // Function: NodeTransitionCacheEntry::invert
  219. // Access: Public, Static
  220. // Description: Returns a new cache entry that represents the inverse
  221. // of a.
  222. ////////////////////////////////////////////////////////////////////
  223. INLINE_GRAPH NodeTransitionCacheEntry NodeTransitionCacheEntry::
  224. invert(const NodeTransitionCacheEntry &a) {
  225. if (a.is_identity()) {
  226. return a;
  227. }
  228. return NodeTransitionCacheEntry(a._trans->invert());
  229. }
  230. ////////////////////////////////////////////////////////////////////
  231. // Function: NodeTransitionCacheEntry::compose
  232. // Access: Public, Static
  233. // Description: Returns a new cache entry that represents the
  234. // composition of a and b.
  235. ////////////////////////////////////////////////////////////////////
  236. INLINE_GRAPH NodeTransitionCacheEntry NodeTransitionCacheEntry::
  237. compose(const NodeTransitionCacheEntry &a,
  238. const NodeTransitionCacheEntry &b) {
  239. if (a.is_identity()) {
  240. return b;
  241. }
  242. if (b.is_identity()) {
  243. return a;
  244. }
  245. return NodeTransitionCacheEntry(a._trans->compose(b._trans));
  246. }
  247. ////////////////////////////////////////////////////////////////////
  248. // Function: NodeTransitionCacheEntry::invert_compose
  249. // Access: Public, Static
  250. // Description: Returns a new cache entry that represents the
  251. // composition of invert(a) and b.
  252. ////////////////////////////////////////////////////////////////////
  253. INLINE_GRAPH NodeTransitionCacheEntry NodeTransitionCacheEntry::
  254. invert_compose(const NodeTransitionCacheEntry &a,
  255. const NodeTransitionCacheEntry &b) {
  256. if (a.is_identity()) {
  257. return b;
  258. }
  259. if (b.is_identity()) {
  260. return NodeTransitionCacheEntry(a._trans->invert());
  261. }
  262. if (a._trans->compare_to(*b._trans) == 0) {
  263. return NodeTransitionCacheEntry();
  264. }
  265. PT(NodeTransition) inv = a._trans->invert();
  266. if (inv == (NodeTransition *)NULL) {
  267. return b;
  268. }
  269. // We don't care about priority for this operation.
  270. // This is broken! We don't have the right the change the priority
  271. // on this node. For now, leave this out, since we aren't using
  272. // priority on any transitions for which we're computing wrt() at
  273. // the moment. Fix me soon.
  274. // inv->set_priority(b._trans->get_priority());
  275. return NodeTransitionCacheEntry(inv->compose(b._trans));
  276. }
  277. ////////////////////////////////////////////////////////////////////
  278. // Function: NodeTransitionCacheEntry::cached_compose
  279. // Access: Public, Static
  280. // Description: Sets this cache entry to the result of compose(a, b),
  281. // as computed using the cache value as a hint. Mark
  282. // the result as computed at time 'now'.
  283. ////////////////////////////////////////////////////////////////////
  284. INLINE_GRAPH NodeTransitionCacheEntry NodeTransitionCacheEntry::
  285. cached_compose(const NodeTransitionCacheEntry &a,
  286. const NodeTransitionCacheEntry &cache,
  287. const NodeTransitionCacheEntry &b,
  288. UpdateSeq now) {
  289. if (wrt_cat.is_spam()) {
  290. wrt_cat.spam()
  291. << "Composing:\n"
  292. << " a) " << a << " = " << a._computed << "\n"
  293. << " cache) " << cache << " = " << cache._computed << "\n"
  294. << " b) " << b << " = " << b._computed << "\n";
  295. }
  296. if (cache._computed == UpdateSeq::initial() ||
  297. (a._computed == UpdateSeq::initial() &&
  298. b._computed == UpdateSeq::initial()) ||
  299. cache._computed < a._computed) {
  300. // If the cache value has not yet been computed, or if the values
  301. // in a and b are both empty, or if the cache is older than the
  302. // source value (a), discard the cache and compute the composition
  303. // directly.
  304. NodeTransitionCacheEntry result = compose(a, b);
  305. result.set_computed_verified(now);
  306. if (wrt_cat.is_spam()) {
  307. wrt_cat.spam() << "computed result is " << result << "\n";
  308. }
  309. return result;
  310. } else {
  311. // Otherwise, the cache value is recent and we can simply use it
  312. // directly.
  313. NodeTransitionCacheEntry result = cache;
  314. result._verified = now;
  315. if (wrt_cat.is_spam()) {
  316. wrt_cat.spam() << "cached result is " << result << "\n";
  317. }
  318. return result;
  319. }
  320. }
  321. ////////////////////////////////////////////////////////////////////
  322. // Function: NodeTransitionCacheEntry::apply
  323. // Access: Public, Static
  324. // Description: Returns a new NodeAttribute (or possibly the same
  325. // NodeAttribute) that represents the indicated
  326. // transition applied to the attribute.
  327. ////////////////////////////////////////////////////////////////////
  328. INLINE_GRAPH NodeAttribute *NodeTransitionCacheEntry::
  329. apply(const NodeAttribute *a, const NodeTransitionCacheEntry &b) {
  330. if (b.is_identity()) {
  331. return (NodeAttribute *)a;
  332. }
  333. return b._trans->apply(a);
  334. }
  335. ////////////////////////////////////////////////////////////////////
  336. // Function: NodeTransitionCacheEntry::make_attrib
  337. // Access: Public, Static
  338. // Description:
  339. ////////////////////////////////////////////////////////////////////
  340. INLINE_GRAPH NodeAttribute *NodeTransitionCacheEntry::
  341. make_attrib() const {
  342. if (_trans == (NodeTransition *)NULL) {
  343. return NULL;
  344. }
  345. return _trans->make_attrib();
  346. }
  347. INLINE_GRAPH ostream &operator << (ostream &out, const NodeTransitionCacheEntry &e) {
  348. e.output(out);
  349. return out;
  350. }