![]() |
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) 1998-2008 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((coin_atexit_f*)_class_::atexit_cleanup); \ 00122 } while (0) 00123 00124 00125 00126 #define SO_SFIELD_INIT_CLASS(_class_, _parent_) \ 00127 do { \ 00128 const char * classname = SO__QUOTE(_class_); \ 00129 PRIVATE_FIELD_INIT_CLASS(_class_, classname, _parent_, &_class_::createInstance); \ 00130 } while (0) 00131 00132 #define SO_SFIELD_CONSTRUCTOR_SOURCE(_class_) \ 00133 _class_::_class_(void) { assert(_class_::classTypeId != SoType::badType()); } \ 00134 _class_::~_class_() { } 00135 00136 00137 00138 #define SO_SFIELD_VALUE_SOURCE(_class_, _valtype_, _valref_) \ 00139 void \ 00140 _class_::setValue(_valref_ valuearg) { \ 00141 this->value = valuearg; \ 00142 this->valueChanged(); \ 00143 } \ 00144 \ 00145 SbBool \ 00146 _class_::operator==(const _class_ & field) const \ 00147 { \ 00148 return (this->getValue() == field.getValue()); \ 00149 } 00150 00151 00152 #define PRIVATE_TYPEID_SOURCE(_class_) \ 00153 SoType _class_::getTypeId(void) const { return _class_::classTypeId; } \ 00154 SoType _class_::getClassTypeId(void) { return _class_::classTypeId; } \ 00155 void * _class_::createInstance(void) { return new _class_; } \ 00156 SoType _class_::classTypeId STATIC_SOTYPE_INIT 00157 00158 00159 #define PRIVATE_EQUALITY_SOURCE(_class_) \ 00160 void \ 00161 _class_::copyFrom(const SoField & field) \ 00162 { \ 00163 this->operator=((const _class_ &)field); \ 00164 } \ 00165 \ 00166 SbBool \ 00167 _class_::isSame(const SoField & field) const \ 00168 { \ 00169 if (field.getTypeId() != this->getTypeId()) return FALSE; \ 00170 return this->operator==((const _class_ &) field); \ 00171 } 00172 00173 00174 00175 #define SO_SFIELD_REQUIRED_SOURCE(_class_) \ 00176 PRIVATE_TYPEID_SOURCE(_class_); \ 00177 PRIVATE_EQUALITY_SOURCE(_class_); \ 00178 \ 00179 const _class_ & \ 00180 _class_::operator=(const _class_ & field) \ 00181 { \ 00182 this->setValue(field.getValue()); \ 00183 return *this; \ 00184 } 00185 00186 00187 00188 #define SO_SFIELD_SOURCE(_class_, _valtype_, _valref_) \ 00189 SO_SFIELD_CONSTRUCTOR_SOURCE(_class_); \ 00190 SO_SFIELD_VALUE_SOURCE(_class_, _valtype_, _valref_); \ 00191 SO_SFIELD_REQUIRED_SOURCE(_class_) 00192 00193 00194 00195 #define SO_SFIELD_DERIVED_SOURCE(_class_, _valtype_, _valref_) \ 00196 SO_SFIELD_CONSTRUCTOR_SOURCE(_class_); \ 00197 SO_SFIELD_REQUIRED_SOURCE(_class_) 00198 00199 00200 /************************************************************************** 00201 * 00202 * Header macros for multiple-value fields. 00203 * 00204 **************************************************************************/ 00205 00206 #define PRIVATE_MFIELD_IO_HEADER() \ 00207 private: \ 00208 virtual SbBool read1Value(SoInput * in, int idx); \ 00209 virtual void write1Value(SoOutput * out, int idx) const 00210 00211 00212 00213 #define SO_MFIELD_VALUE_HEADER(_class_, _valtype_, _valref_) \ 00214 PRIVATE_MFIELD_IO_HEADER(); \ 00215 protected: \ 00216 virtual void deleteAllValues(void); \ 00217 virtual void copyValue(int to, int from); \ 00218 virtual int fieldSizeof(void) const; \ 00219 virtual void * valuesPtr(void); \ 00220 virtual void setValuesPtr(void * ptr); \ 00221 virtual void allocValues(int num); \ 00222 \ 00223 _valtype_ * values; \ 00224 public: \ 00225 _valref_ operator[](const int idx) const \ 00226 { this->evaluate(); return this->values[idx]; } \ 00227 \ 00230 const _valtype_ * getValues(const int start) const \ 00231 { this->evaluate(); return const_cast<const _valtype_ *>(this->values + start); } \ 00232 int find(_valref_ value, SbBool addifnotfound = FALSE); \ 00233 void setValues(const int start, const int num, const _valtype_ * newvals); \ 00234 void set1Value(const int idx, _valref_ value); \ 00235 void setValue(_valref_ value); \ 00236 _valref_ operator=(_valref_ val) { this->setValue(val); return val; } \ 00237 SbBool operator==(const _class_ & field) const; \ 00238 SbBool operator!=(const _class_ & field) const { return !operator==(field); } \ 00239 _valtype_ * startEditing(void) { this->evaluate(); return this->values; } \ 00240 void finishEditing(void) { this->valueChanged(); } 00241 00242 #define SO_MFIELD_DERIVED_VALUE_HEADER(_class_, _valtype_, _valref_) \ 00243 PRIVATE_MFIELD_IO_HEADER(); \ 00244 public: \ 00245 _valref_ operator=(_valref_ val) { this->setValue(val); return val; } 00246 00247 00248 00249 #define SO_MFIELD_HEADER(_class_, _valtype_, _valref_) \ 00250 SO_SFIELD_CONSTRUCTOR_HEADER(_class_); \ 00251 SO_SFIELD_REQUIRED_HEADER(_class_); \ 00252 SO_MFIELD_VALUE_HEADER(_class_, _valtype_, _valref_) 00253 00254 00255 00256 #define SO_MFIELD_DERIVED_HEADER(_class_, _valtype_, _valref_) \ 00257 SO_SFIELD_CONSTRUCTOR_HEADER(_class_); \ 00258 SO_SFIELD_REQUIRED_HEADER(_class_); \ 00259 SO_MFIELD_DERIVED_VALUE_HEADER(_class_, _valtype_, _valref_) 00260 00261 #define SO_MFIELD_SETVALUESPOINTER_HEADER(_valtype_) \ 00262 void setValuesPointer(const int num, const _valtype_ * userdata); \ 00263 void setValuesPointer(const int num, _valtype_ * userdata) 00264 00265 00266 /************************************************************************** 00267 * 00268 * Source macros for multiple-value fields. 00269 * 00270 **************************************************************************/ 00271 00272 00273 #define SO_MFIELD_INIT_CLASS(_class_, _parent_) \ 00274 SO_SFIELD_INIT_CLASS(_class_, _parent_) 00275 00276 00277 00278 #define SO_MFIELD_CONSTRUCTOR_SOURCE(_class_) \ 00279 _class_::_class_(void) \ 00280 { \ 00281 assert(_class_::classTypeId != SoType::badType()); \ 00282 this->values = NULL; \ 00283 } \ 00284 \ 00285 _class_::~_class_(void) \ 00286 { \ 00287 this->enableNotify(FALSE); /* Avoid notifying destructed containers. */ \ 00288 this->deleteAllValues(); \ 00289 } 00290 00291 00292 00293 #define SO_MFIELD_DERIVED_CONSTRUCTOR_SOURCE(_class_) \ 00294 _class_::_class_(void) { } \ 00295 _class_::~_class_(void) { } 00296 00297 00298 00299 #define SO_MFIELD_REQUIRED_SOURCE(_class_) \ 00300 PRIVATE_TYPEID_SOURCE(_class_); \ 00301 PRIVATE_EQUALITY_SOURCE(_class_); \ 00302 const _class_ & \ 00303 _class_::operator=(const _class_ & field) \ 00304 { \ 00305 /* The allocValues() call is needed, as setValues() doesn't */ \ 00306 /* necessarily make the field's getNum() size become the same */ \ 00307 /* as the second argument (only if it expands on the old size). */ \ 00308 this->allocValues(field.getNum()); \ 00309 \ 00310 this->setValues(0, field.getNum(), field.getValues(0)); \ 00311 return *this; \ 00312 } 00313 00314 00315 00316 #define SO_MFIELD_VALUE_SOURCE(_class_, _valtype_, _valref_) \ 00317 int \ 00318 _class_::fieldSizeof(void) const \ 00319 { \ 00320 return sizeof(_valtype_); \ 00321 } \ 00322 \ 00323 void * \ 00324 _class_::valuesPtr(void) \ 00325 { \ 00326 return (void *)this->values; \ 00327 } \ 00328 \ 00329 void \ 00330 _class_::setValuesPtr(void * ptr) \ 00331 { \ 00332 this->values = (_valtype_ *)ptr; \ 00333 } \ 00334 \ 00335 int \ 00336 _class_::find(_valref_ value, SbBool addifnotfound) \ 00337 { \ 00338 evaluate(); \ 00339 for (int i=0; i < this->num; i++) if (this->values[i] == value) return i; \ 00340 \ 00341 if (addifnotfound) this->set1Value(this->num, value); \ 00342 return -1; \ 00343 } \ 00344 \ 00345 void \ 00346 _class_::setValues(const int start, const int numarg, const _valtype_ * newvals) \ 00347 { \ 00348 if (start+numarg > this->maxNum) this->allocValues(start+numarg); \ 00349 else if (start+numarg > this->num) this->num = start+numarg; \ 00350 \ 00351 for (int i=0; i < numarg; i++) \ 00352 this->values[i+start] = (_valtype_) newvals[i]; \ 00353 this->valueChanged(); \ 00354 } \ 00355 \ 00356 void \ 00357 _class_::set1Value(const int idx, _valref_ value) \ 00358 { \ 00359 if (idx+1 > this->maxNum) this->allocValues(idx+1); \ 00360 else if (idx+1 > this->num) this->num = idx+1; \ 00361 this->values[idx] = value; \ 00362 this->valueChanged(); \ 00363 } \ 00364 \ 00365 void \ 00366 _class_::setValue(_valref_ value) \ 00367 { \ 00368 this->allocValues(1); \ 00369 this->values[0] = value; \ 00370 this->valueChanged(); \ 00371 } \ 00372 \ 00373 SbBool \ 00374 _class_::operator==(const _class_ & field) const \ 00375 { \ 00376 if (this == &field) return TRUE; \ 00377 if (this->getNum() != field.getNum()) return FALSE; \ 00378 \ 00379 const _valtype_ * const lhs = this->getValues(0); \ 00380 const _valtype_ * const rhs = field.getValues(0); \ 00381 for (int i = 0; i < this->num; i++) if (lhs[i] != rhs[i]) return FALSE; \ 00382 return TRUE; \ 00383 } \ 00384 \ 00385 \ 00386 void \ 00387 _class_::deleteAllValues(void) \ 00388 { \ 00389 this->setNum(0); \ 00390 } \ 00391 \ 00392 \ 00393 void \ 00394 _class_::copyValue(int to, int from) \ 00395 { \ 00396 this->values[to] = this->values[from]; \ 00397 } 00398 00399 00400 #define SO_MFIELD_ALLOC_SOURCE(_class_, _valtype_) \ 00401 void \ 00402 _class_::allocValues(int newnum) \ 00403 { \ 00404 /* Important notice: the "malloc-version" of this method is found */ \ 00405 /* in SoMField.cpp. If you make modifications here, do check whether */ \ 00406 /* or not they should be matched with modifications in that method */ \ 00407 /* aswell. */ \ 00408 \ 00409 /* these must be declared here as a gcc 4.0.0 bug workaround */ \ 00410 int i; \ 00411 int oldmaxnum; \ 00412 _valtype_ * newblock; \ 00413 assert(newnum >= 0); \ 00414 \ 00415 if (newnum == 0) { \ 00416 if (!this->userDataIsUsed) delete[] this->values; /* don't fetch pointer through valuesPtr() (avoids void* cast) */ \ 00417 this->setValuesPtr(NULL); \ 00418 this->maxNum = 0; \ 00419 this->userDataIsUsed = FALSE; \ 00420 } \ 00421 else if (newnum > this->maxNum || newnum < this->num) { \ 00422 if (this->valuesPtr()) { \ 00423 \ 00424 /* Allocation strategy is to repeatedly double the size of the */ \ 00425 /* allocated block until it will at least match the requested size. */ \ 00426 /* (Unless the requested size is less than what we've got, */ \ 00427 /* then we'll repeatedly halve the allocation size.) */ \ 00428 /* */ \ 00429 /* I think this will handle both cases quite gracefully: */ \ 00430 /* 1) newnum > this->maxNum, 2) newnum < num */ \ 00431 oldmaxnum = this->maxNum; \ 00432 while (newnum > this->maxNum) this->maxNum *= 2; \ 00433 while ((this->maxNum / 2) >= newnum) this->maxNum /= 2; \ 00434 \ 00435 if (oldmaxnum != this->maxNum) { \ 00436 newblock = new _valtype_[this->maxNum]; \ 00437 \ 00438 for (i=0; i < SbMin(this->num, newnum); i++) \ 00439 newblock[i] = this->values[i]; \ 00440 \ 00441 delete[] this->values; /* don't fetch pointer through valuesPtr() (avoids void* cast) */ \ 00442 this->setValuesPtr(newblock); \ 00443 this->userDataIsUsed = FALSE; \ 00444 } \ 00445 } \ 00446 else { \ 00447 this->setValuesPtr(new _valtype_[newnum]); \ 00448 this->userDataIsUsed = FALSE; \ 00449 this->maxNum = newnum; \ 00450 } \ 00451 } \ 00452 \ 00453 this->num = newnum; \ 00454 } 00455 00456 00457 00458 #define SO_MFIELD_MALLOC_SOURCE(_class_, _valtype_) \ 00459 void \ 00460 _class_::allocValues(int number) \ 00461 { \ 00462 SoMField::allocValues(number); \ 00463 } 00464 00465 00466 00467 #define SO_MFIELD_SOURCE_MALLOC(_class_, _valtype_, _valref_) \ 00468 SO_MFIELD_REQUIRED_SOURCE(_class_); \ 00469 SO_MFIELD_CONSTRUCTOR_SOURCE(_class_); \ 00470 SO_MFIELD_MALLOC_SOURCE(_class_, _valtype_); \ 00471 SO_MFIELD_VALUE_SOURCE(_class_, _valtype_, _valref_) 00472 00473 00474 00475 #define SO_MFIELD_SOURCE(_class_, _valtype_, _valref_) \ 00476 SO_MFIELD_REQUIRED_SOURCE(_class_); \ 00477 SO_MFIELD_CONSTRUCTOR_SOURCE(_class_); \ 00478 SO_MFIELD_ALLOC_SOURCE(_class_, _valtype_); \ 00479 SO_MFIELD_VALUE_SOURCE(_class_, _valtype_, _valref_) 00480 00481 00482 #define SO_MFIELD_DERIVED_SOURCE(_class_, _valtype_, _valref_) \ 00483 SO_MFIELD_REQUIRED_SOURCE(_class_); \ 00484 SO_MFIELD_DERIVED_CONSTRUCTOR_SOURCE(_class_) 00485 00486 #define SO_MFIELD_SETVALUESPOINTER_SOURCE(_class_, _valtype_, _usertype_) \ 00487 void \ 00488 _class_::setValuesPointer(const int numarg, _usertype_ * userdata) \ 00489 { \ 00490 this->makeRoom(0); \ 00491 if (numarg > 0 && userdata) { \ 00492 this->values = (_valtype_*) userdata; \ 00493 this->userDataIsUsed = TRUE; \ 00494 this->num = this->maxNum = numarg; \ 00495 this->valueChanged(); \ 00496 } \ 00497 } \ 00498 void \ 00499 _class_::setValuesPointer(const int numarg, const _usertype_ * userdata) \ 00500 { \ 00501 this->setValuesPointer(numarg, (_usertype_*) userdata); \ 00502 } 00503 00504 #endif // !COIN_SOSUBFIELD_H
Copyright © 1998-2008 by Kongsberg SIM. All rights reserved.
Generated on Sat Nov 8 00:38:09 2008 for Coin by Doxygen 1.5.6.