MFNode.h

Go to the documentation of this file.
00001 
00002 //    Copyright 2004, SenseGraphics AB
00003 //
00004 //    This file is part of H3D API.
00005 //
00006 //    H3D API is free software; you can redistribute it and/or modify
00007 //    it under the terms of the GNU General Public License as published by
00008 //    the Free Software Foundation; either version 2 of the License, or
00009 //    (at your option) any later version.
00010 //
00011 //    H3D API is distributed in the hope that it will be useful,
00012 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 //    GNU General Public License for more details.
00015 //
00016 //    You should have received a copy of the GNU General Public License
00017 //    along with H3D API; if not, write to the Free Software
00018 //    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 //
00020 //    A commercial license is also available. Please contact us at 
00021 //    www.sensegraphics.com for more information.
00022 //
00023 //
00026 //
00028 #ifndef __MFNODE_H__
00029 #define __MFNODE_H__
00030 
00031 #include "RefCountMField.h"
00032 #include "MFNodeAutoRefVector.h"
00033 #include "FieldTemplates.h"
00034 #include "Node.h"
00035 #include "X3DPrototypeInstance.h"
00036 
00037 namespace H3D {
00038 
00044   class H3DAPI_API MFNode: public RefCountMField< Node > { 
00045     //    Field > {
00046   public:   
00047     
00048     class const_iterator: public RefCountMField< Node >::const_iterator {
00049     public:
00050       const_iterator( RefCountMField< Node >::const_iterator i ):
00051         RefCountMField< Node >::const_iterator( i ) {
00052       }
00053       
00054       Node * const operator*() {
00055         Node *n = RefCountMField< Node >::const_iterator::operator*();
00056         X3DPrototypeInstance *pi = dynamic_cast< X3DPrototypeInstance * >( n );
00057         if( pi ) {
00058           return pi->getPrototypedNode();
00059         } else {
00060           return n;
00061         }
00062       }
00063     };
00064     
00065     class const_reverse_iterator: 
00066       public RefCountMField< Node >::const_reverse_iterator {
00067     public:
00069       const_reverse_iterator( RefCountMField< Node >::const_reverse_iterator i ):
00070         RefCountMField< Node >::const_reverse_iterator( i ) {
00071         
00072       }
00073       
00074       Node * const operator*() {
00075         Node *n = RefCountMField< Node >::const_reverse_iterator::operator*();
00076         X3DPrototypeInstance *pi = dynamic_cast< X3DPrototypeInstance * >( n );
00077         if( pi ) {
00078           return pi->getPrototypedNode();
00079         } else {
00080           return n;
00081         }
00082       }
00083     };
00084 
00086     inline const_iterator begin( int id = 0 ) { 
00087       return const_iterator( RefCountMField<Node>::begin( id ) );
00088     }
00089     
00091     inline const_iterator end( int id = 0 ) { 
00092       return const_iterator( RefCountMField<Node>::end( id ) );
00093     }
00094 
00096     inline const_reverse_iterator rbegin( int id = 0 ) { 
00097       return const_reverse_iterator( RefCountMField<Node>::rbegin( id ) );
00098     }
00099 
00101     inline const_reverse_iterator rend( int id = 0 ) { 
00102       return const_reverse_iterator( RefCountMField<Node>::rend( id ) );
00103     }
00104 
00106     inline virtual Node * operator[](size_type i ) {
00107       Node *n = RefCountMField< Node >::operator[](i);
00108       X3DPrototypeInstance *pi = dynamic_cast< X3DPrototypeInstance * >( n );
00109       if( pi ) {
00110         return pi->getPrototypedNode();
00111       } else {
00112         return n;
00113       }
00114     }
00115     
00117     inline virtual Node * front( int id = 0 ) { 
00118       Node *n = RefCountMField< Node >::front(id);
00119       X3DPrototypeInstance *pi = dynamic_cast< X3DPrototypeInstance * >( n );
00120       if( pi ) {
00121         return pi->getPrototypedNode();
00122       } else {
00123         return n;
00124       }
00125     }
00126 
00128     inline virtual Node * back( int id = 0 ) {
00129       Node *n = RefCountMField< Node >::back(id);
00130       X3DPrototypeInstance *pi = dynamic_cast< X3DPrototypeInstance * >( n );
00131       if( pi ) {
00132         return pi->getPrototypedNode();
00133       } else {
00134         return n;
00135       }
00136     }
00137 
00139     inline virtual Node * getValueByIndex( 
00140                                           size_type i,
00141                                           int id = 0 ) {
00142       Node *n = RefCountMField< Node >::getValueByIndex( i, id );
00143       X3DPrototypeInstance *pi = dynamic_cast< X3DPrototypeInstance * >( n );
00144       if( pi ) {
00145         return pi->getPrototypedNode();
00146       } else {
00147         return n;
00148       }
00149     }
00150 
00151 
00152     
00153     virtual Node *preOnAdd( Node *n ) {
00154       Node *pn = getPrototypeNode( n );
00155       if( pn ) {
00156         return pn;
00157       }
00158       else
00159         return n;
00160     }
00161     
00162     virtual Node *preOnRemove( Node *n ) {
00163       Node *pn = getPrototypeNode( n );
00164       if( pn ) 
00165         return pn;
00166       else
00167         return n;
00168     }
00169 
00170 
00172     MFNode() {}
00173     
00175     MFNode( size_type sz ) : 
00176       RefCountMField< Node >( sz ) {} 
00177     
00179     inline virtual const NodeVector &getValue( int id = 0 ) {
00180       // check that we have the correct access type
00181       checkAccessTypeGet( id );
00182       // check that the field is up-to-date first
00183       this->upToDate();
00184       return value;
00185     }
00186 
00188     virtual string getTypeName() {
00189       return classTypeName();
00190     }
00191     
00193     static string classTypeName() {
00194       return "MFNode";
00195     }
00196 
00198     virtual X3DTypes::X3DType getX3DType() { return X3DTypes::MFNODE; }
00199 
00200   protected:
00201     Node *getPrototypeNode( Node *n );
00202   };
00203 
00204   template<>
00205   inline string MFieldBase<Node *>::classTypeName() {
00206     return "MFNode";
00207   }  
00208   
00209   
00214   template< class NodeType >
00215   class TypedMFNode: public MFNode {
00216   protected:
00218     virtual void onAdd( Node *n) {
00219       if( !dynamic_cast< NodeType * >( n ) ) {
00220         Node *pi = getPrototypeNode( n );
00221         if( !dynamic_cast< NodeType * >( pi ) ) {
00222           stringstream s;
00223           s << "Expecting " << typeid( NodeType ).name();
00224           throw InvalidNodeType( n->getTypeName(),
00225                                  s.str(),
00226                                  H3D_FULL_LOCATION ); 
00227         } 
00228       }
00229       MFNode::onAdd( n );
00230     }
00231     
00232   public:
00234     virtual NodeType *getValueByIndex( typename MFNode::size_type i, 
00235                                        int id = 0 ) {
00236       return static_cast< NodeType * >( MFNode::getValueByIndex( i, id ) );
00237     }
00238 
00240     virtual NodeType *getCastedValueByIndex( typename MFNode::size_type i, 
00241                                              int id = 0 ) {
00242       return this->getValueByIndex( i, id );
00243     }
00244   };
00245 
00258   template< class Type >
00259   class TypedMFNodeObject: public MFNode {
00260   protected:
00262     void onAdd( Node *n) {
00263       if( !dynamic_cast< Type * >( n ) ) {
00264         Node *pi = getPrototypeNode( n );
00265         if( !dynamic_cast< Type * >( pi ) ) {
00266           stringstream s;
00267           s << "Expecting " << typeid( Type ).name();
00268           throw InvalidNodeType( n->getTypeName(),
00269                                  s.str(),
00270                                  H3D_FULL_LOCATION ); 
00271         } 
00272       }
00273       MFNode::onAdd( n );
00274     }
00275     
00276   public:
00278     virtual Type *getCastedValueByIndex( typename MFNode::size_type i, 
00279                                          int id = 0 ) {
00280       return reinterpret_cast< Type * >( this->getValueByIndex( i, id ) );
00281     }
00282   };
00283   
00284   
00285 }
00286 
00287 #endif

Generated on Thu Aug 24 12:38:33 2006 for H3D API by  doxygen 1.4.5