![]() |
http://www.sim.no/ http://www.coin3d.org/ |
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) by Kongsberg Oil & Gas Technologies. 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 Oil & Gas Technologies 00018 * about acquiring a Coin Professional Edition License. 00019 * 00020 * See http://www.coin3d.org/ for more information. 00021 * 00022 * Kongsberg Oil & Gas Technologies, Bygdoy Alle 5, 0257 Oslo, 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
Copyright © 1998-2010 by Kongsberg Oil & Gas Technologies. All rights reserved.
Generated for Coin by Doxygen 1.5.6.