Coin Logo http://www.sim.no
http://www.coin3d.org

SoSubField.h

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

Copyright © 1998-2007 by Systems in Motion AS. All rights reserved.

Generated on Mon Feb 23 16:33:32 2009 for Coin by Doxygen. 1.5.8