00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00026 #include <archon/x3d/server/event.H>
00027 #include <archon/x3d/server/scene.H>
00028
00029 namespace Archon
00030 {
00031 namespace X3D
00032 {
00033 void Route::cascadeEvent(const Event *e) const
00034 {
00035 try
00036 {
00037 Ref<NodeBase> n = targetNode.getRef();
00038 targetField->set(n.get(), e, true);
00039 }
00040 catch(ForwardDestroyedException &) {}
00041 }
00042
00043 Ref<NodeBase> Route::getSourceNode() const
00044 {
00045 return sourceNode.getRef();
00046 }
00047
00048 const FieldBase *Route::getSourceField() const
00049 {
00050 return sourceField;
00051 }
00052
00062 void Route::add(Ref<NodeBase> sourceNode, const FieldBase *sourceField,
00063 Ref<NodeBase> targetNode, const FieldBase *targetField)
00064 throw(AccessException, TypeException, ContextException)
00065 {
00066
00067 if(!sourceField->getIsEventSource() ||
00068 !targetField->getIsEventTarget()) ARCHON_THROW(AccessException);
00069
00070
00071 if(sourceNode == targetNode && sourceField == targetField) return;
00072
00073
00074 const FieldType *fieldType = sourceField->getType();
00075 if(fieldType != targetField->getType()) ARCHON_THROW(TypeException);
00076
00077
00078 if(const NodeFieldBase *sourceNodeField =
00079 dynamic_cast<const NodeFieldBase *>(sourceField))
00080 {
00081 const NodeFieldBase *targetNodeField =
00082 dynamic_cast<const NodeFieldBase *>(targetField);
00083 if(!sourceNodeField->getNodeType()->
00084 isDerivedFrom(targetNodeField->getNodeType()))
00085 ARCHON_THROW(TypeException);
00086 }
00087
00088 try
00089 {
00090 Ref<ExecutionContext> context = sourceNode->context.getRef();
00091 if(context != targetNode->context.getRef())
00092 ARCHON_THROW(ContextException);
00093
00094 Route *r = new Route(sourceNode, sourceField, targetNode, targetField);
00095 Ref<RouteTail> t(dynamic_cast<RouteTail *>(r));
00096 Ref<RouteHead> h(dynamic_cast<RouteHead *>(r));
00097 if(sourceField->addRoute(sourceNode.get(), t.get()))
00098 {
00099 targetNode->realize();
00100 targetNode->addRouteTarget(h);
00101 context->add(r);
00102 }
00103 }
00104 catch(ForwardDestroyedException &) {}
00105 }
00106
00107 bool Route::del(Ref<NodeBase> sourceNode, const FieldBase *sourceField,
00108 Ref<NodeBase> targetNode, const FieldBase *targetField)
00109 throw(ContextException)
00110 {
00111 if(sourceNode->context != targetNode->context)
00112 ARCHON_THROW(ContextException);
00113 Route r(sourceNode, sourceField, targetNode, targetField);
00114 return sourceField->delRouteMatch(sourceNode.get(), &r);
00115 }
00116
00117 void Route::refDispose(Mutex::Lock &l)
00118 {
00119 if(getTailCountNoLock() == 0)
00120 {
00121 if(getHeadCountNoLock() == 0)
00122 {
00123 l.release();
00124 try
00125 {
00126 sourceNode->context->remove(this);
00127 }
00128 catch(ForwardDestroyedException &) {}
00129 delete this;
00130 return;
00131 }
00132 Ref<RouteHead> h(this, RefNoLockTag());
00133 l.release();
00134 try
00135 {
00136 targetNode->removeRouteTarget(h);
00137 }
00138 catch(ForwardDestroyedException &) {}
00139 return;
00140 }
00141 Ref<RouteTail> t(this, RefNoLockTag());
00142 l.release();
00143 try
00144 {
00145 Ref<NodeBase> n = sourceNode.getRef();
00146 sourceField->delRoute(n.get(), t.get());
00147 }
00148 catch(ForwardDestroyedException &) {}
00149 }
00150
00151 Route::~Route() {}
00152
00153 Route::Route(Ref<NodeBase> sourceNode, const FieldBase *sourceField,
00154 Ref<NodeBase> targetNode, const FieldBase *targetField):
00155 RouteTail(sourceNode, sourceField),
00156 RouteHead(targetNode, targetField)
00157 {
00158 }
00159
00160 bool Route::match(const RouteTail *r) const
00161 {
00162 const Route *s = dynamic_cast<const Route *>(r);
00163 return s && s->targetNode == targetNode &&
00164 s->targetField == targetField;
00165 }
00166 }
00167 }