network.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/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       // UrlObject
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       // SubSceneNode
00067 
00068       SubSceneNode::type =
00069         NodeType::newAbstract("SubSceneNode", false, 0, ChildNode::type);
00070 
00071 
00072       // Inline
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       // ApplicationLink
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     {{ // The extra scope is needed to work around gcc3.2 bug #8287
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(); // Ask this job to abort
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       // Attempt to aquire a "safe" reference
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        * Give the derived node a chance to clean up any data
00262        * produced from the old URI contents such as textures and
00263        * script engines.
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     string ApplicationLink::dump(int level) const
00340     {
00341       if(!subScene) return "";
00342       return subScene->dump(level);
00343     }
00344     */
00345   }
00346 }

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