event.C

Go to the documentation of this file.
00001 /*
00002  * This file is part of the "Archon" framework.
00003  * (http://files3d.sourceforge.net)
00004  *
00005  * Copyright © 2002 by Kristian Spangsege and Brian Kristiansen.
00006  *
00007  * Permission to use, copy, modify, and distribute this software and
00008  * its documentation under the terms of the GNU General Public License is
00009  * hereby granted. No representations are made about the suitability of
00010  * this software for any purpose. It is provided "as is" without express
00011  * or implied warranty. See the GNU General Public License
00012  * (http://www.gnu.org/copyleft/gpl.html) for more details.
00013  *
00014  * The characters in this file are ISO8859-1 encoded.
00015  *
00016  * The documentation in this file is in "Doxygen" style
00017  * (http://www.doxygen.org).
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       // Field input/output capabilities
00067       if(!sourceField->getIsEventSource() ||
00068          !targetField->getIsEventTarget()) ARCHON_THROW(AccessException);
00069 
00070       // Self reference is redundant and must be ignored
00071       if(sourceNode == targetNode && sourceField == targetField) return;
00072 
00073       // Type conformance
00074       const FieldType *fieldType = sourceField->getType();
00075       if(fieldType != targetField->getType()) ARCHON_THROW(TypeException);
00076 
00077       // Injective node type restriction
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 }

Generated on Sun Jul 30 22:55:49 2006 for Archon by  doxygen 1.4.4