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