00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef ARCHON_X3D_CUSTOM_FIELD_H
00021 #define ARCHON_X3D_CUSTOM_FIELD_H
00022
00023
00024
00025
00026
00027
00028
00029 #include <archon/x3d/server/field_type.H>
00030
00031 #include <archon/x3d/server/type.H>
00032 #include <archon/x3d/server/event.H>
00033 #include <archon/x3d/server/node.H>
00034
00035 namespace Archon
00036 {
00037 namespace X3D
00038 {
00039 using namespace Archon::Math;
00040
00041 struct Parser;
00042
00043 struct CustomFieldBase: virtual RefObjectBase, virtual FieldBase
00044 {
00045 int getIndex() const { return index; }
00046
00047 protected:
00048 CustomFieldBase(int index, const NodeBase *containingNode):
00049 index(index)
00050 {
00051 const NodeType *t = containingNode->getType();
00052 unsigned long j = t->getNumberOfImmediateFields();
00053 j += index;
00054 j <<= NodeType::maxIndexBits;
00055 j |= t->getIndex();
00056 id = j;
00057 }
00058
00059 const int index;
00060
00061
00062 bool addRoute(NodeBase *, const RouteTail *r) const
00063 {
00064 CustomFieldBase *f =
00065 const_cast<CustomFieldBase *>(this);
00066 return f->eventSource.addRoute(r);
00067 }
00068
00069
00070 void delRoute(NodeBase *, const RouteTail *r) const
00071 {
00072 CustomFieldBase *f =
00073 const_cast<CustomFieldBase *>(this);
00074 f->eventSource.delRoute(r);
00075 }
00076
00077
00078 bool delRouteMatch(NodeBase *, const RouteTail *r) const
00079 {
00080 CustomFieldBase *f =
00081 const_cast<CustomFieldBase *>(this);
00082 return f->eventSource.delRouteMatch(r);
00083 }
00084
00085 protected:
00086 EventSource eventSource;
00087 Time timestamp;
00088 };
00089
00100 struct CustomFieldNode: virtual NodeBase
00101 {
00106 bool addCustomField(Ref<CustomFieldBase>) throw(RealizedException);
00107
00114 unsigned getNumberOfCustomFields() const
00115 {
00116 Mutex::Lock l(mutex);
00117 return customFields.size();
00118 }
00119
00120 Ref<CustomFieldBase> getCustomField(unsigned index) const
00121 {
00122 Mutex::Lock l(mutex);
00123 if(index >= customFields.size()) return 0;
00124 return customFields[index];
00125 }
00129 Ref<CustomFieldBase> getCustomFieldNoLock(unsigned index) const
00130 {
00131 return customFields[index];
00132 }
00133
00134
00135
00136
00137 protected:
00138 CustomFieldNode() {}
00139
00140 vector<Ref<CustomFieldBase> > customFields;
00141
00142 template<typename T> friend struct SimpleCustomField;
00143 template<typename T> friend struct SimpleSeqCustomField;
00144 template<typename C> friend struct NodeCustomField;
00145 template<typename C> friend struct NodeSequenceCustomField;
00146
00152 virtual void handleEvent(int fieldIndex, Time timestamp) = 0;
00153
00154 private:
00155
00156 const FieldBase *lookupField(string name) const;
00157 };
00158
00159
00160 template<typename T>
00161 struct SimpleCustomField: CustomFieldBase
00162 {
00163 SimpleCustomField(const NodeBase *containingNode,
00164 int index, string name, const FieldType *type,
00165 bool isEventTarget, bool isEventSource,
00166 const T &v):
00167 FieldBase(name, type, isEventTarget, isEventSource),
00168 CustomFieldBase(index, containingNode),
00169 value(v) {}
00170
00171
00172 Ref<ValueBase> get(const NodeBase *) const
00173 {
00174 return new SimpleValue<T>(this->getType(), value);
00175 }
00176
00177
00178 void set(NodeBase *n, const Event *e, bool cascade) const
00179 {
00180 const SimpleValueBase *val =
00181 dynamic_cast<const SimpleValueBase *>(e->value.get());
00182 if(!val) ARCHON_THROW1(InternalException,
00183 "SimpleCustomField::set: "
00184 "Value/Field type inconsistency");
00185 CustomFieldNode *m = dynamic_cast<CustomFieldNode *>(n);
00186 if(!m) ARCHON_THROW1(InternalException,
00187 "SimpleCustomField::set: "
00188 "Node was not a CustomFieldNode");
00189 SimpleCustomField *f =
00190 const_cast<SimpleCustomField *>(this);
00191 f->timestamp = e->time;
00192 f->value = *static_cast<const T *>(val->getValuePtr());
00193 if(cascade && isEventTarget) m->handleEvent(index, e->time);
00194 if(cascade) eventSource.cascadeEvent(e);
00195 }
00196
00197
00198 bool changedSince(const NodeBase *, const Time &t) const
00199 {
00200 return timestamp >= t;
00201 }
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212 void forwardClear(NodeBase *n) const
00213 {
00214 SimpleCustomField *f =
00215 const_cast<SimpleCustomField *>(this);
00216 f->eventSource.clear();
00217 }
00218
00219 private:
00220 T value;
00221 };
00222
00223 template<typename T>
00224 struct SimpleSeqCustomField: CustomFieldBase, SequenceFieldBase
00225 {
00226 typedef vector<T> V;
00227
00228 SimpleSeqCustomField(const NodeBase *containingNode,
00229 int index, string name, const FieldType *type,
00230 bool isEventTarget, bool isEventSource,
00231 const V &v):
00232 FieldBase(name, type, isEventTarget, isEventSource),
00233 CustomFieldBase(index, containingNode) {}
00234
00235
00236 Ref<ValueBase> get(const NodeBase *) const
00237 {
00238 return new SimpleValue<V>(this->getType(), value);
00239 }
00240
00241
00242 void set(NodeBase *n, const Event *e, bool cascade) const
00243 {
00244 const SimpleValueBase *val =
00245 dynamic_cast<const SimpleValueBase *>(e->value.get());
00246 if(!val) ARCHON_THROW1(InternalException,
00247 "SimpleCustomField::set: "
00248 "Value/Field type inconsistency");
00249 CustomFieldNode *m = dynamic_cast<CustomFieldNode *>(n);
00250 if(!m) ARCHON_THROW1(InternalException,
00251 "SimpleCustomField::set: "
00252 "Node was not a CustomFieldNode");
00253 SimpleSeqCustomField *f =
00254 const_cast<SimpleSeqCustomField *>(this);
00255 f->timestamp = e->time;
00256 f->value = *static_cast<const V *>(val->getValuePtr());
00257 if(cascade && isEventTarget) m->handleEvent(index, e->time);
00258 if(cascade) eventSource.cascadeEvent(e);
00259 }
00260
00261
00262 unsigned getSize(const NodeBase *) const
00263 {
00264 return value.size();
00265 }
00266
00267
00268 Ref<ValueBase> getAt(const NodeBase *, unsigned i) const
00269 {
00270 if(i >= value.size())
00271 ARCHON_THROW1(InternalException, "Index out of range");
00272 return new SimpleValue<T>(this->getType()->getSingleType(), value[i]);
00273 }
00274
00275
00276 void setAt(NodeBase *n, const ValueBase *v,
00277 unsigned i, Time time, bool cascade) const
00278 {
00279 if(i >= value.size())
00280 ARCHON_THROW1(InternalException, "Index out of range");
00281 const SimpleValue<T> *w =
00282 dynamic_cast<const SimpleValue<T> *>(v);
00283 if(!w) ARCHON_THROW1(InternalException, "Value/Field type mismatch");
00284 CustomFieldNode *m = dynamic_cast<CustomFieldNode *>(n);
00285 if(!m) ARCHON_THROW1(InternalException, "Not a CustomFieldNode");
00286 SimpleSeqCustomField *f =
00287 const_cast<SimpleSeqCustomField *>(this);
00288 f->timestamp = time;
00289 f->value[i] = w->value;
00290 if(cascade && isEventTarget) m->handleEvent(index, time);
00291 if(cascade)
00292 {
00293 Ref<ValueBase> x = get(n);
00294 SimpleValue<V> *s = dynamic_cast<SimpleValue<V> *>(x.get());
00295 if(!s) ARCHON_THROW1(InternalException, "Wrong value type");
00296 Event e(s, time);
00297 eventSource.cascadeEvent(&e);
00298 }
00299 }
00300
00301
00302 void add(NodeBase *n, const ValueBase *v, Time time, bool cascade) const
00303 {
00304 const SimpleValue<T> *w =
00305 dynamic_cast<const SimpleValue<T> *>(v);
00306 if(!w) ARCHON_THROW1(InternalException, "Value/Field type mismatch");
00307 CustomFieldNode *m = dynamic_cast<CustomFieldNode *>(n);
00308 if(!m) ARCHON_THROW1(InternalException, "Not a CustomFieldNode");
00309 SimpleSeqCustomField *f =
00310 const_cast<SimpleSeqCustomField *>(this);
00311 f->timestamp = time;
00312 f->value.push_back(w->value);
00313 if(cascade && isEventTarget) m->handleEvent(index, time);
00314 if(cascade)
00315 {
00316 Ref<ValueBase> x = get(n);
00317 SimpleValue<V> *s = dynamic_cast<SimpleValue<V> *>(x.get());
00318 if(!s) ARCHON_THROW1(InternalException, "Wrong value type");
00319 Event e(s, time);
00320 eventSource.cascadeEvent(&e);
00321 }
00322 }
00323
00324
00325 void remove(NodeBase *n, const ValueBase *v, Time time, bool cascade) const
00326 {
00327 const SimpleValue<T> *w =
00328 dynamic_cast<const SimpleValue<T> *>(v);
00329 if(!w) ARCHON_THROW1(InternalException, "Value/Field type mismatch");
00330 CustomFieldNode *m = dynamic_cast<CustomFieldNode *>(n);
00331 if(!m) ARCHON_THROW1(InternalException, "Not a CustomFieldNode");
00332 SimpleSeqCustomField *f =
00333 const_cast<SimpleSeqCustomField *>(this);
00334 f->timestamp = time;
00335 std::remove(f->value.begin(), f->value.end(), w->value);
00336 if(cascade && isEventTarget) m->handleEvent(index, time);
00337 if(cascade)
00338 {
00339 Ref<ValueBase> x = get(n);
00340 SimpleValue<V> *s = dynamic_cast<SimpleValue<V> *>(x.get());
00341 if(!s) ARCHON_THROW1(InternalException, "Wrong value type");
00342 Event e(s, time);
00343 eventSource.cascadeEvent(&e);
00344 }
00345 }
00346
00347
00348 bool changedSince(const NodeBase *, const Time &t) const
00349 {
00350 return timestamp >= t;
00351 }
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362 void forwardClear(NodeBase *n) const
00363 {
00364 SimpleSeqCustomField *f =
00365 const_cast<SimpleSeqCustomField *>(this);
00366 f->eventSource.clear();
00367 }
00368
00369 private:
00370 V value;
00371 };
00372
00373 template<typename C>
00374 struct NodeCustomField: CustomFieldBase, NodeFieldBase
00375 {
00376 NodeCustomField(const NodeBase *containingNode,
00377 int index, string name, const NodeType *nodeType,
00378 bool isEventTarget, bool isEventSource,
00379 Ref<C> v):
00380 FieldBase(name, SFNode::type, isEventTarget, isEventSource),
00381 CustomFieldBase(index, containingNode),
00382 NodeFieldBase(nodeType), value(v) {}
00383
00384
00385 Ref<ValueBase> get(const NodeBase *) const
00386 {
00387 return new NodeValue(SFNode::type, value.get());
00388 }
00389
00390
00391 void set(NodeBase *n, const Event *e, bool cascade) const
00392 {
00393 const NodeValue *val =
00394 dynamic_cast<const NodeValue *>(e->value.get());
00395 if(!val) ARCHON_THROW1(InternalException,
00396 "NodeCustomField::set: "
00397 "Value/Field type inconsistency");
00398 C *v = dynamic_cast<C *>(val->value.get());
00399 if(!v && val->value.get())
00400 ARCHON_THROW1(InternalException,
00401 "NodeCustomField::set: "
00402 "Incompatible node");
00403 CustomFieldNode *m = dynamic_cast<CustomFieldNode *>(n);
00404 if(!m) ARCHON_THROW1(InternalException,
00405 "NodeCustomField::set: "
00406 "Node was not a CustomFieldNode");
00407 NodeCustomField *f =
00408 const_cast<NodeCustomField *>(this);
00409 f->timestamp = e->time;
00410 f->value = v;
00411 if(cascade && isEventTarget) m->handleEvent(index, e->time);
00412 if(cascade) eventSource.cascadeEvent(e);
00413 }
00414
00415
00416 bool inject(NodeBase *n, NodeBase *child, Time time, bool cascade) const
00417 {
00418 C *c = dynamic_cast<C *>(child);
00419 if(!c && child)
00420 ARCHON_THROW1(InternalException,
00421 "NodeCustomField::inject: "
00422 "Incompatible node");
00423 CustomFieldNode *m = dynamic_cast<CustomFieldNode *>(n);
00424 if(!m) ARCHON_THROW1(InternalException,
00425 "NodeCustomField::inject: "
00426 "Node was not a CustomFieldNode");
00427 NodeCustomField *f =
00428 const_cast<NodeCustomField *>(this);
00429 if(f->value) return false;
00430 f->timestamp = time;
00431 f->value = c;
00432 if(cascade && isEventTarget) m->handleEvent(index, time);
00433 if(cascade)
00434 {
00435 Event e(new NodeValue(SFNode::type, c), time);
00436 eventSource.cascadeEvent(&e);
00437 }
00438 return true;
00439 }
00440
00441
00442 bool changedSince(const NodeBase *, const Time &t) const
00443 {
00444 return timestamp >= t || value->changedSince(t);
00445 }
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456 void forwardClear(NodeBase *) const
00457 {
00458 NodeCustomField *f =
00459 const_cast<NodeCustomField *>(this);
00460 f->value.reset();
00461 f->eventSource.clear();
00462 }
00463
00464 private:
00465 Ref<C> value;
00466 };
00467
00468 template<typename C>
00469 struct NodeSequenceCustomField: CustomFieldBase, NodeSequenceFieldBase
00470 {
00471 NodeSequenceCustomField(const NodeBase *containingNode,
00472 int index, string name, const NodeType *nodeType,
00473 bool isEventTarget, bool isEventSource,
00474 const vector<Ref<C> > &v):
00475 FieldBase(name, MFNode::type, isEventTarget, isEventSource),
00476 CustomFieldBase(index, containingNode),
00477 NodeSequenceFieldBase(nodeType), value(v) {}
00478
00479
00480 void set(NodeBase *n, const Event *e, bool cascade) const
00481 {
00482 const NodeSequenceValue *val =
00483 dynamic_cast<const NodeSequenceValue *>(e->value.get());
00484 if(!val) ARCHON_THROW1(InternalException,
00485 "NodeSequenceCustomField::set: "
00486 "Value/Field type inconsistency");
00487 vector<Ref<C> > v;
00488 v.resize(val->value.size());
00489 for(unsigned i=0; i<val->value.size(); ++i)
00490 {
00491 NodeBase *m = val->value[i].get();
00492 if(!m) ARCHON_THROW1(InternalException,
00493 "NodeSequenceCustomField::set: "
00494 "Null node is illegal");
00495 v[i] = dynamic_cast<C *>(m);
00496 if(!v[i])
00497 ARCHON_THROW1(InternalException,
00498 "NodeSequenceCustomField::set: "
00499 "Incompatible node");
00500 }
00501 CustomFieldNode *m = dynamic_cast<CustomFieldNode *>(n);
00502 if(!m) ARCHON_THROW1(InternalException,
00503 "SimpleCustomField::set: "
00504 "Node was not a CustomFieldNode");
00505 NodeSequenceCustomField *f =
00506 const_cast<NodeSequenceCustomField *>(this);
00507 f->timestamp = e->time;
00508 f->value = v;
00509 if(cascade && isEventTarget) m->handleEvent(index, e->time);
00510 if(cascade) eventSource.cascadeEvent(e);
00511 }
00512
00513
00514 Ref<ValueBase> get(const NodeBase *) const
00515 {
00516 Ref<NodeSequenceValue> v = new NodeSequenceValue(MFNode::type);
00517 v->value.resize(value.size());
00518 for(unsigned i=0; i<value.size(); ++i) v->value[i] = value[i];
00519 return v;
00520 }
00521
00522
00523 unsigned getSize(const NodeBase *) const
00524 {
00525 return value.size();
00526 }
00527
00528
00529 Ref<ValueBase> getAt(const NodeBase *, unsigned i) const
00530 {
00531 if(i >= value.size())
00532 ARCHON_THROW1(InternalException, "Index out of range");
00533 return new NodeValue(SFNode::type, value[i].get());
00534 }
00535
00536
00537 void setAt(NodeBase *n, const ValueBase *v,
00538 unsigned i, Time time, bool cascade) const
00539 {
00540 if(i >= value.size())
00541 ARCHON_THROW1(InternalException, "Index out of range");
00542 const NodeValue *w =
00543 dynamic_cast<const NodeValue *>(v);
00544 if(!w) ARCHON_THROW1(InternalException, "Value/Field type mismatch");
00545 C *c = dynamic_cast<C *>(w->value.get());
00546 if(!c) ARCHON_THROW1(InternalException, "Incompatible node type");
00547 CustomFieldNode *m = dynamic_cast<CustomFieldNode *>(n);
00548 if(!m) ARCHON_THROW1(InternalException, "Not a CustomFieldNode");
00549
00550 NodeSequenceCustomField *f =
00551 const_cast<NodeSequenceCustomField *>(this);
00552 f->timestamp = time;
00553 f->value[i].reset(c);
00554 if(cascade && isEventTarget) m->handleEvent(index, time);
00555 if(cascade)
00556 {
00557 Ref<ValueBase> x = get(n);
00558 NodeSequenceValue *s =
00559 dynamic_cast<NodeSequenceValue *>(x.get());
00560 if(!s) ARCHON_THROW1(InternalException, "Wrong value type");
00561 Event e(s, time);
00562 eventSource.cascadeEvent(&e);
00563 }
00564 }
00565
00566
00567 void add(NodeBase *n, const ValueBase *v, Time time, bool cascade) const
00568 {
00569 const NodeValue *w =
00570 dynamic_cast<const NodeValue *>(v);
00571 if(!w) ARCHON_THROW1(InternalException, "Value/Field type mismatch");
00572 C *c = dynamic_cast<C *>(w->value.get());
00573 if(!c) ARCHON_THROW1(InternalException, "Incompatible node type");
00574 CustomFieldNode *m = dynamic_cast<CustomFieldNode *>(n);
00575 if(!m) ARCHON_THROW1(InternalException, "Not a CustomFieldNode");
00576
00577 NodeSequenceCustomField *f =
00578 const_cast<NodeSequenceCustomField *>(this);
00579 f->timestamp = time;
00580 f->value.push_back(c);
00581 if(cascade && isEventTarget) m->handleEvent(index, time);
00582 if(cascade)
00583 {
00584 Ref<ValueBase> x = get(n);
00585 NodeSequenceValue *s =
00586 dynamic_cast<NodeSequenceValue *>(x.get());
00587 if(!s) ARCHON_THROW1(InternalException, "Wrong value type");
00588 Event e(s, time);
00589 eventSource.cascadeEvent(&e);
00590 }
00591 }
00592
00593
00594 void remove(NodeBase *n, const ValueBase *v, Time time, bool cascade) const
00595 {
00596 const NodeValue *w =
00597 dynamic_cast<const NodeValue *>(v);
00598 if(!w) ARCHON_THROW1(InternalException, "Value/Field type mismatch");
00599 C *c = dynamic_cast<C *>(w->value.get());
00600 if(!c) ARCHON_THROW1(InternalException, "Incompatible node type");
00601 CustomFieldNode *m = dynamic_cast<CustomFieldNode *>(n);
00602 if(!m) ARCHON_THROW1(InternalException, "Not a CustomFieldNode");
00603
00604 NodeSequenceCustomField *f =
00605 const_cast<NodeSequenceCustomField *>(this);
00606 f->timestamp = time;
00607 std::remove(f->value.begin(), f->value.end(), Ref<C>(c));
00608 if(cascade && isEventTarget) m->handleEvent(index, time);
00609 if(cascade)
00610 {
00611 Ref<ValueBase> x = get(n);
00612 NodeSequenceValue *s =
00613 dynamic_cast<NodeSequenceValue *>(x.get());
00614 if(!s) ARCHON_THROW1(InternalException, "Wrong value type");
00615 Event e(s, time);
00616 eventSource.cascadeEvent(&e);
00617 }
00618 }
00619
00620
00621
00622 bool inject(NodeBase *n, NodeBase *child, Time time, bool cascade) const
00623 {
00624 C *c = dynamic_cast<C *>(child);
00625 if(!c && child)
00626 ARCHON_THROW1(InternalException,
00627 "NodeCustomField::inject: "
00628 "Incompatible node");
00629 CustomFieldNode *m = dynamic_cast<CustomFieldNode *>(n);
00630 if(!m) ARCHON_THROW1(InternalException, "Not a CustomFieldNode");
00631 NodeSequenceCustomField *f =
00632 const_cast<NodeSequenceCustomField *>(this);
00633 f->timestamp = time;
00634 f->value.push_back(c);
00635 if(cascade && isEventTarget) m->handleEvent(index, time);
00636 if(cascade)
00637 {
00638 Ref<ValueBase> x = get(n);
00639 NodeSequenceValue *s =
00640 dynamic_cast<NodeSequenceValue *>(x.get());
00641 if(!s) ARCHON_THROW1(InternalException, "Wrong value type");
00642 Event e(s, time);
00643 eventSource.cascadeEvent(&e);
00644 }
00645 return true;
00646 }
00647
00648
00649 bool changedSince(const NodeBase *, const Time &t) const
00650 {
00651 if(timestamp >= t) return true;
00652 for(unsigned i=0; i<value.size(); ++i)
00653 {
00654 const C *c = value[i].get();
00655 if(c->changedSince(t)) return true;
00656 }
00657 return false;
00658 }
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678 void forwardClear(NodeBase *) const
00679 {
00680 NodeSequenceCustomField *f =
00681 const_cast<NodeSequenceCustomField *>(this);
00682 f->value.clear();
00683 f->eventSource.clear();
00684 }
00685
00686 private:
00687 vector<Ref<C> > value;
00688 };
00689 }
00690 }
00691
00692 #endif // ARCHON_X3D_CUSTOM_FIELD_H