custom_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_CUSTOM_FIELD_H
00021 #define ARCHON_X3D_CUSTOM_FIELD_H
00022 
00023 /*
00024  * \file
00025  *
00026  *  Definition of custom fields as used in scripts.
00027  */
00028 
00029 #include <archon/x3d/server/field_type.H>
00030 // #include <archon/x3d/server/dump.H>
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; // Index into CustomFieldNode::customFields
00060 
00061       // Overriding from FieldBase
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       // Overriding from FieldBase
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       // Overriding from FieldBase
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       // Overriding from NodeBase
00135       // string dumpFields(int level) const;
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       // Overriding from NodeBase
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       // Overriding from FieldBase
00172       Ref<ValueBase> get(const NodeBase *) const
00173       {
00174         return new SimpleValue<T>(this->getType(), value);
00175       }
00176 
00177       // Overriding from FieldBase
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       // Overriding from FieldBase
00198       bool changedSince(const NodeBase *, const Time &t) const
00199       {
00200         return timestamp >= t;
00201       }
00202 
00203       // Overriding from FieldBase
00204       /*
00205       string dump(const NodeBase *, int level) const
00206       {
00207         return string(2*level, ' ') +
00208           this->getName() + " " + dumpValue(value) + "\n";
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       // Overriding from FieldBase
00236       Ref<ValueBase> get(const NodeBase *) const
00237       {
00238         return new SimpleValue<V>(this->getType(), value);
00239       }
00240 
00241       // Overriding from FieldBase
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       // Overriding from SequenceFieldBase
00262       unsigned getSize(const NodeBase *) const
00263       {
00264         return value.size();
00265       }
00266 
00267       // Overriding from SequenceFieldBase
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       // Overriding from SequenceFieldBase
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       // Overriding from SequenceFieldBase
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       // Overriding from SequenceFieldBase
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       // Overriding from FieldBase
00348       bool changedSince(const NodeBase *, const Time &t) const
00349       {
00350         return timestamp >= t;
00351       }
00352 
00353       // Overriding from FieldBase
00354       /*
00355       string dump(const NodeBase *, int level) const
00356       {
00357         return string(2*level, ' ') +
00358           this->getName() + " " + dumpValue(value) + "\n";
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       // Overriding from FieldBase
00385       Ref<ValueBase> get(const NodeBase *) const
00386       {
00387         return new NodeValue(SFNode::type, value.get());
00388       }
00389 
00390       // Overriding from FieldBase
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       // Overriding from NodeFieldBase
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       // Overriding from FieldBase
00442       bool changedSince(const NodeBase *, const Time &t) const
00443       {
00444         return timestamp >= t || value->changedSince(t);
00445       }
00446 
00447       // Overriding from FieldBase
00448       /*
00449       string dump(const NodeBase *, int level) const
00450       {
00451         return string(2*level, ' ') + this->getName() +
00452           (value ? "\n" + value->dump(level+1) : string(" NULL\n"));
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       // Overriding from FieldBase
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       // Overriding from SequenceFieldBase
00523       unsigned getSize(const NodeBase *) const
00524       {
00525         return value.size();
00526       }
00527 
00528       // Overriding from SequenceFieldBase
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       // Overriding from SequenceFieldBase
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       // Overriding from SequenceFieldBase
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       // Overriding from SequenceFieldBase
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       // Overriding from NodeFieldBase
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       // Overriding from FieldBase
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       // Overriding from FieldBase
00661       /*
00662       string dump(const NodeBase *, int level) const
00663       {
00664         string indent(2*level, ' ');
00665         string s = indent + this->getName();
00666         if(!value.size()) return s + " []\n";
00667         s += "\n";
00668         indent + "[\n";
00669         for(unsigned i=0; i<value.size(); ++i)
00670         {
00671           const C *child = value[i].get();
00672           s += child->dump(level+1);
00673         }
00674         return s + indent + "]\n";
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

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