00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef ARCHON_X3D_TYPE_H
00021 #define ARCHON_X3D_TYPE_H
00022
00029 #include <string>
00030 #include <map>
00031 #include <set>
00032 #include <list>
00033
00034 #include <archon/util/logger.H>
00035 #include <archon/util/ref.H>
00036 #include <archon/util/time.H>
00037
00038 #include <archon/x3d/server/exception.H>
00039
00040 namespace Archon
00041 {
00042 namespace X3D
00043 {
00044 using namespace std;
00045 using namespace Utilities;
00046
00047 struct ValueBase;
00048 struct Event;
00049 struct Route;
00050 struct RouteTail;
00051 struct NodeBase;
00052 struct NodeType;
00053
00054 struct ExecutionContext;
00055
00061 struct FieldType
00062 {
00063 FieldType(unsigned index, string name, const FieldType *singleType=0);
00064
00065 unsigned getIndex() const { return index; }
00066 string getName() const { return name; }
00067 bool getIsMultiple() const { return singleType; }
00068 const FieldType *getSingleType() const { return singleType; }
00069
00079 static const FieldType *lookup(string name);
00080
00081 private:
00082 unsigned index;
00083 string name;
00084 const FieldType *singleType;
00085 };
00086
00095 struct FieldBase
00096 {
00097 unsigned long getId() const { return id; }
00098 string getName() const { return name; }
00099 const FieldType *getType() const { return type; }
00100 bool getIsEventTarget() const { return isEventTarget; }
00101 bool getIsEventSource() const { return isEventSource; }
00102
00111 static const FieldBase *fetch(unsigned long fieldId, const NodeBase *n=0);
00112
00113 virtual Ref<ValueBase> get(const NodeBase *) const = 0;
00114
00133 virtual void set(NodeBase *, const Event *, bool cascade) const = 0;
00134
00141 virtual bool changedSince(const NodeBase *n, const Time &) const = 0;
00142
00151 virtual bool addRoute(NodeBase *, const RouteTail *) const = 0;
00152
00161 virtual void delRoute(NodeBase *, const RouteTail *) const = 0;
00162
00172 virtual bool delRouteMatch(NodeBase *, const RouteTail *) const = 0;
00173
00177
00178
00179 virtual ~FieldBase() {}
00180
00181 protected:
00182 FieldBase(string name, const FieldType *,
00183 bool isEventTarget, bool isEventSource);
00184
00194 FieldBase() {}
00195
00196 bool isEventTarget;
00197 bool isEventSource;
00198
00199 friend struct NodeBase;
00200 friend struct NodeType;
00201
00202 virtual void forwardClear(NodeBase *) const = 0;
00203
00204 unsigned long id;
00205 string name;
00206 const FieldType *type;
00207 };
00208
00209
00214 struct SequenceFieldBase: virtual FieldBase
00215 {
00216 virtual unsigned getSize(const NodeBase *) const = 0;
00217 virtual Ref<ValueBase> getAt(const NodeBase *, unsigned index) const = 0;
00218 virtual void setAt(NodeBase *, const ValueBase *, unsigned index, Time, bool cascade) const = 0;
00219 virtual void add(NodeBase *, const ValueBase *, Time, bool cascade) const = 0;
00220 virtual void remove(NodeBase *, const ValueBase *, Time, bool cascade) const = 0;
00221 };
00222
00223
00227 struct NodeFieldBase: virtual FieldBase
00228 {
00229 const NodeType *getNodeType() const { return nodeType; }
00230
00231 protected:
00232 NodeFieldBase(const NodeType *nodeType): nodeType(nodeType)
00233 {
00234 if(!nodeType)
00235 ARCHON_THROW1(InternalException,
00236 "Refering to uninitialized node type");
00237 }
00238
00239 private:
00240 friend struct NodeBase;
00241
00252 virtual bool inject(NodeBase *, NodeBase *childNode, Time, bool cascade) const = 0;
00253
00254 const NodeType *nodeType;
00255 };
00256
00260 struct NodeSequenceFieldBase: NodeFieldBase, SequenceFieldBase
00261 {
00262 protected:
00263 NodeSequenceFieldBase(const NodeType *nodeType):
00264 NodeFieldBase(nodeType) {}
00265 };
00266
00288 struct NodeType
00289 {
00290 static const int maxIndexBits = 7;
00291
00292 unsigned long getIndex() const { return index; }
00293
00297 static unsigned long getTotalNumber();
00298
00302 static const NodeType *get(unsigned long index);
00303
00309 static const NodeType *lookup(const string &nodeTypeName);
00310
00315 Ref<NodeBase> instantiate(BackRef<ExecutionContext> context) const;
00316
00320 string getName() const { return name; }
00321
00326 string getContainerField() const { return containerField; }
00327
00328 bool isAbstract() const { return !instanceMaker; }
00329 bool isVirtualBase() const { return virtualBase; }
00330 bool isInternalUseOnly() const { return internalUseOnly; }
00331 bool isDerivedFrom(const NodeType *baseType) const;
00332
00337 bool isUserInstantiable() const
00338 {
00339 return instanceMaker && !internalUseOnly;
00340 }
00341
00346 unsigned long getNumberOfImmediateFields() const
00347 {
00348 return fields.size();
00349 }
00350
00358 const FieldBase *getImmediateField(unsigned long fieldIndex) const
00359 {
00360 if(fieldIndex >= fields.size())
00361 ARCHON_THROW1(InternalException, "Index out of bound");
00362 return fields[fieldIndex];
00363 }
00364
00372 const FieldBase *lookupImmediateField(string name) const;
00373
00386 const FieldBase *lookupField(string name) const;
00387
00397 const NodeFieldBase *lookupNodeField(const NodeType *) const;
00398
00399
00400 static const NodeType *newAbstract(string name, bool virtualBase,
00401 const vector<const FieldBase *> *fields);
00402 static const NodeType *newAbstract(string name, bool virtualBase,
00403 const vector<const FieldBase *> *fields,
00404 const NodeType *derivedFrom1);
00405 static const NodeType *newAbstract(string name, bool virtualBase,
00406 const vector<const FieldBase *> *fields,
00407 const NodeType *derivedFrom1,
00408 const NodeType *derivedFrom2);
00409 static const NodeType *newConcrete(string name, string conatinerField,
00410 Ref<NodeBase> (*instanceMaker)(BackRef<ExecutionContext>),
00411 const vector<const FieldBase *> *fields,
00412 const NodeType *derivedFrom1);
00413 static const NodeType *newConcrete(string name, string conatinerField,
00414 Ref<NodeBase> (*instanceMaker)(BackRef<ExecutionContext>),
00415 const vector<const FieldBase *> *fields,
00416 const NodeType *derivedFrom1,
00417 const NodeType *derivedFrom2);
00418
00429 void setFields(const vector<const FieldBase *> *fields);
00430
00431
00435 bool changedSince(const NodeBase *, const Time &) const;
00436
00437 void describe(Logger *) const;
00438 static void describeAll(Logger *);
00439
00443
00444
00445 typedef vector<const NodeType *>::const_iterator iterator;
00446 iterator derivedFromBegin() const;
00447 iterator derivedFromEnd() const;
00448
00449 private:
00450 unsigned long index;
00451 string name;
00452 string containerField;
00453 bool virtualBase;
00454 bool internalUseOnly;
00455 vector<const NodeType *> derivedFrom;
00456 vector<const FieldBase *> fields;
00457 Ref<NodeBase> (*instanceMaker)(BackRef<ExecutionContext>);
00458 map<string, const FieldBase *> fieldMap;
00459
00460 void addFields(vector<pair<const FieldBase *, const NodeType *> > &) const;
00461 void initFieldMap(map<string, const FieldBase *> &,
00462 string, set<const NodeType *> &) const;
00463
00476 NodeType(string name, string containerField, bool virtualBase,
00477 const vector<const NodeType *> *derivedFrom,
00478 const vector<const FieldBase *> *fields,
00479 Ref<NodeBase> (*instanceMaker)(BackRef<ExecutionContext>));
00480
00481
00482 friend struct NodeBase;
00483
00484 void forwardClear(NodeBase *) const;
00485 };
00486 }
00487 }
00488
00489 #endif // ARCHON_X3D_TYPE_H