00001 #ifndef COIN_SOSUBFIELD_H
00002 #define COIN_SOSUBFIELD_H
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include <Inventor/SbBasic.h>
00028 #include <Inventor/SbName.h>
00029 #include <Inventor/C/tidbits.h>
00030 #include <assert.h>
00031
00032 #ifndef COIN_INTERNAL
00033
00034 #include <Inventor/fields/SoField.h>
00035 #include <Inventor/SoInput.h>
00036 #include <Inventor/SoOutput.h>
00037 #endif // !COIN_INTERNAL
00038
00039
00040
00041
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
00086
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
00110
00111
00112
00113 #define PRIVATE_FIELD_INIT_CLASS(_class_, _classname_, _parent_, _createfunc_) \
00114 do { \
00115 \
00116 assert(_parent_::getClassTypeId() != SoType::badType()); \
00117 \
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
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
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); \
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 \
00309 \
00310 \
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 \
00408 \
00409 \
00410 \
00411 \
00412 \
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; \
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 \
00428 \
00429 \
00430 \
00431 \
00432 \
00433 \
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; \
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); \
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