SoSubField.h

Go to the documentation of this file.
00001 #ifndef COIN_SOSUBFIELD_H
00002 #define COIN_SOSUBFIELD_H
00003 
00004 /**************************************************************************\
00005  *
00006  *  This file is part of the Coin 3D visualization library.
00007  *  Copyright (C) 1998-2009 by Kongsberg SIM.  All rights reserved.
00008  *
00009  *  This library is free software; you can redistribute it and/or
00010  *  modify it under the terms of the GNU General Public License
00011  *  ("GPL") version 2 as published by the Free Software Foundation.
00012  *  See the file LICENSE.GPL at the root directory of this source
00013  *  distribution for additional information about the GNU GPL.
00014  *
00015  *  For using Coin with software that can not be combined with the GNU
00016  *  GPL, and for taking advantage of the additional benefits of our
00017  *  support services, please contact Kongsberg SIM about acquiring
00018  *  a Coin Professional Edition License.
00019  *
00020  *  See http://www.coin3d.org/ for more information.
00021  *
00022  *  Kongsberg SIM, Postboks 1283, Pirsenteret, 7462 Trondheim, NORWAY.
00023  *  http://www.sim.no/  sales@sim.no  coin-support@coin3d.org
00024  *
00025 \**************************************************************************/
00026 
00027 #include <Inventor/SbBasic.h> // for SO__QUOTE() definition
00028 #include <Inventor/SbName.h> // SoType::createType() needs to know SbName.
00029 #include <Inventor/C/tidbits.h>
00030 #include <assert.h>
00031 
00032 #ifndef COIN_INTERNAL
00033 // Added to be Inventor compliant.
00034 #include <Inventor/fields/SoField.h>
00035 #include <Inventor/SoInput.h>
00036 #include <Inventor/SoOutput.h>
00037 #endif // !COIN_INTERNAL
00038 
00039 /**************************************************************************
00040  *
00041  * Header macros for single-value fields.
00042  *
00043  **************************************************************************/
00044 
00045 #define SO_SFIELD_CONSTRUCTOR_HEADER(_class_) \
00046 public: \
00047   _class_(void); \
00048   virtual ~_class_()
00049 
00050 
00051 #define SO_SFIELD_REQUIRED_HEADER(_class_) \
00052 private: \
00053   static SoType classTypeId; \
00054   static void atexit_cleanup(void) { SoType::removeType(_class_::classTypeId.getName()); _class_::classTypeId STATIC_SOTYPE_INIT; } \
00055 public: \
00056   static void * createInstance(void); \
00057   static SoType getClassTypeId(void); \
00058   virtual SoType getTypeId(void) const; \
00059  \
00060   virtual void copyFrom(const SoField & field); \
00061   const _class_ & operator=(const _class_ & field); \
00062   virtual SbBool isSame(const SoField & field) const
00063 
00064 
00065 #define PRIVATE_SFIELD_IO_HEADER() \
00066 private: \
00067   virtual SbBool readValue(SoInput * in); \
00068   virtual void writeValue(SoOutput * out) const
00069 
00070 
00071 #define SO_SFIELD_VALUE_HEADER(_class_, _valtype_, _valref_) \
00072   PRIVATE_SFIELD_IO_HEADER(); \
00073 protected: \
00074   _valtype_ value; \
00075  \
00076 public: \
00077   _valref_ getValue(void) const { this->evaluate(); return this->value; } \
00078   void setValue(_valref_ newvalue); \
00079   _valref_ operator=(_valref_ newvalue) { this->setValue(newvalue); return this->value; } \
00080  \
00081   int operator==(const _class_ & field) const; \
00082   int operator!=(const _class_ & field) const { return ! operator==(field); }
00083 
00084 
00085 // FIXME: is really the operator=() definition below necessary?
00086 // 19991226 mortene.
00087 #define SO_SFIELD_DERIVED_VALUE_HEADER(_class_, _valtype_, _valref_) \
00088   PRIVATE_SFIELD_IO_HEADER(); \
00089 public: \
00090   _valref_ operator=(_valref_ newvalue) { this->setValue(newvalue); return this->value; }
00091 
00092 
00093 
00094 #define SO_SFIELD_HEADER(_class_, _valtype_, _valref_) \
00095   SO_SFIELD_CONSTRUCTOR_HEADER(_class_); \
00096   SO_SFIELD_REQUIRED_HEADER(_class_); \
00097   SO_SFIELD_VALUE_HEADER(_class_, _valtype_, _valref_)
00098 
00099 
00100 #define SO_SFIELD_DERIVED_HEADER(_class_, _valtype_, _valref_) \
00101   SO_SFIELD_CONSTRUCTOR_HEADER(_class_); \
00102   SO_SFIELD_REQUIRED_HEADER(_class_); \
00103   SO_SFIELD_DERIVED_VALUE_HEADER(_class_, _valtype_, _valref_)
00104 
00105 
00106 
00107 /**************************************************************************
00108  *
00109  * Source macros for single-value fields.
00110  *
00111  **************************************************************************/
00112 
00113 #define PRIVATE_FIELD_INIT_CLASS(_class_, _classname_, _parent_, _createfunc_) \
00114   do { \
00115     /* Make sure superclass get initialized before subclass. */ \
00116     assert(_parent_::getClassTypeId() != SoType::badType()); \
00117     /* Make sure we only initialize once. */ \
00118     assert(_class_::classTypeId == SoType::badType()); \
00119     _class_::classTypeId = \
00120       SoType::createType(_parent_::getClassTypeId(), _classname_, _createfunc_); \
00121     cc_coin_atexit_static_internal \
00122       ( \
00123        _class_::atexit_cleanup \
00124        ); \
00125   } while (0)
00126 
00127 
00128 
00129 #define SO_SFIELD_INIT_CLASS(_class_, _parent_) \
00130   do { \
00131     const char * classname = SO__QUOTE(_class_); \
00132     PRIVATE_FIELD_INIT_CLASS(_class_, classname, _parent_, &_class_::createInstance); \
00133   } while (0)
00134 
00135 #define SO_SFIELD_CONSTRUCTOR_SOURCE(_class_) \
00136 _class_::_class_(void) { assert(_class_::classTypeId != SoType::badType()); } \
00137 _class_::~_class_() { }
00138 
00139 
00140 
00141 #define SO_SFIELD_VALUE_SOURCE(_class_, _valtype_, _valref_) \
00142 void \
00143 _class_::setValue(_valref_ valuearg) { \
00144   this->value = valuearg; \
00145   this->valueChanged(); \
00146 } \
00147  \
00148 SbBool \
00149 _class_::operator==(const _class_ & field) const \
00150 { \
00151   return (this->getValue() == field.getValue()); \
00152 }
00153 
00154 
00155 #define PRIVATE_TYPEID_SOURCE(_class_) \
00156 SoType _class_::getTypeId(void) const { return _class_::classTypeId; } \
00157 SoType _class_::getClassTypeId(void) { return _class_::classTypeId; } \
00158 void * _class_::createInstance(void) { return new _class_; } \
00159 SoType _class_::classTypeId STATIC_SOTYPE_INIT
00160 
00161 
00162 #define PRIVATE_EQUALITY_SOURCE(_class_) \
00163 void \
00164 _class_::copyFrom(const SoField & field) \
00165 { \
00166   this->operator=(static_cast<const _class_ &>(field)); \
00167 } \
00168  \
00169 SbBool \
00170 _class_::isSame(const SoField & field) const \
00171 { \
00172   if (field.getTypeId() != this->getTypeId()) return FALSE; \
00173   return this->operator==(static_cast<const _class_ &>(field)); \
00174 }
00175 
00176 
00177 
00178 #define SO_SFIELD_REQUIRED_SOURCE(_class_) \
00179 PRIVATE_TYPEID_SOURCE(_class_); \
00180 PRIVATE_EQUALITY_SOURCE(_class_); \
00181  \
00182 const _class_ & \
00183 _class_::operator=(const _class_ & field) \
00184 { \
00185   this->setValue(field.getValue()); \
00186   return *this; \
00187 }
00188 
00189 
00190 
00191 #define SO_SFIELD_SOURCE(_class_, _valtype_, _valref_) \
00192   SO_SFIELD_CONSTRUCTOR_SOURCE(_class_); \
00193   SO_SFIELD_VALUE_SOURCE(_class_, _valtype_, _valref_); \
00194   SO_SFIELD_REQUIRED_SOURCE(_class_)
00195 
00196 
00197 
00198 #define SO_SFIELD_DERIVED_SOURCE(_class_, _valtype_, _valref_) \
00199   SO_SFIELD_CONSTRUCTOR_SOURCE(_class_); \
00200   SO_SFIELD_REQUIRED_SOURCE(_class_)
00201 
00202 
00203 /**************************************************************************
00204  *
00205  * Header macros for multiple-value fields.
00206  *
00207  **************************************************************************/
00208 
00209 #define PRIVATE_MFIELD_IO_HEADER() \
00210 private: \
00211   virtual SbBool read1Value(SoInput * in, int idx); \
00212   virtual void write1Value(SoOutput * out, int idx) const
00213 
00214 
00215 
00216 #define SO_MFIELD_VALUE_HEADER(_class_, _valtype_, _valref_) \
00217   PRIVATE_MFIELD_IO_HEADER(); \
00218 protected: \
00219   virtual void deleteAllValues(void); \
00220   virtual void copyValue(int to, int from); \
00221   virtual int fieldSizeof(void) const; \
00222   virtual void * valuesPtr(void); \
00223   virtual void setValuesPtr(void * ptr); \
00224   virtual void allocValues(int num); \
00225  \
00226   _valtype_ * values; \
00227 public: \
00228   _valref_ operator[](const int idx) const \
00229     { this->evaluate(); return this->values[idx]; } \
00230  \
00233   const _valtype_ * getValues(const int start) const \
00234     { this->evaluate(); return const_cast<const _valtype_ *>(this->values + start); } \
00235   int find(_valref_ value, SbBool addifnotfound = FALSE); \
00236   void setValues(const int start, const int num, const _valtype_ * newvals); \
00237   void set1Value(const int idx, _valref_ value); \
00238   void setValue(_valref_ value); \
00239   _valref_ operator=(_valref_ val) { this->setValue(val); return val; } \
00240   SbBool operator==(const _class_ & field) const; \
00241   SbBool operator!=(const _class_ & field) const { return !operator==(field); } \
00242   _valtype_ * startEditing(void) { this->evaluate(); return this->values; } \
00243   void finishEditing(void) { this->valueChanged(); }
00244 
00245 #define SO_MFIELD_DERIVED_VALUE_HEADER(_class_, _valtype_, _valref_) \
00246   PRIVATE_MFIELD_IO_HEADER(); \
00247 public: \
00248   _valref_ operator=(_valref_ val) { this->setValue(val); return val; }
00249 
00250 
00251 
00252 #define SO_MFIELD_HEADER(_class_, _valtype_, _valref_) \
00253   SO_SFIELD_CONSTRUCTOR_HEADER(_class_); \
00254   SO_SFIELD_REQUIRED_HEADER(_class_); \
00255   SO_MFIELD_VALUE_HEADER(_class_, _valtype_, _valref_)
00256 
00257 
00258 
00259 #define SO_MFIELD_DERIVED_HEADER(_class_, _valtype_, _valref_) \
00260   SO_SFIELD_CONSTRUCTOR_HEADER(_class_); \
00261   SO_SFIELD_REQUIRED_HEADER(_class_); \
00262   SO_MFIELD_DERIVED_VALUE_HEADER(_class_, _valtype_, _valref_)
00263 
00264 #define SO_MFIELD_SETVALUESPOINTER_HEADER(_valtype_) \
00265   void setValuesPointer(const int num, const _valtype_ * userdata); \
00266   void setValuesPointer(const int num, _valtype_ * userdata)
00267 
00268 
00269 /**************************************************************************
00270  *
00271  * Source macros for multiple-value fields.
00272  *
00273  **************************************************************************/
00274 
00275 
00276 #define SO_MFIELD_INIT_CLASS(_class_, _parent_) \
00277   SO_SFIELD_INIT_CLASS(_class_, _parent_)
00278 
00279 
00280 
00281 #define SO_MFIELD_CONSTRUCTOR_SOURCE(_class_) \
00282 _class_::_class_(void) \
00283 { \
00284   assert(_class_::classTypeId != SoType::badType()); \
00285   this->values = NULL; \
00286 } \
00287  \
00288 _class_::~_class_(void) \
00289 { \
00290   this->enableNotify(FALSE); /* Avoid notifying destructed containers. */ \
00291   this->deleteAllValues(); \
00292 }
00293 
00294 
00295 
00296 #define SO_MFIELD_DERIVED_CONSTRUCTOR_SOURCE(_class_) \
00297 _class_::_class_(void) { } \
00298 _class_::~_class_(void) { }
00299 
00300 
00301 
00302 #define SO_MFIELD_REQUIRED_SOURCE(_class_) \
00303 PRIVATE_TYPEID_SOURCE(_class_); \
00304 PRIVATE_EQUALITY_SOURCE(_class_); \
00305 const _class_ & \
00306 _class_::operator=(const _class_ & field) \
00307 { \
00308   /* The allocValues() call is needed, as setValues() doesn't */ \
00309   /* necessarily make the field's getNum() size become the same */ \
00310   /* as the second argument (only if it expands on the old size). */ \
00311   this->allocValues(field.getNum()); \
00312   \
00313   this->setValues(0, field.getNum(), field.getValues(0)); \
00314   return *this; \
00315 }
00316 
00317 
00318 
00319 #define SO_MFIELD_VALUE_SOURCE(_class_, _valtype_, _valref_) \
00320 int \
00321 _class_::fieldSizeof(void) const \
00322 { \
00323   return sizeof(_valtype_); \
00324 } \
00325  \
00326 void * \
00327 _class_::valuesPtr(void) \
00328 { \
00329   return static_cast<void *>(this->values); \
00330 } \
00331  \
00332 void \
00333 _class_::setValuesPtr(void * ptr) \
00334 { \
00335   this->values = static_cast<_valtype_ *>(ptr); \
00336 } \
00337  \
00338 int \
00339 _class_::find(_valref_ value, SbBool addifnotfound) \
00340 { \
00341   evaluate(); \
00342   for (int i=0; i < this->num; i++) if (this->values[i] == value) return i; \
00343  \
00344   if (addifnotfound) this->set1Value(this->num, value); \
00345   return -1; \
00346 } \
00347  \
00348 void \
00349 _class_::setValues(const int start, const int numarg, const _valtype_ * newvals) \
00350 { \
00351   if (start+numarg > this->maxNum) this->allocValues(start+numarg); \
00352   else if (start+numarg > this->num) this->num = start+numarg; \
00353  \
00354   for (int i=0; i < numarg; i++) \
00355     this->values[i+start] = static_cast<_valtype_>(newvals[i]); \
00356   this->valueChanged(); \
00357 } \
00358  \
00359 void \
00360 _class_::set1Value(const int idx, _valref_ value) \
00361 { \
00362   if (idx+1 > this->maxNum) this->allocValues(idx+1); \
00363   else if (idx+1 > this->num) this->num = idx+1; \
00364   this->values[idx] = value; \
00365   this->valueChanged(); \
00366 } \
00367  \
00368 void \
00369 _class_::setValue(_valref_ value) \
00370 { \
00371   this->allocValues(1); \
00372   this->values[0] = value; \
00373   this->valueChanged(); \
00374 } \
00375  \
00376 SbBool \
00377 _class_::operator==(const _class_ & field) const \
00378 { \
00379   if (this == &field) return TRUE; \
00380   if (this->getNum() != field.getNum()) return FALSE; \
00381  \
00382   const _valtype_ * const lhs = this->getValues(0); \
00383   const _valtype_ * const rhs = field.getValues(0); \
00384   for (int i = 0; i < this->num; i++) if (lhs[i] != rhs[i]) return FALSE; \
00385   return TRUE; \
00386 } \
00387  \
00388  \
00389 void \
00390 _class_::deleteAllValues(void) \
00391 { \
00392   this->setNum(0); \
00393 } \
00394  \
00395  \
00396 void \
00397 _class_::copyValue(int to, int from) \
00398 { \
00399   this->values[to] = this->values[from]; \
00400 }
00401 
00402 
00403 #define SO_MFIELD_ALLOC_SOURCE(_class_, _valtype_) \
00404 void \
00405 _class_::allocValues(int newnum) \
00406 { \
00407   /* Important notice: the "malloc-version" of this method is found */ \
00408   /* in SoMField.cpp. If you make modifications here, do check whether */ \
00409   /* or not they should be matched with modifications in that method */ \
00410   /* aswell. */ \
00411  \
00412   /* these must be declared here as a gcc 4.0.0 bug workaround */ \
00413   int i; \
00414   int oldmaxnum; \
00415   _valtype_ * newblock; \
00416   assert(newnum >= 0); \
00417  \
00418   if (newnum == 0) { \
00419     if (!this->userDataIsUsed) delete[] this->values; /* don't fetch pointer through valuesPtr() (avoids void* cast) */ \
00420     this->setValuesPtr(NULL); \
00421     this->maxNum = 0; \
00422     this->userDataIsUsed = FALSE; \
00423   } \
00424   else if (newnum > this->maxNum || newnum < this->num) { \
00425     if (this->valuesPtr()) { \
00426  \
00427       /* Allocation strategy is to repeatedly double the size of the */ \
00428       /* allocated block until it will at least match the requested size. */ \
00429       /* (Unless the requested size is less than what we've got, */ \
00430       /* then we'll repeatedly halve the allocation size.) */ \
00431       /* */ \
00432       /* I think this will handle both cases quite gracefully: */ \
00433       /* 1) newnum > this->maxNum, 2) newnum < num */ \
00434       oldmaxnum = this->maxNum; \
00435       while (newnum > this->maxNum) this->maxNum *= 2; \
00436       while ((this->maxNum / 2) >= newnum) this->maxNum /= 2; \
00437  \
00438       if (oldmaxnum != this->maxNum) { \
00439         newblock = new _valtype_[this->maxNum]; \
00440  \
00441         for (i=0; i < SbMin(this->num, newnum); i++) \
00442           newblock[i] = this->values[i]; \
00443  \
00444         delete[] this->values; /* don't fetch pointer through valuesPtr() (avoids void* cast) */ \
00445         this->setValuesPtr(newblock); \
00446         this->userDataIsUsed = FALSE; \
00447       } \
00448     } \
00449     else { \
00450       this->setValuesPtr(new _valtype_[newnum]); \
00451       this->userDataIsUsed = FALSE; \
00452       this->maxNum = newnum; \
00453     } \
00454   } \
00455  \
00456   this->num = newnum; \
00457 }
00458 
00459 
00460 
00461 #define SO_MFIELD_MALLOC_SOURCE(_class_, _valtype_) \
00462 void \
00463 _class_::allocValues(int number) \
00464 { \
00465   SoMField::allocValues(number); \
00466 }
00467 
00468 
00469 
00470 #define SO_MFIELD_SOURCE_MALLOC(_class_, _valtype_, _valref_) \
00471   SO_MFIELD_REQUIRED_SOURCE(_class_); \
00472   SO_MFIELD_CONSTRUCTOR_SOURCE(_class_); \
00473   SO_MFIELD_MALLOC_SOURCE(_class_, _valtype_); \
00474   SO_MFIELD_VALUE_SOURCE(_class_, _valtype_, _valref_)
00475 
00476 
00477 
00478 #define SO_MFIELD_SOURCE(_class_, _valtype_, _valref_) \
00479   SO_MFIELD_REQUIRED_SOURCE(_class_); \
00480   SO_MFIELD_CONSTRUCTOR_SOURCE(_class_); \
00481   SO_MFIELD_ALLOC_SOURCE(_class_, _valtype_); \
00482   SO_MFIELD_VALUE_SOURCE(_class_, _valtype_, _valref_)
00483 
00484 
00485 #define SO_MFIELD_DERIVED_SOURCE(_class_, _valtype_, _valref_) \
00486   SO_MFIELD_REQUIRED_SOURCE(_class_); \
00487   SO_MFIELD_DERIVED_CONSTRUCTOR_SOURCE(_class_)
00488 
00489 #define SO_MFIELD_SETVALUESPOINTER_SOURCE(_class_, _valtype_, _usertype_) \
00490 void \
00491 _class_::setValuesPointer(const int numarg, _usertype_ * userdata) \
00492 { \
00493   this->makeRoom(0); \
00494   if (numarg > 0 && userdata) { \
00495     this->values = reinterpret_cast<_valtype_*>(userdata); /* reinterpret_cast is needed for certain special uses of this function, such as SoMFColor */ \
00496     this->userDataIsUsed = TRUE; \
00497     this->num = this->maxNum = numarg; \
00498     this->valueChanged(); \
00499   } \
00500 } \
00501 void \
00502 _class_::setValuesPointer(const int numarg, const _usertype_ * userdata) \
00503 { \
00504   this->setValuesPointer(numarg, const_cast<_usertype_*>(userdata)); \
00505 }
00506 
00507 #endif // !COIN_SOSUBFIELD_H

Generated on Wed Nov 23 19:00:40 2011 for FreeCAD by  doxygen 1.6.1