field.H

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 
00020 #ifndef ARCHON_X3D_PROXY_FIELD_H
00021 #define ARCHON_X3D_PROXY_FIELD_H
00022 
00023 #include <archon/x3d/proxy/node.H>
00024 #include <archon/x3d/proxy/event.H>
00025 
00026 namespace Archon
00027 {
00028   namespace X3D
00029   {
00030     namespace Proxy
00031     {
00032       template<typename> struct EventSource;
00033       template<typename> struct EventTarget;
00034 
00035       struct Field
00036       {
00037       protected:
00038         friend struct ExecutionContext;
00039 
00040         Field() {} // Dummy
00041         Field(NodeBase *s, unsigned long i): self(s), id(i) {}
00042 
00043         NodeBase *self;
00044         unsigned long id;
00045 
00046         template<typename T> static void checkDerivation(T *) {}
00047 
00048         template<typename F, typename G>
00049         static void registerInterest(EventSource<F> *f,
00050                                      EventHandler<G> *h, bool destroy)
00051         {
00052           if(false) { F *p; checkDerivation<G>(p); }
00053           f->self->registerFieldInterest(f->id, h, destroy);
00054         }
00055 
00056         template<typename C, typename D>
00057         static void registerInterest(EventSource<SFNode<C> > *f,
00058                                      EventHandler<SFNode<C> > *h, bool destroy)
00059         {
00060           if(false) { C *p; checkDerivation<D>(p); }
00061           f->self->registerFieldInterest(f->id, h, destroy);
00062         }
00063 
00064         template<typename C, typename D>
00065         static void registerInterest(EventSource<MFNode<C> > *f,
00066                                      EventHandler<MFNode<C> > *h, bool destroy)
00067         {
00068           if(false) { C *p; checkDerivation<D>(p); }
00069           f->self->registerFieldInterest(f->id, h, destroy);
00070         }
00071       };
00072 
00073       template<typename F> struct FieldGet: virtual Field
00074       {
00075         typedef typename F::Type T;
00076         T get() const
00077         {
00078           x3d::sai::Value_var w = self->fieldGet(id);
00079           T v;
00080           self->importValue(F::index, w,
00081                             reinterpret_cast<void *>(&v));
00082           return v;
00083         }
00084 
00085       protected:
00086         FieldGet() {}
00087       };
00088 
00089       template<typename C> struct FieldGet<SFNode<C> >: virtual Field
00090       {
00091         typedef typename SFNode<C>::Type T;
00092         T get() const
00093         {
00094           x3d::sai::Value_var w = self->fieldGet(id);
00095           Ref<NodeBase> v;
00096           self->importValue(SFNode<C>::index, w,
00097                             reinterpret_cast<void *>(&v));
00098           C *c = dynamic_cast<C *>(v.get());
00099           if(!c) ARCHON_THROW1(Session::ProtocolException,
00100                                "Incompatible node type");
00101           return c;
00102         }
00103 
00104       protected:
00105         FieldGet() {}
00106       };
00107 
00108       template<typename C> struct FieldGet<MFNode<C> >: virtual Field
00109       {
00110         typedef typename MFNode<C>::Type T;
00111         T get() const
00112         {
00113           x3d::sai::Value_var w = self->fieldGet(id);
00114           vector<Ref<NodeBase> > v;
00115           self->importValue(MFNode<C>::index, w,
00116                             reinterpret_cast<void *>(&v));
00117           vector<Ref<C> > u(v.size());
00118           for(unsigned i=0; i<v.size(); ++i)
00119           {
00120             C *c = dynamic_cast<C *>(v[i].get());
00121             if(!c) ARCHON_THROW1(Session::ProtocolException,
00122                                  "Incompatible node type");
00123             u[i].reset(c);
00124           }
00125           return u;
00126         }
00127 
00128       protected:
00129         FieldGet() {}
00130       };
00131 
00132       template<typename F> struct FieldSet: virtual Field
00133       {
00134         typedef typename F::ArgType A;
00135         void set(A v)
00136         {
00137           x3d::sai::Value w;
00138           self->exportValue(F::index,
00139                             reinterpret_cast<const void *>(&v), w);
00140           self->fieldSet(id, w);
00141         }
00142 
00143       protected:
00144         FieldSet() {}
00145       };
00146 
00147       template<typename C> struct FieldSet<SFNode<C> >: virtual Field
00148       {
00149         typedef typename SFNode<C>::ArgType A;
00150         void set(A v)
00151         {
00152           Ref<NodeBase> u = v;
00153           x3d::sai::Value w;
00154           self->exportValue(SFNode<C>::index,
00155                             reinterpret_cast<const void *>(&u), w);
00156           self->fieldSet(id, w);
00157         }
00158 
00159       protected:
00160         FieldSet() {}
00161       };
00162 
00163       template<typename C> struct FieldSet<MFNode<C> >: virtual Field
00164       {
00165         typedef typename MFNode<C>::ArgType A;
00166         void set(A v)
00167         {
00168           vector<Ref<NodeBase> > u(v.size());
00169           for(unsigned i=0; i<v.size(); ++i) u[i] = v[i];
00170           x3d::sai::Value w;
00171           self->exportValue(MFNode<C>::index,
00172                             reinterpret_cast<const void *>(&u), w);
00173           self->fieldSet(id, w);
00174         }
00175 
00176       protected:
00177         FieldSet() {}
00178       };
00179 
00180       template<typename F> struct FieldSeqGet: virtual FieldGet<F>
00181       {
00182         typedef typename F::Single SF;
00183         typedef typename SF::Type ST;
00184 
00185         ST getAt(unsigned long i) const
00186         {
00187           x3d::sai::Value_var w = this->self->fieldGetAt(this->id, i);
00188           ST v;
00189           this->self->importValue(SF::index, w,
00190                                   reinterpret_cast<void *>(&v));
00191           return v;
00192         }
00193 
00194       protected:
00195         FieldSeqGet() {}
00196       };
00197 
00198       template<typename C>
00199       struct FieldSeqGet<MFNode<C> >: virtual FieldGet<MFNode<C> >
00200       {
00201         typedef typename MFNode<C>::Single SF;
00202         typedef typename SF::Type ST;
00203 
00204         ST getAt(unsigned long i) const
00205         {
00206           x3d::sai::Value_var w = this->self->fieldGetAt(this->id, i);
00207           Ref<NodeBase> v;
00208           this->self->importValue(SF::index, w,
00209                                   reinterpret_cast<void *>(&v));
00210           C *c = dynamic_cast<C *>(v.get());
00211           if(!c) ARCHON_THROW1(Session::ProtocolException,
00212                                "Incompatible node type");
00213           return c;
00214         }
00215 
00216       protected:
00217         FieldSeqGet() {}
00218       };
00219 
00220       template<typename F> struct FieldSeqSet: virtual FieldSet<F>
00221       {
00222         typedef typename F::Single SF;
00223         typedef typename SF::ArgType SA;
00224 
00225         void setAt(SA v, unsigned long i)
00226         {
00227           x3d::sai::Value w;
00228           this->self->exportValue(SF::index,
00229                                   reinterpret_cast<const void *>(&v), w);
00230           this->self->fieldSetAt(this->id, w, i);
00231         }
00232 
00233         void add(SA v)
00234         {
00235           x3d::sai::Value w;
00236           this->self->exportValue(SF::index,
00237                                   reinterpret_cast<const void *>(&v), w);
00238           this->self->fieldAdd(this->id, w);
00239         }
00240 
00241         void remove(SA v)
00242         {
00243           x3d::sai::Value w;
00244           this->self->exportValue(SF::index,
00245                                   reinterpret_cast<const void *>(&v), w);
00246           this->self->fieldDel(this->id, w);
00247         }
00248 
00249       protected:
00250         FieldSeqSet() {}
00251       };
00252 
00253       template<typename C>
00254       struct FieldSeqSet<MFNode<C> >: virtual FieldSet<MFNode<C> >
00255       {
00256         typedef typename MFNode<C>::Single SF;
00257         typedef typename SF::ArgType SA;
00258 
00259         void setAt(SA v, unsigned long i)
00260         {
00261           Ref<NodeBase> u = v;
00262           x3d::sai::Value w;
00263           this->self->exportValue(SF::index,
00264                                   reinterpret_cast<const void *>(&u), w);
00265           this->self->fieldSetAt(this->id, w, i);
00266         }
00267 
00268         void add(SA v)
00269         {
00270           Ref<NodeBase> u = v;
00271           x3d::sai::Value w;
00272           this->self->exportValue(SF::index,
00273                             reinterpret_cast<const void *>(&u), w);
00274           this->self->fieldAdd(this->id, w);
00275         }
00276 
00277         void remove(SA v)
00278         {
00279           Ref<NodeBase> u = v;
00280           x3d::sai::Value w;
00281           this->self->exportValue(SF::index,
00282                             reinterpret_cast<const void *>(&u), w);
00283           this->self->fieldDel(this->id, w);
00284         }
00285 
00286       protected:
00287         FieldSeqSet() {}
00288       };
00289 
00290 
00291 
00292       template<typename F>
00293       struct EventSource: virtual FieldGet<F>
00294       {
00295         template<typename G>
00296         void registerInterest(Ref<EventHandler<G> > h)
00297         {
00298           Field::registerInterest(this, h.get(), false);
00299         }
00300 
00301         template<typename G>
00302         void unregisterInterest(Ref<EventHandler<G> > h)
00303         {
00304           Field::registerInterest(this, h.get(), true);
00305         }
00306       };
00307 
00308       template<typename F>
00309       struct EventTarget: virtual FieldSet<F>
00310       {
00311       };
00312 
00313 
00314 
00315       template<typename F>
00316       struct EventSourceSeq: FieldSeqGet<F>, EventSource<F> {};
00317 
00318       template<typename F>
00319       struct EventTargetSeq: FieldSeqSet<F>, EventTarget<F> {};
00320 
00321 
00322 
00323       // Single value fields
00324 
00325       template<typename F>
00326       struct InitializeOnly: FieldGet<F>, FieldSet<F>
00327       {
00328         typedef typename F::Type T;
00329         typedef typename F::ArgType A;
00330 
00331         InitializeOnly &operator=(A a) { set(a); return *this; }
00332         operator T() const { return this->get(); }
00333 
00334         InitializeOnly(NodeBase *s, unsigned long i): Field(s, i) {}
00335       };
00336 
00337       template<typename F>
00338       struct InputOnly: EventTarget<F>
00339       {
00340         typedef typename F::ArgType A;
00341 
00342         InputOnly &operator=(A a) { set(a); return *this; }
00343         void operator()(A a) { set(a); }
00344 
00345         InputOnly(NodeBase *s, unsigned long i): Field(s, i) {}
00346       };
00347 
00348       template<typename F>
00349       struct OutputOnly: EventSource<F>
00350       {
00351         typedef typename F::Type T;
00352 
00353         operator T() const { return this->get(); }
00354 
00355         OutputOnly(NodeBase *s, unsigned long i): Field(s, i) {}
00356       };
00357 
00358       template<typename F>
00359       struct InputOutput: EventSource<F>, EventTarget<F>
00360       {
00361         typedef typename F::Type T;
00362         typedef typename F::ArgType A;
00363 
00364         InputOutput &operator=(A a) { set(a); return *this; }
00365         operator T() const { return this->get(); }
00366 
00367         InputOutput(NodeBase *s, unsigned long i): Field(s, i) {}
00368       };
00369 
00370 
00371 
00372       // Sequence fields
00373 
00374       template<typename F>
00375       struct InitializeOnlySeq: FieldSeqGet<F>, FieldSeqSet<F>
00376       {
00377         typedef typename F::Type T;
00378         typedef typename F::ArgType A;
00379 
00380         InitializeOnlySeq &operator=(A a) { set(a); return *this; }
00381         operator T() const { return this->get(); }
00382 
00383         InitializeOnlySeq(NodeBase *s, unsigned long i): Field(s, i) {}
00384       };
00385 
00386       template<typename F>
00387       struct InputOnlySeq: EventTargetSeq<F>
00388       {
00389         typedef typename F::ArgType A;
00390 
00391         InputOnlySeq &operator=(A a) { set(a); return *this; }
00392         void operator()(A a) { set(a); }
00393 
00394         InputOnlySeq(NodeBase *s, unsigned long i): Field(s, i) {}
00395       };
00396 
00397       template<typename F>
00398       struct OutputOnlySeq: EventSourceSeq<F>
00399       {
00400         typedef typename F::Type T;
00401 
00402         operator T() const { return this->get(); }
00403 
00404         OutputOnlySeq(NodeBase *s, unsigned long i): Field(s, i) {}
00405       };
00406 
00407       template<typename F>
00408       struct InputOutputSeq: EventSourceSeq<F>, EventTargetSeq<F>
00409       {
00410         typedef typename F::Type T;
00411         typedef typename F::ArgType A;
00412 
00413         InputOutputSeq &operator=(A a) { set(a); return *this; }
00414         operator T() const { return this->get(); }
00415 
00416         InputOutputSeq(NodeBase *s, unsigned long i): Field(s, i) {}
00417       };
00418     }
00419   }
00420 }
00421 
00422 #endif // ARCHON_X3D_PROXY_FIELD_H

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