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 __REFCOUNTMFIELD_H__
00029 #define __REFCOUNTMFIELD_H__
00030
00031 #include "MField.h"
00032 #include "MFNodeAutoRefVector.h"
00033
00034 namespace H3D {
00035
00039 typedef AutoRefVector< Node > NodeVector;
00040
00046 template< class RefClass >
00047 class RefCountMField:
00048 public MFieldBase< RefClass *,
00049 FieldInternals::MFNodeAutoRefVector< RefClass >,
00050 Field > {
00051 public:
00052
00053 typedef MFieldBase< RefClass *,
00054 FieldInternals::MFNodeAutoRefVector< RefClass >,
00055 Field > BaseFieldType;
00056
00059 H3D_VALUE_EXCEPTION( typename BaseFieldType::size_type, InvalidIndex );
00060
00061
00063 RefCountMField() {
00064 this->value.owner = this;
00065 }
00066
00068 RefCountMField( typename FieldInternals::MFNodeAutoRefVector< RefClass >::size_type sz ) :
00069 MFieldBase< RefClass *,
00070 FieldInternals::MFNodeAutoRefVector< RefClass >,
00071 Field >( sz ){
00072 this->value.owner = this;
00073 }
00074
00075 ~RefCountMField() {
00076 this->value.clear();
00077 };
00078
00080 inline virtual const NodeVector &getValue( int id = 0 ) {
00081 this->checkAccessTypeGet( id );
00082 this->upToDate();
00083 return this->value;
00084 }
00085
00087 inline virtual RefClass * getValueByIndex(
00088 typename BaseFieldType::size_type i,
00089 int id = 0 ) {
00090 this->checkAccessTypeGet( id );
00091 this->upToDate();
00092 if( i < 0 || i >= this->value.size() ) {
00093 stringstream s;
00094 s << "Trying to access value outside the bounds of field "
00095 << this->getFullName() << ". Field has size " << this->value.size()
00096 << ". ";
00097 throw InvalidIndex( i, s.str(), H3D_FULL_LOCATION );
00098 }
00099 return this->value[i];
00100 }
00101
00107
00108 inline void setValue( typename FieldInternals::MFNodeAutoRefVector< RefClass >::size_type i,
00109 const typename FieldInternals::MFNodeAutoRefVector< RefClass >::value_type &v,
00110 int id = 0 ) {
00111 this->checkAccessTypeSet( id );
00112 this->value.set( i, v );
00113
00114 this->startEvent();
00115 }
00116
00119 inline virtual void setValue( const AutoRefVector< RefClass > &v,
00120 int id = 0 ) {
00121 this->checkAccessTypeSet( id );
00122 this->value = v;
00123 this->startEvent();
00124 }
00125
00128 inline virtual void setValue( const vector< RefClass * > &v, int id = 0 ) {
00129 this->checkAccessTypeSet( id );
00130 this->value = v;
00131 this->startEvent();
00132 }
00133
00134
00136 inline virtual void swap( vector< RefClass * > &v, int id = 0 ) {
00137 this->checkAccessTypeSet( id );
00138 this->checkAccessTypeGet( id );
00139 this->upToDate();
00140 this->value.swap( v );
00141 this->startEvent();
00142 }
00143
00145 inline virtual void erase( RefClass *a, int id = 0 ) {
00146 this->checkAccessTypeSet( id );
00147 this->upToDate();
00148 this->value.erase( a );
00149 }
00150
00152 virtual string getTypeName() {
00153 return classTypeName();
00154 }
00155
00157 static string classTypeName() {
00158 return "RefCountMField";
00159 }
00160
00161 protected:
00162 friend class FieldInternals::MFNodeAutoRefVector<RefClass>;
00163
00165 inline virtual void update() {
00166 this->value = static_cast< RefCountMField* >(this->event.ptr)->getValue();
00167 }
00168
00169 virtual RefClass *preOnAdd( RefClass *n ) {
00170 return n;
00171 }
00172
00173 virtual RefClass *preOnRemove( RefClass *n ) {
00174 return n;
00175 }
00176
00182 virtual void onAdd( RefClass *n ) {
00183 #ifdef REF_COUNT_DEBUG
00184 Console(1) << "RefCountMField::onAdd( " << getFullName() << " = " << this
00185 << ", n = " << n << ") " << endl;
00186 #endif
00187 }
00188
00194 virtual void onRemove( RefClass *n ) {
00195 #ifdef REF_COUNT_DEBUG
00196 Console(1) << "RefCountMField::onRemove( " << getFullName() << " = "
00197 << this << ", n = " << n << ") " << endl;
00198 #endif
00199 }
00200 };
00201
00202 }
00203
00204 #endif