00001
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00028
00030
00031 #ifndef __H3DNODEDATABSE_H__
00032 #define __H3DNODEDATABSE_H__
00033
00034 #include "H3DApi.h"
00035 #include "Field.h"
00036 #include <iostream>
00037 #include <string>
00038 #include <map>
00039
00040 using namespace std;
00041
00042
00044 #define FIELDDB_ELEMENT( base, field, access ) \
00045 FieldDBInsert field( access( &base::database, #field, &base::field ) );
00046
00048 #define FIELDDB_ELEMENT_EX( base, field, access, fieldst ) \
00049 FieldDBInsert fieldst( access( &base::database, #fieldst, &base::field ) );
00050
00051 namespace H3D {
00052
00053 class Node;
00054 typedef Node*( *H3DCreateNodeFunc)();
00055
00056 struct H3DNodeDatabase;
00057
00059 struct H3DAPI_API FieldDBElement {
00065 FieldDBElement( H3DNodeDatabase *_container,
00066 const string & _name,
00067 const Field::AccessType _access );
00068
00070 virtual ~FieldDBElement() {};
00071
00073 H3DNodeDatabase* getContainer() {
00074 return container;
00075 }
00076
00078 const string& getName() {
00079 return name;
00080 }
00081
00083 const Field::AccessType getAccessType() {
00084 return access;
00085 }
00086
00089 virtual Field *getField( Node *n ) const { return NULL; };
00090
00091 protected:
00092 H3DNodeDatabase *container;
00093 string name;
00094 const Field::AccessType access;
00095 };
00096
00101 struct H3DAPI_API DynamicFieldDBElement : FieldDBElement {
00102 DynamicFieldDBElement( H3DNodeDatabase *_container,
00103 const string&_name,
00104 const Field::AccessType _access,
00105 Field *_ptr ) :
00106 FieldDBElement( _container, _name, _access ), ptr( _ptr ) {}
00107
00110 virtual Field *getField( Node *n ) const {
00111 if( ptr && n == ptr->getOwner() )
00112 return ptr;
00113 else
00114 return NULL;
00115 }
00116 protected:
00118 Field *ptr;
00119 };
00120
00121
00123 template< class N, class F >
00124 struct FieldDBTemplate : FieldDBElement {
00125 FieldDBTemplate( H3DNodeDatabase *_container,
00126 const string& _name,
00127 const Field::AccessType _access,
00128 auto_ptr<F> N:: *_ptr ) :
00129 FieldDBElement( _container, _name, _access ), ptr( _ptr ) {}
00130
00133 virtual Field *getField( Node *n ) const {
00134 N *node = dynamic_cast<N*>(n);
00135 if ( node )
00136 return (node->*ptr).get();
00137 else
00138 return NULL;
00139 }
00140 protected:
00142 const auto_ptr<F> N:: *ptr;
00143 };
00144
00146 template< class N, class F >
00147 inline FieldDBTemplate< N, F >* INITIALIZE_ONLY( H3DNodeDatabase *_container,
00148 const string& _name,
00149 auto_ptr<F> N:: *_ptr ) {
00150 return new FieldDBTemplate< N, F >( _container,
00151 _name,
00152 Field::INITIALIZE_ONLY,
00153 _ptr );
00154 }
00155
00157 template< class N, class F >
00158 inline FieldDBTemplate< N, F >* OUTPUT_ONLY( H3DNodeDatabase *_container,
00159 const string &_name,
00160 auto_ptr<F> N:: *_ptr ) {
00161 return new FieldDBTemplate< N, F >( _container,
00162 _name,
00163 Field::OUTPUT_ONLY, _ptr );
00164 }
00165
00167 template< class N, class F >
00168 inline FieldDBTemplate< N, F >* INPUT_ONLY( H3DNodeDatabase *_container,
00169 const string &_name,
00170 auto_ptr<F> N:: *_ptr ) {
00171 return new FieldDBTemplate< N, F >( _container,
00172 _name,
00173 Field::INPUT_ONLY,
00174 _ptr );
00175 }
00176
00178 template< class N, class F >
00179 inline FieldDBTemplate< N, F >* INPUT_OUTPUT( H3DNodeDatabase *_container,
00180 const string &_name,
00181 auto_ptr<F> N:: *_ptr ) {
00182 return new FieldDBTemplate< N, F >( _container,
00183 _name,
00184 Field::INPUT_OUTPUT,
00185 _ptr );
00186 }
00187
00188
00195 struct H3DAPI_API H3DNodeDatabase {
00196 typedef map< string, FieldDBElement* > FieldDBType;
00197 typedef map< string, H3DNodeDatabase*> H3DNodeDatabaseType;
00198 typedef H3DNodeDatabaseType::const_iterator NodeDatabaseConstIterator;
00199
00203 class H3DAPI_API FieldDBConstIterator {
00204 public:
00206 FieldDBConstIterator( H3DNodeDatabase * _ndb , bool is_end );
00207
00209 FieldDBConstIterator( const FieldDBConstIterator &f ):
00210 status( f.status ),
00211 local_iterator( f.local_iterator ),
00212 inherited_iterator( new FieldDBConstIterator ),
00213 ndb( f.ndb ) {
00214 *inherited_iterator = *f.inherited_iterator;
00215 }
00216
00218 inline FieldDBConstIterator &operator++(int) {
00219 return operator++();
00220 }
00221
00223 FieldDBConstIterator &operator++();
00224
00226 bool operator==( FieldDBConstIterator iter );
00227
00229 inline bool operator!=( FieldDBConstIterator iter ) {
00230 return !operator==( iter );
00231 }
00232
00234 inline string operator*() {
00235 if( status == INHERITED )
00236 return *(*inherited_iterator);
00237 else
00239 return (*local_iterator).first;
00240 }
00241
00242 protected:
00243 FieldDBConstIterator(){}
00244
00245 typedef enum {
00248 LOCAL,
00251 INHERITED,
00253 END
00254 } Status;
00255
00258 Status status;
00261 FieldDBType::const_iterator local_iterator;
00264 FieldDBConstIterator* inherited_iterator;
00266 H3DNodeDatabase * ndb;
00267 };
00268
00269
00271 H3DNodeDatabase( const string&_name,
00272 H3DCreateNodeFunc _createf,
00273 const type_info &_ti,
00274 H3DNodeDatabase *_parent = 0 );
00275
00278 H3DNodeDatabase( const type_info &_ti,
00279 H3DNodeDatabase *_parent = 0 );
00280
00282 static H3DNodeDatabase *lookupTypeId( const type_info &t );
00283
00285 static H3DNodeDatabase *lookupName( const string &name );
00286
00291 static Node *createNode( const string &name );
00292
00294 void addField( FieldDBElement *f );
00295
00298 Field *getField( Node *n, const string& f ) const;
00299
00302 void initFields( Node* ) const;
00303
00304 private:
00306 Field *getFieldHelp( Node *n, const string& f ) const;
00307
00309 string name;
00310
00312 const H3DCreateNodeFunc createf;
00313
00315 const type_info &ti;
00316
00318 H3DNodeDatabase *parent;
00319
00321 FieldDBType fields;
00322
00324 static bool initialized;
00325
00326 public:
00328 static H3DNodeDatabaseType *database;
00329
00333 static NodeDatabaseConstIterator begin() {
00334 return database->begin();
00335 }
00336
00338 static NodeDatabaseConstIterator end() {
00339 return database->end();
00340 }
00341
00344 FieldDBConstIterator fieldDBBegin() {
00345 return FieldDBConstIterator( this, 0 );
00346 }
00347
00349 FieldDBConstIterator fieldDBEnd() {
00350 return FieldDBConstIterator( this,1 );
00351 }
00352
00354 inline size_t fieldDBSize() {
00355 if( !parent ) {
00356 return fields.size();
00357 } else {
00358 return fields.size() + parent->fieldDBSize();
00359 }
00360 }
00361
00362 };
00363
00364 struct FieldDBInsert {
00365 FieldDBInsert( FieldDBElement *f ) {
00366 f->getContainer()->addField( f );
00367 }
00368 };
00369
00370
00371 }
00372
00373 #endif