![]() |
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-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