open_toontown_panda3d/panda/src/graph/dftraverser.I

102 lines
3.6 KiB
Plaintext

// Filename: dftraverser.cxx
// Created by: drose (26Oct98)
//
////////////////////////////////////////////////////////////////////
#include "dftraverser.h"
#include <notify.h>
////////////////////////////////////////////////////////////////////
// Function: DFTraverser::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class Visitor, class LevelState>
INLINE_GRAPH DFTraverser<Visitor, LevelState>::
DFTraverser(Visitor &visitor,
const AttributeWrapper &initial_render_state,
TypeHandle graph_type) :
_visitor(visitor),
_initial_render_state(initial_render_state),
_graph_type(graph_type)
{
}
////////////////////////////////////////////////////////////////////
// Function: DFTraverser::start
// Access: Public
// Description: Starts the traversal from the indicated arc.
////////////////////////////////////////////////////////////////////
template<class Visitor, class LevelState>
INLINE_GRAPH void DFTraverser<Visitor, LevelState>::
start(NodeRelation *arc, const LevelState &initial_level_state) {
traverse(arc, _initial_render_state, initial_level_state);
}
////////////////////////////////////////////////////////////////////
// Function: DFTraverser::start
// Access: Public
// Description: Starts the traversal from the indicated node.
////////////////////////////////////////////////////////////////////
template<class Visitor, class LevelState>
INLINE_GRAPH void DFTraverser<Visitor, LevelState>::
start(Node *root, const LevelState &initial_level_state) {
LevelState level_state(initial_level_state);
traverse(root, _initial_render_state, level_state);
}
////////////////////////////////////////////////////////////////////
// Function: DFTraverser::Traverse
// Access: Public
// Description: Walks to the next arc of the graph.
////////////////////////////////////////////////////////////////////
template<class Visitor, class LevelState>
void DFTraverser<Visitor, LevelState>::
traverse(NodeRelation *arc, AttributeWrapper state, LevelState level_state) {
nassertv(arc->get_child() != (Node *)NULL);
// Give the visitor a chance to veto this arc.
TransitionWrapper trans =
TransitionWrapper::init_from(_initial_render_state);
trans.extract_from(arc);
AttributeWrapper post_state(state);
post_state.apply_in_place(trans);
if (_visitor.forward_arc(arc, trans, state, post_state, level_state)) {
traverse(arc->get_child(), post_state, level_state);
_visitor.backward_arc(arc, trans, state, post_state, level_state);
}
}
////////////////////////////////////////////////////////////////////
// Function: DFTraverser::Traverse
// Access: Public
// Description: Walks to the next node of the graph.
////////////////////////////////////////////////////////////////////
template<class Visitor, class LevelState>
void DFTraverser<Visitor, LevelState>::
traverse(Node *node, AttributeWrapper &state, LevelState &level_state) {
// Tell the visitor we reached the node, and give it a chance to
// veto our further progress.
if (_visitor.reached_node(node, state, level_state)) {
// Look for further children of the given NodeRelation.
DownRelations::const_iterator dri;
dri = node->_children.find(_graph_type);
if (dri != node->_children.end()) {
// Here are some!
const DownRelationPointers &drp = (*dri).second;
// Now visit each of the children in turn.
DownRelationPointers::const_iterator drpi;
for (drpi = drp.begin(); drpi != drp.end(); ++drpi) {
traverse(*drpi, state, level_state);
}
}
}
}