00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00026 #include <archon/x3d/server/context.H>
00027 #include <archon/x3d/server/server.H>
00028
00029 namespace Archon
00030 {
00031 namespace X3D
00032 {
00033 FrameDrivenNode::~FrameDrivenNode()
00034 {
00035 if(!isRealized()) return;
00036 try{ context->removeFrameDrivenNode(this); }
00037 catch(ForwardDestroyedException &) {}
00038 }
00039
00040 void FrameDrivenNode::onRealized()
00041 {
00042 context->addFrameDrivenNode(this);
00043 }
00044
00045 string AbstractFileServer::getNextId()
00046 {
00047 static Mutex m;
00048 static unsigned long n = 0;
00049 unsigned long v;
00050 {
00051 Mutex::Lock l(m);
00052 v = n++;
00053 }
00054 string s;
00055 for(unsigned i=0; i<8; ++i)
00056 {
00057 int d = int(v % 36ul);
00058 s = (d < 10 ? char('0'+d) : char('A'+(d-10))) + s;
00059 v /= 36ul;
00060 }
00061 return s;
00062 }
00063
00064 ExecutionContext::ExecutionContext(Ref<Server> server, Uri baseUri,
00065 Ref<AbstractFileServer> fileServer):
00066 server(server), fileServer(fileServer),
00067 baseUri(baseUri), realized(false)
00068 {
00069 }
00070
00071 ExecutionContext::~ExecutionContext()
00072 {
00073 if(!isRealized()) return;
00074 try { server->remove(this); }
00075 catch(ForwardDestroyedException &) {}
00076 }
00077
00078 void ExecutionContext::realize()
00079 {
00080 Mutex::Lock l(contextMutex);
00081 if(realized) return;
00082 realized = true;
00083 server->add(this);
00084 }
00085
00086 bool ExecutionContext::isRealized() const
00087 {
00088 Mutex::Lock l(contextMutex);
00089 return realized;
00090 }
00091
00092 Uri ExecutionContext::getBaseUri() const
00093 {
00094 Mutex::Lock l(contextMutex);
00095 return baseUri;
00096 }
00097
00098 Ref<NodeBase> ExecutionContext::lookupNode(string name) const
00099 {
00100 Mutex::Lock l(namedNodesMutex);
00101 map<string, NodeBase *>::const_iterator i=namedNodes.find(name);
00102 if(i==namedNodes.end()) return 0;
00103 return Ref<NodeBase>(i->second, RefSafeIncTag());
00104 }
00105
00106 void ExecutionContext::add(Route *r)
00107 {
00108 Mutex::Lock l(routesMutex);
00109 routes.push_back(r);
00110 }
00111
00112 void ExecutionContext::remove(Route *r)
00113 {
00114 Mutex::Lock l(routesMutex);
00115 routes.remove(r);
00116 }
00117
00118 void ExecutionContext::changeNodeName(NodeBase *n, string oldName, string newName)
00119 throw(NodeNameInUseException)
00120 {
00121 if(newName == oldName) return;
00122 Mutex::Lock l(namedNodesMutex);
00123 if(!newName.empty())
00124 {
00125 pair<string, NodeBase *> p(newName, n);
00126 if(!namedNodes.insert(p).second) ARCHON_THROW(NodeNameInUseException);
00127 }
00128 if(!oldName.empty()) namedNodes.erase(oldName);
00129 }
00130
00131 void ExecutionContext::addFrameDrivenNode(FrameDrivenNode *n)
00132 {
00133 Mutex::Lock l(frameDrivenNodesMutex);
00134 frameDrivenNodes.push_back(n);
00135 }
00136
00137 void ExecutionContext::removeFrameDrivenNode(FrameDrivenNode *n)
00138 {
00139 Mutex::Lock l(frameDrivenNodesMutex);
00140 frameDrivenNodes.remove(n);
00141 }
00142
00143 void ExecutionContext::tick()
00144 {
00145 list<Ref<FrameDrivenNode> > t;
00146 {
00147 Mutex::Lock l(frameDrivenNodesMutex);
00148 list<FrameDrivenNode *>::iterator i = frameDrivenNodes.begin();
00149 while(i != frameDrivenNodes.end())
00150 {
00151 Ref<FrameDrivenNode> r(*i, RefSafeIncTag());
00152 if(r) t.push_back(r);
00153 ++i;
00154 }
00155 }
00156 {
00157 list<Ref<FrameDrivenNode> >::iterator i = t.begin();
00158 while(i != t.end())
00159 {
00160 (*i)->tick();
00161 ++i;
00162 }
00163 }
00164 }
00165 }
00166 }
00167