#include "Visitor.h" #include "X3DComponentVisitor.h" #include "AbstractVisitor.h" #include "SFType.h" using namespace X3DTK; using namespace std; Visitor::Visitor() : X3DActor() { SFType::addVisitor(this); setComponentVisitor(new AbstractVisitor()); } Visitor::~Visitor() { if (autoDelete) for (list::iterator it = _componentList.begin(); it != _componentList.end(); ++it) { (*it)->removeOneActor(); if ((*it)->getActorNumber() == 0) delete *it; } SFType::removeVisitor(this); } void Visitor::setComponentVisitor(X3DComponentVisitor *component) { //replace the equivalent component. X3DComponentVisitor *replacedComponent = 0; bool replaced = false; for (list::iterator it = _componentList.begin(); it != _componentList.end(); ++it) { if ((*it)->getComponent()->getEncodedName() == component->getComponent()->getEncodedName()) { replacedComponent = *it; *it = component; replacedComponent->removeOneActor(); component->addOneActor(); replaced = true; } } if (replacedComponent == component) return; if (!replaced) { _componentList.push_back(component); component->addOneActor(); } //remove replaced component. if ((autoDelete) && (replacedComponent != 0) && (replacedComponent->getActorNumber() == 0)) delete replacedComponent; //iterating the types. for (unsigned int id = 0; id < _visitingArray.size(); ++id) { /// If the _visitingArray[id] == 0, then it means that the node of id id is not met. if (_visitingArray[id] != 0) { _visitingArray[id]->setEnterFunction(getEnterFunctionOf(SFType::getTypeOfId(id))); _visitingArray[id]->setWalkOnFunction(getWalkOnFunctionOf(SFType::getTypeOfId(id))); _visitingArray[id]->setLeaveFunction(getLeaveFunctionOf(SFType::getTypeOfId(id))); } } } void Visitor::reset() { //remove components if (autoDelete) for (list::iterator it = _componentList.begin(); it != _componentList.end(); ++it) { (*it)->removeOneActor(); if ((*it)->getActorNumber() == 0) delete *it; } _componentList.clear(); } void Visitor::addType(const SFType *type) { if ((int)_visitingArray.size() <= type->getId()) _visitingArray.resize(type->getId() + 1); _visitingArray[type->getId()] = new VisitingFunctions(getEnterFunctionOf(type), getWalkOnFunctionOf(type), getLeaveFunctionOf(type)); } EnterFunction *Visitor::getEnterFunctionOf(const SFType *type) const { SFType *t = (SFType *)type; //searching the enter function. EnterFunction *EF = 0; while (t != 0) { for (list::const_iterator it = _componentList.begin(); it != _componentList.end(); ++it) { EF = (*it)->getEnterFunctionOf(t); if (EF != 0) break; } if (EF != 0) break; t = t->getParent(); } return EF; } WalkOnFunction *Visitor::getWalkOnFunctionOf(const SFType *type) const { SFType *t = (SFType *)type; //searching the walkOn function. WalkOnFunction *WF = 0; while (t != 0) { for (list::const_iterator it = _componentList.begin(); it != _componentList.end(); ++it) { WF = (*it)->getWalkOnFunctionOf(t); if (WF != 0) break; } if (WF != 0) break; t = t->getParent(); } return WF; } LeaveFunction *Visitor::getLeaveFunctionOf(const SFType *type) const { SFType *t = (SFType *)type; //searching the leave function. LeaveFunction *LF = 0; while (t != 0) { for (list::const_iterator it = _componentList.begin(); it != _componentList.end(); ++it) { LF = (*it)->getLeaveFunctionOf(t); if (LF != 0) break; } if (LF != 0) break; t = t->getParent(); } return LF; } namespace X3DTK { Visitor *joinVisitors(Visitor *N0, Visitor *N1) { Visitor *N = new Visitor(); for (list::const_iterator i = N0->_componentList.begin(); i != N0->_componentList.end(); ++i) N->setComponentVisitor(*i); for (list::const_iterator j = N1->_componentList.begin(); j != N1->_componentList.end(); ++j) N->setComponentVisitor(*j); return N; } }