354 lines
12 KiB
Plaintext
354 lines
12 KiB
Plaintext
// Filename: nodeTransitionCacheEntry.I
|
|
// Created by: drose (20Mar00)
|
|
//
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
#include "config_graph.h"
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: NodeTransitionCacheEntry::Constructor
|
|
// Access: Public
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE NodeTransitionCacheEntry::
|
|
NodeTransitionCacheEntry(NodeTransition *trans) : _trans(trans) {
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: NodeTransitionCacheEntry::Copy Constructor
|
|
// Access: Public
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE NodeTransitionCacheEntry::
|
|
NodeTransitionCacheEntry(const NodeTransitionCacheEntry ©) :
|
|
_trans(copy._trans),
|
|
_computed(copy._computed),
|
|
_verified(copy._verified)
|
|
{
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: NodeTransitionCacheEntry::Copy Assignment Operator
|
|
// Access: Public
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE void NodeTransitionCacheEntry::
|
|
operator = (const NodeTransitionCacheEntry ©) {
|
|
_trans = copy._trans;
|
|
_computed = copy._computed;
|
|
_verified = copy._verified;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: NodeTransitionCacheEntry::is_identity
|
|
// Access: Public
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE bool NodeTransitionCacheEntry::
|
|
is_identity() const {
|
|
return (_trans == (NodeTransition *)NULL);
|
|
// || _trans->is_identity();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: NodeTransitionCacheEntry::compare_to
|
|
// Access: Public
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE int NodeTransitionCacheEntry::
|
|
compare_to(const NodeTransitionCacheEntry &other) const {
|
|
bool this_ident = is_identity();
|
|
bool other_ident = other.is_identity();
|
|
if (this_ident && other_ident) {
|
|
return 0;
|
|
}
|
|
if (this_ident) {
|
|
return -1;
|
|
}
|
|
if (other_ident) {
|
|
return 1;
|
|
}
|
|
|
|
// This should be guaranteed by the above logic.
|
|
nassertr(_trans != (NodeTransition *)NULL &&
|
|
other._trans != (NodeTransition *)NULL, false);
|
|
|
|
return _trans->compare_to(*other._trans);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: NodeTransitionCacheEntry::clear
|
|
// Access: Public
|
|
// Description: Reinitializes the cache entry to its original state.
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE void NodeTransitionCacheEntry::
|
|
clear() {
|
|
_trans.clear();
|
|
_computed.clear();
|
|
_verified.clear();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: NodeTransitionCacheEntry::set_trans
|
|
// Access: Public
|
|
// Description: Changes the transition associated with the cache
|
|
// entry without changing the associated time stamps.
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE void NodeTransitionCacheEntry::
|
|
set_trans(NodeTransition *trans) {
|
|
_trans = trans;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: NodeTransitionCacheEntry::clear_trans
|
|
// Access: Public
|
|
// Description: Removes the transitoin associated with the cache
|
|
// entry without changing the associated time stamps.
|
|
// This is of limited usefulness.
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE void NodeTransitionCacheEntry::
|
|
clear_trans() {
|
|
_trans.clear();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: NodeTransitionCacheEntry::has_trans
|
|
// Access: Public
|
|
// Description: Returns true if the cache entry has an associated
|
|
// NodeTransition, false if it doesn't (and the
|
|
// transition should be assumed to be identity).
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE bool NodeTransitionCacheEntry::
|
|
has_trans() const {
|
|
return _trans != (NodeTransition *)NULL;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: NodeTransitionCacheEntry::get_trans
|
|
// Access: Public
|
|
// Description: Returns the NodeTransition associated with the cache
|
|
// entry, or NULL if there is no associated
|
|
// NodeTransition (in which case it should be assumed to
|
|
// be identity).
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE NodeTransition *NodeTransitionCacheEntry::
|
|
get_trans() const {
|
|
return _trans;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: NodeTransitionCacheEntry::is_cache_verified
|
|
// Access: Public
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE bool NodeTransitionCacheEntry::
|
|
is_cache_verified(UpdateSeq now) const {
|
|
return _verified == now;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: NodeTransitionCacheEntry::is_freshly_computed
|
|
// Access: Public
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE bool NodeTransitionCacheEntry::
|
|
is_freshly_computed(UpdateSeq changed) const {
|
|
return changed < _computed;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: NodeTransitionCacheEntry::set_computed_verified
|
|
// Access: Public
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE void NodeTransitionCacheEntry::
|
|
set_computed_verified(UpdateSeq now) {
|
|
_computed = now;
|
|
_verified = now;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: NodeTransitionCacheEntry::Typecast Operator
|
|
// Access: Public
|
|
// Description: This typecast operator allows the cache entry to be
|
|
// directly assigned to a NodeTransition pointer. It's
|
|
// primarily useful for using the code in
|
|
// setTransitionHelpers.h interchangeably between
|
|
// NodeTransitions and NodeTransitionCaches.
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE NodeTransitionCacheEntry::
|
|
operator const PT(NodeTransition) &() const {
|
|
return _trans;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: NodeTransitionCacheEntry::get_computed
|
|
// Access: Public
|
|
// Description: Returns the timestamp at which this cache entry was
|
|
// computed.
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE UpdateSeq NodeTransitionCacheEntry::
|
|
get_computed() const {
|
|
return _computed;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: NodeTransitionCacheEntry::get_verified
|
|
// Access: Public
|
|
// Description: Returns the last timestamp at which this cache entry
|
|
// was verified; i.e. when the graph was last walked up
|
|
// to the root to ensure the cache entry is still valid.
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE UpdateSeq NodeTransitionCacheEntry::
|
|
get_verified() const {
|
|
return _verified;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: NodeTransitionCacheEntry::invert
|
|
// Access: Public, Static
|
|
// Description: Returns a new cache entry that represents the inverse
|
|
// of a.
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE NodeTransitionCacheEntry NodeTransitionCacheEntry::
|
|
invert(const NodeTransitionCacheEntry &a) {
|
|
if (a.is_identity()) {
|
|
return a;
|
|
}
|
|
return NodeTransitionCacheEntry(a._trans->invert());
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: NodeTransitionCacheEntry::compose
|
|
// Access: Public, Static
|
|
// Description: Returns a new cache entry that represents the
|
|
// composition of a and b.
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE NodeTransitionCacheEntry NodeTransitionCacheEntry::
|
|
compose(const NodeTransitionCacheEntry &a,
|
|
const NodeTransitionCacheEntry &b) {
|
|
if (a.is_identity()) {
|
|
return b;
|
|
}
|
|
if (b.is_identity()) {
|
|
return a;
|
|
}
|
|
return NodeTransitionCacheEntry(a._trans->compose(b._trans));
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: NodeTransitionCacheEntry::invert_compose
|
|
// Access: Public, Static
|
|
// Description: Returns a new cache entry that represents the
|
|
// composition of invert(a) and b.
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE NodeTransitionCacheEntry NodeTransitionCacheEntry::
|
|
invert_compose(const NodeTransitionCacheEntry &a,
|
|
const NodeTransitionCacheEntry &b) {
|
|
if (a.is_identity()) {
|
|
return b;
|
|
}
|
|
if (b.is_identity()) {
|
|
return NodeTransitionCacheEntry(a._trans->invert());
|
|
}
|
|
if (a._trans->compare_to(*b._trans) == 0) {
|
|
return NodeTransitionCacheEntry();
|
|
}
|
|
|
|
PT(NodeTransition) inv = a._trans->invert();
|
|
if (inv == (NodeTransition *)NULL) {
|
|
return b;
|
|
}
|
|
|
|
// We don't care about priority for this operation.
|
|
|
|
// This is broken! We don't have the right the change the priority
|
|
// on this node. For now, leave this out, since we aren't using
|
|
// priority on any transitions for which we're computing wrt() at
|
|
// the moment. Fix me soon.
|
|
// inv->set_priority(b._trans->get_priority());
|
|
|
|
return NodeTransitionCacheEntry(inv->compose(b._trans));
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: NodeTransitionCacheEntry::cached_compose
|
|
// Access: Public, Static
|
|
// Description: Sets this cache entry to the result of compose(a, b),
|
|
// as computed using the cache value as a hint.
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE NodeTransitionCacheEntry NodeTransitionCacheEntry::
|
|
cached_compose(const NodeTransitionCacheEntry &a,
|
|
const NodeTransitionCacheEntry &cache,
|
|
const NodeTransitionCacheEntry &b,
|
|
UpdateSeq now) {
|
|
#ifndef NDEBUG
|
|
if (wrt_cat.is_spam()) {
|
|
wrt_cat.spam()
|
|
<< "Composing:\n"
|
|
<< " a) " << a << " = " << a._computed << "\n"
|
|
<< " cache) " << cache << " = " << cache._computed << "\n"
|
|
<< " b) " << b << " = " << b._computed << "\n";
|
|
}
|
|
#endif
|
|
if (cache._computed == UpdateSeq::initial() ||
|
|
(a._computed == UpdateSeq::initial() &&
|
|
b._computed == UpdateSeq::initial()) ||
|
|
cache._computed < a._computed) {
|
|
|
|
// If the cache value has not yet been computed, or if the values
|
|
// in a and b are both empty, or if the cache is older than the
|
|
// source value (a), discard the cache and compute the composition
|
|
// directly.
|
|
NodeTransitionCacheEntry result = compose(a, b);
|
|
result.set_computed_verified(now);
|
|
#ifndef NDEBUG
|
|
if (wrt_cat.is_spam()) {
|
|
wrt_cat.spam() << "computed result is " << result << "\n";
|
|
}
|
|
#endif
|
|
return result;
|
|
|
|
} else {
|
|
// Otherwise, the cache value is recent and we can simply use it
|
|
// directly.
|
|
NodeTransitionCacheEntry result = cache;
|
|
result._verified = now;
|
|
#ifndef NDEBUG
|
|
if (wrt_cat.is_spam()) {
|
|
wrt_cat.spam() << "cached result is " << result << "\n";
|
|
}
|
|
#endif
|
|
return result;
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: NodeTransitionCacheEntry::apply
|
|
// Access: Public, Static
|
|
// Description: Returns a new NodeAttribute (or possibly the same
|
|
// NodeAttribute) that represents the indicated
|
|
// transition applied to the attribute.
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE NodeAttribute *NodeTransitionCacheEntry::
|
|
apply(const NodeAttribute *a, const NodeTransitionCacheEntry &b) {
|
|
if (b.is_identity()) {
|
|
return (NodeAttribute *)a;
|
|
}
|
|
|
|
return b._trans->apply(a);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: NodeTransitionCacheEntry::make_attrib
|
|
// Access: Public, Static
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE NodeAttribute *NodeTransitionCacheEntry::
|
|
make_attrib() const {
|
|
if (_trans == (NodeTransition *)NULL) {
|
|
return NULL;
|
|
}
|
|
return _trans->make_attrib();
|
|
}
|