00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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
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
00181 checkAccessTypeGet( id );
00182
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