fix list_cycles()

This commit is contained in:
David Rose 2004-09-13 17:26:16 +00:00
parent cf44a95d84
commit 63a777ed78
6 changed files with 44 additions and 148 deletions

View File

@ -323,29 +323,3 @@ CompositionCycleDescEntry(const RenderState *obj,
_inverted(inverted)
{
}
////////////////////////////////////////////////////////////////////
// Function: RenderState::CycleChain::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE RenderState::CycleChain::
CycleChain(const RenderState *state) :
_state(state),
_prev(NULL),
_length(1)
{
}
////////////////////////////////////////////////////////////////////
// Function: RenderState::CycleChain::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE RenderState::CycleChain::
CycleChain(CycleChain *prev, const RenderState *state) :
_state(state),
_prev(prev),
_length(prev->_length + 1)
{
}

View File

@ -881,8 +881,7 @@ list_cycles(ostream &out) {
bool inserted = visited.insert(state).second;
if (inserted) {
VisitedStates visited_this_cycle;
CycleChain chain(state);
if (r_detect_cycles(state, visited_this_cycle, &chain, cycle_desc)) {
if (r_detect_cycles(state, state, 1, visited_this_cycle, cycle_desc)) {
// This state begins a cycle.
CompositionCycleDesc::reverse_iterator csi;
@ -1294,28 +1293,30 @@ do_invert_compose(const RenderState *other) const {
// in reverse order.
////////////////////////////////////////////////////////////////////
bool RenderState::
r_detect_cycles(const RenderState *state,
r_detect_cycles(const RenderState *start_state,
const RenderState *current_state,
int length,
RenderState::VisitedStates &visited_this_cycle,
RenderState::CycleChain *chain,
RenderState::CompositionCycleDesc &cycle_desc) {
bool inserted = visited_this_cycle.insert(state).second;
if (!inserted && chain->has_result(state)) {
bool inserted = visited_this_cycle.insert(current_state).second;
if (!inserted) {
// We've already seen this state; therefore, we've found a cycle.
// However, we only care about cycles that involve more than two
// steps. If only one or two nodes are involved, it doesn't
// represent a memory leak, so no problem there.
return (chain->_length > 2);
// However, we only care about cycles that return to the starting
// state and involve more than two steps. If only one or two
// nodes are involved, it doesn't represent a memory leak, so no
// problem there.
return (current_state == start_state && length > 2);
}
CompositionCache::const_iterator ci;
for (ci = state->_composition_cache.begin();
ci != state->_composition_cache.end();
for (ci = current_state->_composition_cache.begin();
ci != current_state->_composition_cache.end();
++ci) {
const RenderState *result = (*ci).second._result;
if (result != (const RenderState *)NULL) {
CycleChain next_chain(chain, result);
if (r_detect_cycles(result, visited_this_cycle, &next_chain, cycle_desc)) {
if (r_detect_cycles(start_state, result, length + 1,
visited_this_cycle, cycle_desc)) {
// Cycle detected.
CompositionCycleDescEntry entry((*ci).first, result, false);
cycle_desc.push_back(entry);
@ -1324,13 +1325,13 @@ r_detect_cycles(const RenderState *state,
}
}
for (ci = state->_invert_composition_cache.begin();
ci != state->_invert_composition_cache.end();
for (ci = current_state->_invert_composition_cache.begin();
ci != current_state->_invert_composition_cache.end();
++ci) {
const RenderState *result = (*ci).second._result;
if (result != (const RenderState *)NULL) {
CycleChain next_chain(chain, result);
if (r_detect_cycles(result, visited_this_cycle, &next_chain, cycle_desc)) {
if (r_detect_cycles(start_state, result, length + 1,
visited_this_cycle, cycle_desc)) {
// Cycle detected.
CompositionCycleDescEntry entry((*ci).first, result, true);
cycle_desc.push_back(entry);
@ -1599,20 +1600,3 @@ fillin(DatagramIterator &scan, BamReader *manager) {
_attributes.push_back(Attribute(override));
}
}
////////////////////////////////////////////////////////////////////
// Function: RenderState::CycleChain::has_result
// Access: Public
// Description: Returns true if the indicated state has been reached
// in this chain previously, false otherwise.
////////////////////////////////////////////////////////////////////
bool RenderState::CycleChain::
has_result(const RenderState *state) const {
if (_state == state) {
return true;
}
if (_prev != NULL) {
return _prev->has_result(state);
}
return false;
}

View File

@ -133,24 +133,14 @@ private:
};
typedef pvector<CompositionCycleDescEntry> CompositionCycleDesc;
typedef pset<const RenderState *> VisitedStates;
class CycleChain {
public:
INLINE CycleChain(const RenderState *state);
INLINE CycleChain(CycleChain *prev, const RenderState *state);
bool has_result(const RenderState *state) const;
const RenderState *_state;
CycleChain *_prev;
int _length;
};
static CPT(RenderState) return_new(RenderState *state);
CPT(RenderState) do_compose(const RenderState *other) const;
CPT(RenderState) do_invert_compose(const RenderState *other) const;
static bool r_detect_cycles(const RenderState *state,
static bool r_detect_cycles(const RenderState *start_state,
const RenderState *current_state,
int length,
VisitedStates &visited_this_cycle,
CycleChain *chain,
CompositionCycleDesc &cycle_desc);
void determine_bin_index();

View File

@ -597,29 +597,3 @@ CompositionCycleDescEntry(const TransformState *obj,
_inverted(inverted)
{
}
////////////////////////////////////////////////////////////////////
// Function: TransformState::CycleChain::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE TransformState::CycleChain::
CycleChain(const TransformState *state) :
_state(state),
_prev(NULL),
_length(1)
{
}
////////////////////////////////////////////////////////////////////
// Function: TransformState::CycleChain::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE TransformState::CycleChain::
CycleChain(CycleChain *prev, const TransformState *state) :
_state(state),
_prev(prev),
_length(prev->_length + 1)
{
}

View File

@ -922,8 +922,7 @@ list_cycles(ostream &out) {
bool inserted = visited.insert(state).second;
if (inserted) {
VisitedStates visited_this_cycle;
CycleChain chain(state);
if (r_detect_cycles(state, visited_this_cycle, &chain, cycle_desc)) {
if (r_detect_cycles(state, state, 1, visited_this_cycle, cycle_desc)) {
// This state begins a cycle.
CompositionCycleDesc::reverse_iterator csi;
@ -1199,28 +1198,30 @@ do_invert_compose(const TransformState *other) const {
// in reverse order.
////////////////////////////////////////////////////////////////////
bool TransformState::
r_detect_cycles(const TransformState *state,
r_detect_cycles(const TransformState *start_state,
const TransformState *current_state,
int length,
TransformState::VisitedStates &visited_this_cycle,
TransformState::CycleChain *chain,
TransformState::CompositionCycleDesc &cycle_desc) {
bool inserted = visited_this_cycle.insert(state).second;
if (!inserted && chain->has_result(state)) {
bool inserted = visited_this_cycle.insert(current_state).second;
if (!inserted) {
// We've already seen this state; therefore, we've found a cycle.
// However, we only care about cycles that involve more than two
// steps. If only one or two nodes are involved, it doesn't
// represent a memory leak, so no problem there.
return (chain->_length > 2);
// However, we only care about cycles that return to the starting
// state and involve more than two steps. If only one or two
// nodes are involved, it doesn't represent a memory leak, so no
// problem there.
return (current_state == start_state && length > 2);
}
CompositionCache::const_iterator ci;
for (ci = state->_composition_cache.begin();
ci != state->_composition_cache.end();
for (ci = current_state->_composition_cache.begin();
ci != current_state->_composition_cache.end();
++ci) {
const TransformState *result = (*ci).second._result;
if (result != (const TransformState *)NULL) {
CycleChain next_chain(chain, result);
if (r_detect_cycles(result, visited_this_cycle, &next_chain, cycle_desc)) {
if (r_detect_cycles(start_state, result, length + 1,
visited_this_cycle, cycle_desc)) {
// Cycle detected.
CompositionCycleDescEntry entry((*ci).first, result, false);
cycle_desc.push_back(entry);
@ -1229,13 +1230,13 @@ r_detect_cycles(const TransformState *state,
}
}
for (ci = state->_invert_composition_cache.begin();
ci != state->_invert_composition_cache.end();
for (ci = current_state->_invert_composition_cache.begin();
ci != current_state->_invert_composition_cache.end();
++ci) {
const TransformState *result = (*ci).second._result;
if (result != (const TransformState *)NULL) {
CycleChain next_chain(chain, result);
if (r_detect_cycles(result, visited_this_cycle, &next_chain, cycle_desc)) {
if (r_detect_cycles(start_state, result, length + 1,
visited_this_cycle, cycle_desc)) {
// Cycle detected.
CompositionCycleDescEntry entry((*ci).first, result, true);
cycle_desc.push_back(entry);
@ -1544,20 +1545,3 @@ fillin(DatagramIterator &scan, BamReader *manager) {
_mat.read_datagram(scan);
}
}
////////////////////////////////////////////////////////////////////
// Function: TransformState::CycleChain::has_result
// Access: Public
// Description: Returns true if the indicated state has been reached
// in this chain previously, false otherwise.
////////////////////////////////////////////////////////////////////
bool TransformState::CycleChain::
has_result(const TransformState *state) const {
if (_state == state) {
return true;
}
if (_prev != NULL) {
return _prev->has_result(state);
}
return false;
}

View File

@ -148,24 +148,14 @@ private:
};
typedef pvector<CompositionCycleDescEntry> CompositionCycleDesc;
typedef pset<const TransformState *> VisitedStates;
class CycleChain {
public:
INLINE CycleChain(const TransformState *state);
INLINE CycleChain(CycleChain *prev, const TransformState *state);
bool has_result(const TransformState *state) const;
const TransformState *_state;
CycleChain *_prev;
int _length;
};
static CPT(TransformState) return_new(TransformState *state);
CPT(TransformState) do_compose(const TransformState *other) const;
CPT(TransformState) do_invert_compose(const TransformState *other) const;
static bool r_detect_cycles(const TransformState *state,
static bool r_detect_cycles(const TransformState *start_state,
const TransformState *current_state,
int length,
VisitedStates &visited_this_cycle,
CycleChain *chain,
CompositionCycleDesc &cycle_desc);
private: