00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00026 #include <archon/util/text.H>
00027
00028 #include <archon/x3d/server/field_type.H>
00029 #include <archon/x3d/server/field.H>
00030 #include <archon/x3d/server/network.H>
00031 #include <archon/x3d/server/scene.H>
00032 #include <archon/x3d/server/server.H>
00033
00034 namespace Archon
00035 {
00036 namespace X3D
00037 {
00038 const NodeType *UrlObject::type = 0;
00039 const NodeType *SubSceneNode::type = 0;
00040 const NodeType *Inline::type = 0;
00041 const NodeType *ApplicationLink::type = 0;
00042
00049 void initializeNetworkComponent()
00050 {
00051 vector<const FieldBase *> fields;
00052
00053
00054
00055 fields.push_back(newExposedField("url", MFString::type,
00056 &UrlObject::url,
00057 &UrlObject::urlAssign,
00058 &UrlObject::urlChanged,
00059 &UrlObject::urlStamp));
00060 UrlObject::type =
00061 NodeType::newAbstract("UrlObject", false, &fields);
00062
00063 fields.clear();
00064
00065
00066
00067
00068 SubSceneNode::type =
00069 NodeType::newAbstract("SubSceneNode", false, 0, ChildNode::type);
00070
00071
00072
00073
00074 fields.push_back(newExposedField("load", SFBool::type,
00075 &Inline::load,
00076 &Inline::loadAssign,
00077 &Inline::loadChanged,
00078 &Inline::loadStamp));
00079 Inline::type =
00080 NodeType::newConcrete("Inline", "children", Inline::instantiate,
00081 &fields, SubSceneNode::type, UrlObject::type);
00082 fields.clear();
00083
00084
00085
00086
00087 ApplicationLink::type =
00088 NodeType::newConcrete("ApplicationLink", "children", ApplicationLink::instantiate,
00089 0, SubSceneNode::type);
00090 fields.clear();
00091 }
00092
00093 UrlObject::UrlObject()
00094 {
00095 }
00096
00097 UrlObject::~UrlObject()
00098 {{
00099 killLoaderJob();
00100 }}
00101
00102 Ref<const Loader::Contents> UrlObject::getContents() const
00103 {
00104 Mutex::Lock l(loaderMutex);
00105 return contents;
00106 }
00107
00113 void UrlObject::addUri(string u, Time stamp)
00114 {
00115 const FieldBase *f = getType()->lookupField("url");
00116 if(!f) ARCHON_THROW1(InternalException,
00117 "Could not find field 'url' in UrlObject");
00118 {
00119 Mutex::Lock l(mutex);
00120 if(!isRealizedNoLock())
00121 {
00122 url.push_back(u);
00123 Event e(new SimpleValue<vector<string> >(MFString::type, url), stamp);
00124 f->set(this, &e, false);
00125 return;
00126 }
00127 }
00128 try
00129 {
00130 Mutex::Lock l(context->server->scenegraphMutex);
00131 url.push_back(u);
00132 Event e(new SimpleValue<vector<string> >(MFString::type, url), stamp);
00133 f->set(this, &e, true);
00134 }
00135 catch(ForwardDestroyedException &) {}
00136 }
00137
00149 void UrlObject::LoaderJob::kill()
00150 {
00151 Loader::Job::kill();
00152 Mutex::Lock l(mutex);
00153 urlObject = 0;
00154 }
00155
00173 void UrlObject::LoaderJob::onCompletion()
00174 {
00175 Ref<const Loader::Contents> c = getContents();
00176
00177 Mutex::Lock l(mutex);
00178
00179
00180 Ref<UrlObject> safeRef(urlObject, RefSafeIncTag());
00181 if(!safeRef) return;
00182
00183 urlObject->setContents(c);
00184
00185 l.release();
00186
00187 safeRef->onLoaded();
00188 }
00189
00198 void UrlObject::setContents(Ref<const Loader::Contents> c)
00199 {
00200 Mutex::Lock l(loaderMutex);
00201 contents = c;
00202 loaderJob = 0;
00203 }
00204
00216 void UrlObject::killLoaderJob()
00217 {
00218 Ref<LoaderJob> j;
00219 {
00220 Mutex::Lock l(loaderMutex);
00221 j = loaderJob;
00222 loaderJob.reset();
00223 contents.reset();
00224 }
00225 if(j) j->kill();
00226 }
00227
00228 void UrlObject::startLoading()
00229 {
00230 if(!url.size()) return;
00231 Ref<ExecutionContext> c;
00232 Ref<Loader> loader;
00233 Ref<AbstractFileServer> fileServer;
00234 try
00235 {
00236 c = context.getRef();
00237 loader = c->server->getLoader();
00238 fileServer = c->fileServer.getRef();
00239 }
00240 catch(ForwardDestroyedException &) { return; }
00241 if(!loader) return;
00242 Ref<LoaderJob> j =
00243 new LoaderJob(this, loader, c->getBaseUri(),
00244 url, getUriType(), fileServer);
00245 {
00246 Mutex::Lock l(loaderMutex);
00247 if(contents || loaderJob) return;
00248 loaderJob = j;
00249 loader->submitJob(j);
00250 }
00251 }
00252
00253 bool UrlObject::urlAssign(const vector<string> &v, const Time &t)
00254 {
00255 url = v;
00256 urlStamp = t;
00257
00258 killLoaderJob();
00259
00260
00261
00262
00263
00264
00265 clear();
00266
00267 if(mayStartLoading()) startLoading();
00268
00269 return true;
00270 }
00271
00272
00273 Ref<SceneBase> SubSceneNode::getSubScene() const
00274 {
00275 {
00276 Mutex::Lock l(mutex);
00277 if(!isRealizedNoLock()) return subScene;
00278 }
00279 try
00280 {
00281 Mutex::Lock l(context->server->scenegraphMutex);
00282 return subScene;
00283 }
00284 catch(ForwardDestroyedException &) { return 0; }
00285 }
00286
00287 void SubSceneNode::setSubScene(Ref<SceneBase> c)
00288 {
00289 if(c) c->realize();
00290 {
00291 Mutex::Lock l(mutex);
00292 if(!isRealizedNoLock())
00293 {
00294 subScene = c;
00295 return;
00296 }
00297 }
00298 try
00299 {
00300 Mutex::Lock l(context->server->scenegraphMutex);
00301 subScene = c;
00302 }
00303 catch(ForwardDestroyedException &) {}
00304 }
00305
00306 void SubSceneNode::refForwardDestroy()
00307 {
00308 Node::refForwardDestroy();
00309 subScene.reset();
00310 }
00311
00312
00313 bool Inline::loadAssign(const bool &v, const Time &t)
00314 {
00315 load = v;
00316 loadStamp = t;
00317
00318 if(load) startLoading();
00319
00320 return true;
00321 }
00322
00323 void Inline::onLoaded()
00324 {
00325 Ref<const Loader::Contents> c = getContents();
00326 if(!c) return;
00327 const Loader::X3DContents *d =
00328 dynamic_cast<const Loader::X3DContents *>(c.get());
00329 if(!d) ARCHON_THROW1(InternalException, "Wrong content type");
00330 setSubScene(d->rootScene);
00331 }
00332
00333 void Inline::clear()
00334 {
00335 subScene.reset();
00336 }
00337
00338
00339
00340
00341
00342
00343
00344
00345 }
00346 }