H3D API  2.4.1
H3DDynamicFieldsObject.h
Go to the documentation of this file.
1 // Copyright 2004-2019, SenseGraphics AB
3 //
4 // This file is part of H3D API.
5 //
6 // H3D API is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 2 of the License, or
9 // (at your option) any later version.
10 //
11 // H3D API is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with H3D API; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 //
20 // A commercial license is also available. Please contact us at
21 // www.sensegraphics.com for more information.
22 //
23 //
27 //
29 #ifndef __H3DDYNAMICFIELDSOBJECT_H__
30 #define __H3DDYNAMICFIELDSOBJECT_H__
31 
32 #include <H3D/H3DNodeDatabase.h>
33 #include <H3DUtil/AutoPtrVector.h>
34 #include <H3D/Node.h>
35 
36 namespace H3D {
42  class H3DAPI_API H3DDynamicFieldsObjectBase {
43  public:
44 
46  H3DDynamicFieldsObjectBase() {}
47 
49  virtual ~H3DDynamicFieldsObjectBase() {
50  }
51 
59  inline virtual bool addField( const string &name,
60  const Field::AccessType &access,
61  Field *field ) {
62 
63  DynamicFieldsMap::const_iterator j = object_dynamic_fields.find( name );
64  if ( field && j == object_dynamic_fields.end() ) {
65  field->setName( name );
66  field->setAccessType( access );
67  object_dynamic_fields.insert( std::pair< string, Field* >( name , field ) );
68  return true;
69  }
70 
71  return false;
72 
73  }
74 
78  inline virtual bool removeField ( const string& _name ) {
79 
80  DynamicFieldsMap::iterator j = object_dynamic_fields.find( _name );
81  if ( j != object_dynamic_fields.end() ) {
82  Field* f= j->second;
83  if ( f ) {
84  object_dynamic_fields.erase ( j );
85  delete f;
86  return true;
87  }
88  }
89  return false;
90 
91  }
92 
97  inline Field *getObjectField ( const string& _name ) const {
98  DynamicFieldsMap::const_iterator j = object_dynamic_fields.find( _name );
99  if ( j != object_dynamic_fields.end() ) {
100  Field* f= j->second;
101  return f;
102  }
103  return NULL;
104  }
105 
107  virtual void clearFields() {
108  for( DynamicFieldsMap::iterator i = object_dynamic_fields.begin();
109  i != object_dynamic_fields.end(); ++i ) {
110  if( i->second )
111  delete i->second;
112  }
113  object_dynamic_fields.clear();
114  }
115 
116  protected:
117  typedef map< string, Field* > DynamicFieldsMap;
118  DynamicFieldsMap object_dynamic_fields;
119  };
120 
121 
128  class H3DAPI_API H3DDynamicFieldsObject : public H3DDynamicFieldsObjectBase {
129  public:
137  inline virtual bool addField( const string &name,
138  const Field::AccessType &access,
139  Field *field ) {
140  Node *n = dynamic_cast< Node * >( this );
141  if( n ) {
142  if( !database.get() ) {
143  H3DNodeDatabase *parent_db = H3DNodeDatabase::lookupTypeId( typeid( *n ) );
144  database.reset( new H3DNodeDatabase( n, parent_db ) );
145  }
146  if( !database->getField( n, name ) ) {
147  // Set the placeholder to the node address.
148  inherited_node = n;
149  field->setOwner( n );
150  field->setName( name );
151  field->setAccessType( access );
152  database->addField( new DynamicFieldDBElement( database.get(),
153  name,
154  access,
155  field ) );
156  dynamic_fields.push_back( field );
157  return true;
158  }
159  }
160  return false;
161  }
162 
166  inline virtual bool removeField ( const string& _name ) {
167  if ( database.get() ) {
168  Field* f= inherited_node->getField ( _name );
169  AutoPtrVector< Field >::iterator i= find ( dynamic_fields.begin(), dynamic_fields.end(), f );
170 
171  if ( f && i != dynamic_fields.end() ) {
172  if ( database->removeField ( _name, inherited_node ) ) {
173  dynamic_fields.erase ( i );
174  return true;
175  }
176  }
177  }
178 
179  return false;
180  }
181 
182  typedef AutoPtrVector< Field >::const_iterator field_iterator;
183 
185  inline field_iterator firstField() {
186  return dynamic_fields.begin();
187  }
188 
190  inline field_iterator endField() {
191  return dynamic_fields.end();
192  }
193 
195  virtual void clearFields() {
196  if( database.get() )
197  database->clearDynamicFields(inherited_node);
198  dynamic_fields.clear();
199  }
200 
201  protected:
202  H3DUniquePtr< H3DNodeDatabase > database;
203  AutoPtrVector< Field > dynamic_fields;
204  // Holds a pointer to the node instance to which dynamic fields
205  // belong to. Note that this pointer should only be used for pointer
206  // comparasion and never for access to any node members.
207  // The reason for using this pointer instead of this is because
208  // H3DDynamicFieldsObject is used with multiple inheritance and
209  // H3DDynamicFieldsObject is not a node class. This could result
210  // in a destructor sequence for a node deleting the node base
211  // class before the H3DDynamicFieldsObject base class which would
212  // result in an invalid value for dynamic_cast< Node * >(this)
213  // and the database is then not cleaned up properly.
214  Node * inherited_node;
215  public:
216 
219  H3DDynamicFieldsObjectBase(), inherited_node( NULL ) {}
220  };
221 }
222 
223 #endif
Header file for H3DNodeDatabase.
Node base class.
The Field class.
Definition: Field.h:46
void setOwner(Node *n)
Set the Node that contains this field.
Definition: Field.cpp:402
void setName(string _name)
Sets local the name of the field. Will be used in error reporting.
Definition: Field.h:125
AccessType
The different access types that a field can have.
Definition: Field.h:53
void setAccessType(AccessType _access_type)
Set the access type of the field.
Definition: Field.h:210
This abstract interface class is the base class for all classes that specify arbitrary fields.
Definition: H3DDynamicFieldsObject.h:128
field_iterator firstField()
Get an iterator to the first of the dynamic fields.
Definition: H3DDynamicFieldsObject.h:185
virtual void clearFields()
Remove all dynamic fields that have been previously added.
Definition: H3DDynamicFieldsObject.h:195
H3DDynamicFieldsObject()
Constructor.
Definition: H3DDynamicFieldsObject.h:218
virtual bool removeField(const string &_name)
Remove a field from the Node.
Definition: H3DDynamicFieldsObject.h:166
virtual bool addField(const string &name, const Field::AccessType &access, Field *field)
Add a field to the Node.
Definition: H3DDynamicFieldsObject.h:137
field_iterator endField()
Get an iterator pointing to the end of the dynamic fields.
Definition: H3DDynamicFieldsObject.h:190
Node is the base class for all classes that can be part of the H3D scene-graph.
Definition: Node.h:46
H3D API namespace.
Definition: Anchor.h:38
The DynamicFieldDBElement is a FieldDBElement for fields that are not actual members of a Node class,...
Definition: H3DNodeDatabase.h:100
The H3DNodeDatabase contains a mapping between a name of a Node and the constructor for the Node with...
Definition: H3DNodeDatabase.h:194
static H3DNodeDatabase * lookupTypeId(const type_info &t)
Search the node database for an entry with a matching type_info structure.
Definition: H3DNodeDatabase.cpp:228