00001 #include "NodeVisitingProxy.h"
00002 #include "X3DComponentVisitor.h"
00003 #include "VisitingFunctions.h"
00004 #include "EnterFunction.h"
00005 #include "WalkOnFunction.h"
00006 #include "LeaveFunction.h"
00007 #include "RootVisitor.h"
00008 #include "Type.h"
00009 #include "X3DNode.h"
00010
00011 using namespace X3DTK;
00012 using namespace std;
00013
00014 NodeVisitingProxy::NodeVisitingProxy()
00015 {
00016 Type::addNodeProxy(this);
00017 setComponentVisitor(new RootVisitor());
00018 }
00019
00020 NodeVisitingProxy::~NodeVisitingProxy()
00021 {
00022 if (autoDelete)
00023 for (list<X3DComponentVisitor *>::iterator it = componentList_.begin(); it != componentList_.end(); ++it)
00024 {
00025 (*it)->removeOneProxy();
00026 if ((*it)->getProxyNumber() == 0)
00027 delete *it;
00028 }
00029
00030 Type::removeNodeProxy(this);
00031 }
00032
00033 void NodeVisitingProxy::setComponentVisitor(X3DComponentVisitor *component)
00034 {
00035
00036 X3DComponentVisitor *replacedComponent = 0;
00037 bool replaced = false;
00038 for (list<X3DComponentVisitor *>::iterator it = componentList_.begin(); it != componentList_.end(); ++it)
00039 {
00040 if ((*it)->getName() == component->getName())
00041 {
00042 replacedComponent = *it;
00043 *it = component;
00044 replacedComponent->removeOneProxy();
00045 component->addOneProxy();
00046 replaced = true;
00047 }
00048 }
00049
00050 if (replacedComponent == component)
00051 return;
00052
00053 if (!replaced)
00054 {
00055 componentList_.push_back(component);
00056 component->addOneProxy();
00057 }
00058
00059
00060 if ((autoDelete) && (replacedComponent != 0) && (replacedComponent->getProxyNumber() == 0))
00061 delete replacedComponent;
00062
00063
00064 for (unsigned int id = 0; id < visitingArray_.size(); ++id)
00065 {
00067 if (visitingArray_[id] != 0)
00068 {
00069 visitingArray_[id]->setEnterFunction(getEnterFunctionOf(Type::getTypeOfId(id)));
00070 visitingArray_[id]->setWalkOnFunction(getWalkOnFunctionOf(Type::getTypeOfId(id)));
00071 visitingArray_[id]->setLeaveFunction(getLeaveFunctionOf(Type::getTypeOfId(id)));
00072 }
00073 }
00074 }
00075
00076 void NodeVisitingProxy::enter(SFNode N) const
00077 {
00078 visitingArray_[N->getType()->getId()]->enter(N);
00079 }
00080
00081 bool NodeVisitingProxy::walkOn(SFNode N, SFNode child) const
00082 {
00083 return visitingArray_[N->getType()->getId()]->walkOn(N, child);
00084 }
00085
00086 void NodeVisitingProxy::leave(SFNode N) const
00087 {
00088 visitingArray_[N->getType()->getId()]->leave(N);
00089 }
00090
00091 void NodeVisitingProxy::reset()
00092 {
00093
00094 if (autoDelete)
00095 for (list<X3DComponentVisitor *>::iterator it = componentList_.begin(); it != componentList_.end(); ++it)
00096 {
00097 (*it)->removeOneProxy();
00098 if ((*it)->getProxyNumber() == 0)
00099 delete *it;
00100 }
00101
00102 componentList_.clear();
00103 }
00104
00105 void NodeVisitingProxy::addType(const Type *type)
00106 {
00107 if ((int)visitingArray_.size() <= type->getId())
00108 visitingArray_.resize(type->getId() + 1);
00109
00110 visitingArray_[type->getId()] = new VisitingFunctions(getEnterFunctionOf(type), getWalkOnFunctionOf(type), getLeaveFunctionOf(type));
00111 }
00112
00113 EnterFunction *NodeVisitingProxy::getEnterFunctionOf(const Type *type) const
00114 {
00115 Type *t = (Type *)type;
00116
00117
00118 EnterFunction *EF = 0;
00119 while (t != 0)
00120 {
00121 for (list<X3DComponentVisitor *>::const_iterator it = componentList_.begin(); it != componentList_.end(); ++it)
00122 {
00123 EF = (*it)->getEnterFunctionOf(t);
00124 if (EF != 0)
00125 break;
00126 }
00127 if (EF != 0)
00128 break;
00129
00130 t = t->getParent();
00131 }
00132
00133 return EF;
00134 }
00135
00136 WalkOnFunction *NodeVisitingProxy::getWalkOnFunctionOf(const Type *type) const
00137 {
00138 Type *t = (Type *)type;
00139
00140
00141 WalkOnFunction *WF = 0;
00142 while (t != 0)
00143 {
00144 for (list<X3DComponentVisitor *>::const_iterator it = componentList_.begin(); it != componentList_.end(); ++it)
00145 {
00146 WF = (*it)->getWalkOnFunctionOf(t);
00147 if (WF != 0)
00148 break;
00149 }
00150 if (WF != 0)
00151 break;
00152
00153 t = t->getParent();
00154 }
00155
00156 return WF;
00157 }
00158
00159 LeaveFunction *NodeVisitingProxy::getLeaveFunctionOf(const Type *type) const
00160 {
00161 Type *t = (Type *)type;
00162
00163
00164 LeaveFunction *LF = 0;
00165 while (t != 0)
00166 {
00167 for (list<X3DComponentVisitor *>::const_iterator it = componentList_.begin(); it != componentList_.end(); ++it)
00168 {
00169 LF = (*it)->getLeaveFunctionOf(t);
00170 if (LF != 0)
00171 break;
00172 }
00173 if (LF != 0)
00174 break;
00175
00176 t = t->getParent();
00177 }
00178
00179 return LF;
00180 }
00181
00182 NodeVisitingProxy *X3DTK::joinNodeVisitingProxies(NodeVisitingProxy *N0, NodeVisitingProxy *N1)
00183 {
00184 NodeVisitingProxy *N = new NodeVisitingProxy();
00185
00186 for (list<X3DComponentVisitor *>::const_iterator it = N0->componentList_.begin(); it != N0->componentList_.end(); ++it)
00187 N->setComponentVisitor(*it);
00188
00189 for (list<X3DComponentVisitor *>::const_iterator it = N1->componentList_.begin(); it != N1->componentList_.end(); ++it)
00190 N->setComponentVisitor(*it);
00191
00192 return N;
00193 }