00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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() {}
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
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
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