Open Inventor Reference
|
00001 /* 00002 * 00003 * Copyright (C) 2000 Silicon Graphics, Inc. All Rights Reserved. 00004 * 00005 * This library is free software; you can redistribute it and/or 00006 * modify it under the terms of the GNU Lesser General Public 00007 * License as published by the Free Software Foundation; either 00008 * version 2.1 of the License, or (at your option) any later version. 00009 * 00010 * This library is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 * Lesser General Public License for more details. 00014 * 00015 * Further, this software is distributed without any warranty that it is 00016 * free of the rightful claim of any third person regarding infringement 00017 * or the like. Any license provided herein, whether implied or 00018 * otherwise, applies only to this software file. Patent licenses, if 00019 * any, provided herein do not apply to combinations of this program with 00020 * other software, or any other product whatsoever. 00021 * 00022 * You should have received a copy of the GNU Lesser General Public 00023 * License along with this library; if not, write to the Free Software 00024 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00025 * 00026 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, 00027 * Mountain View, CA 94043, or: 00028 * 00029 * http://www.sgi.com 00030 * 00031 * For further information regarding this notice, see: 00032 * 00033 * http://oss.sgi.com/projects/GenInfo/NoticeExplan/ 00034 * 00035 */ 00036 00037 00038 /* 00039 * Copyright (C) 1990,91 Silicon Graphics, Inc. 00040 * 00041 _______________________________________________________________________ 00042 ______________ S I L I C O N G R A P H I C S I N C . ____________ 00043 | 00044 | $Revision: 1.1.1.1 $ 00045 | 00046 | Description: 00047 | This file defines some macros that implement things common to 00048 | many subclasses of SoField (actually, subclasses of SoSField 00049 | and SoMField). They may be used to make subclassing easier. 00050 | In the macros, the following parameters are used consistently: 00051 | 00052 | className = name of new field subclass 00053 | 00054 | valueType = type of field value (e.g., float, SbVec3f) 00055 | 00056 | valueRef = type of field value that can be passed or 00057 | returned. For simple types like float or 00058 | int, it is the same as valueType. For 00059 | aggregates such as SbVec3f, use a const 00060 | reference, e.g.: const SbVec3f & 00061 | 00062 | Macros for single-value (SoSField) field subclasses: 00063 | 00064 | Within class header: 00065 | 00066 | SO_SFIELD_REQUIRED_HEADER() 00067 | SO_SFIELD_CONSTRUCTOR_HEADER() 00068 | SO_SFIELD_VALUE_HEADER() 00069 | SO_SFIELD_DERIVED_VALUE_HEADER() 00070 | 00071 | SO_SFIELD_HEADER() 00072 | [includes REQUIRED, CONSTRUCTOR, and VALUE] 00073 | SO_SFIELD_DERIVED_HEADER() 00074 | [includes REQUIRED, CONSTRUCTOR, and DERIVED_VALUE] 00075 | 00076 | Within class source: 00077 | 00078 | SO_SFIELD_INIT_CLASS() 00079 | SO_SFIELD_REQUIRED_SOURCE() 00080 | SO_SFIELD_CONSTRUCTOR_SOURCE() 00081 | SO_SFIELD_VALUE_SOURCE() 00082 | 00083 | SO_SFIELD_SOURCE() 00084 | [includes REQUIRED, CONSTRUCTOR, and VALUE] 00085 | SO_SFIELD_DERIVED_SOURCE() 00086 | [includes REQUIRED and CONSTRUCTOR] 00087 | 00088 | Macros for multiple-value (SoMField) field subclasses: 00089 | 00090 | Within class header: 00091 | 00092 | SO_MFIELD_REQUIRED_HEADER() 00093 | SO_MFIELD_CONSTRUCTOR_HEADER() 00094 | SO_MFIELD_VALUE_HEADER() 00095 | SO_MFIELD_DERIVED_VALUE_HEADER() 00096 | 00097 | SO_MFIELD_HEADER() 00098 | [includes REQUIRED, CONSTRUCTOR, and VALUE] 00099 | SO_MFIELD_DERIVED_HEADER() 00100 | [includes REQUIRED and DERIVED_VALUE ] 00101 | 00102 | Within class source: 00103 | 00104 | SO_MFIELD_INIT_CLASS() 00105 | SO_MFIELD_REQUIRED_SOURCE() 00106 | SO_MFIELD_CONSTRUCTOR_SOURCE() 00107 | SO_MFIELD_DERIVED_CONSTRUCTOR_SOURCE() 00108 | SO_MFIELD_VALUE_SOURCE() 00109 | SO_MFIELD_ALLOC_SOURCE() 00110 | SO_MFIELD_MALLOC_SOURCE() 00111 | 00112 | SO_MFIELD_SOURCE() 00113 | [includes REQUIRED, CONSTRUCTOR, VALUE, and ALLOC] 00114 | SO_MFIELD_SOURCE_MALLOC() 00115 | [includes REQUIRED, CONSTRUCTOR, VALUE, and MALLOC] 00116 | SO_MFIELD_DERIVED_SOURCE() 00117 | [includes REQUIRED and DERIVED_CONSTRUCTOR] 00118 | 00119 | Author(s) : Paul S. Strauss 00120 | 00121 ______________ S I L I C O N G R A P H I C S I N C . ____________ 00122 _______________________________________________________________________ 00123 */ 00124 00125 #ifndef _SO_SUB_FIELD_ 00126 #define _SO_SUB_FIELD_ 00127 00128 #include <Inventor/system/SbSystem.h> 00129 #include <Inventor/fields/SoField.h> 00130 #include <Inventor/SoInput.h> 00131 #include <Inventor/SoOutput.h> 00132 00133 00139 00140 #define SO__FIELD_HEADER(className) \ 00141 public: \ 00142 virtual SoType getTypeId() const; \ 00143 static SoType getClassTypeId() { return classTypeId; } \ 00144 \ 00145 /* Copy from another field of same type */ \ 00146 const className & operator =(const className &f); \ 00147 \ 00148 SoINTERNAL public: \ 00149 /* Copy from another field of unknown type (assumed to be same type) */ \ 00150 virtual void copyFrom(const SoField &f); \ 00151 \ 00152 static void * createInstance(); /* for SoType */ \ 00153 \ 00154 /* Returns TRUE if fields are same type and have same values */ \ 00155 virtual SbBool isSame(const SoField &f) const; \ 00156 \ 00157 private: \ 00158 static SoType classTypeId 00159 00160 #define SO__SFIELD_RW_HEADER(className) \ 00161 private: \ 00162 /* Reads value of field from file */ \ 00163 virtual SbBool readValue(SoInput *in); \ 00164 \ 00165 /* Writes value of field to file */ \ 00166 virtual void writeValue(SoOutput *out) const 00167 00168 #define SO__MFIELD_RW_HEADER(className) \ 00169 private: \ 00170 /* Reads indexed value of field from file */ \ 00171 virtual SbBool read1Value(SoInput *in, int index); \ 00172 \ 00173 /* Writes one (indexed) value to file */ \ 00174 virtual void write1Value(SoOutput *out, int index) const 00175 00176 #define SO__FIELD_INIT_CLASS(className,classPrintName,parentClass) \ 00177 classTypeId = SoType::createType(parentClass::getClassTypeId(), \ 00178 classPrintName, \ 00179 &className::createInstance) 00180 00181 #define SO__FIELD_ID_SOURCE(className) \ 00182 \ 00183 SoType className::classTypeId; \ 00184 \ 00185 SoType \ 00186 className::getTypeId() const \ 00187 { \ 00188 return classTypeId; \ 00189 } \ 00190 void * \ 00191 className::createInstance() \ 00192 { \ 00193 return (void *)(new className); \ 00194 } 00195 00196 #define SO__FIELD_EQ_SAME_SOURCE(className) \ 00197 \ 00198 void \ 00199 className::copyFrom(const SoField &f) \ 00200 { \ 00201 *this = * (const className *) &f; \ 00202 } \ 00203 \ 00204 SbBool \ 00205 className::isSame(const SoField &f) const \ 00206 { \ 00207 return (getTypeId() == f.getTypeId() && \ 00208 (*this) == (const className &) f); \ 00209 } 00210 00217 00223 00224 #define SO_SFIELD_REQUIRED_HEADER(className) \ 00225 SO__FIELD_HEADER(className) 00226 00232 00233 #define SO_SFIELD_CONSTRUCTOR_HEADER(className) \ 00234 public: \ 00235 className(); \ 00236 virtual ~className() 00237 00244 00245 #define SO_SFIELD_VALUE_HEADER(className, valueType, valueRef) \ 00246 SO__SFIELD_RW_HEADER(className); \ 00247 public: \ 00248 /* Get the value */ \ 00249 valueRef getValue() const \ 00250 { evaluate(); return value; } \ 00251 \ 00252 /* Set value from a value of the appropriate type */ \ 00253 void setValue(valueRef newValue); \ 00254 valueRef operator =(valueRef newValue) \ 00255 { setValue(newValue); return value; } \ 00256 \ 00257 /* Equality/inequality test for fields of same type */ \ 00258 int operator ==(const className &f) const; \ 00259 int operator !=(const className &f) const \ 00260 { return ! ((*this) == f); } \ 00261 \ 00262 protected: \ 00263 valueType value 00264 00272 00273 #define SO_SFIELD_DERIVED_VALUE_HEADER(className, valueType, valueRef) \ 00274 SO__SFIELD_RW_HEADER(className); \ 00275 public: \ 00276 /* Since = operator is not inherited, we redefine it here */ \ 00277 valueRef operator =(valueRef newValue) \ 00278 { setValue(newValue); return value; } 00279 00286 00287 #define SO_SFIELD_HEADER(className, valueType, valueRef) \ 00288 SO_SFIELD_REQUIRED_HEADER(className); \ 00289 SO_SFIELD_CONSTRUCTOR_HEADER(className); \ 00290 SO_SFIELD_VALUE_HEADER(className, valueType, valueRef) 00291 00299 00300 #define SO_SFIELD_DERIVED_HEADER(className, valueType, valueRef) \ 00301 SO_SFIELD_REQUIRED_HEADER(className); \ 00302 SO_SFIELD_CONSTRUCTOR_HEADER(className); \ 00303 SO_SFIELD_DERIVED_VALUE_HEADER(className, valueType, valueRef) 00304 00311 00317 00318 #define SO_MFIELD_REQUIRED_HEADER(className) \ 00319 SO__FIELD_HEADER(className) 00320 00326 00327 #define SO_MFIELD_CONSTRUCTOR_HEADER(className) \ 00328 public: \ 00329 className(); \ 00330 virtual ~className() 00331 00338 00339 #define SO_MFIELD_VALUE_HEADER(className, valueType, valueRef) \ 00340 SO__MFIELD_RW_HEADER(className); \ 00341 public: \ 00342 /* Get indexed value */ \ 00343 valueRef operator [](int i) const \ 00344 { evaluate(); return values[i]; } \ 00345 \ 00346 /* Get pointer into array of values */ \ 00347 const valueType * getValues(int start) const \ 00348 { evaluate(); return (const valueType *)(values + start); } \ 00349 \ 00350 /* Finds index of value that is equal to given one, or -1 if not */ \ 00351 /* found. If not found and addIfNotFound is TRUE, the new value is */ \ 00352 /* appended to the field. */ \ 00353 int find(valueRef targetValue, \ 00354 SbBool addIfNotFound = FALSE); \ 00355 \ 00356 /* Set num values starting at index start from info in newValues */ \ 00357 void setValues(int start, int num, \ 00358 const valueType *newValues); \ 00359 \ 00360 /* Set 1 value at given index */ \ 00361 void set1Value(int index, valueRef newValue); \ 00362 \ 00363 /* Set field to have one value */ \ 00364 void setValue(valueRef newValue); \ 00365 valueRef operator =(valueRef newValue) \ 00366 { setValue(newValue); return newValue; } \ 00367 \ 00368 /* Equality/inequality test for fields of same type */ \ 00369 int operator ==(const className &f) const; \ 00370 int operator !=(const className &f) const \ 00371 { return ! ((*this) == f); } \ 00372 \ 00373 /* Get non-const pointer into array of values for batch edits */ \ 00374 valueType * startEditing() \ 00375 { evaluate(); return values; } \ 00376 \ 00377 /* Indicate that batch edits have finished */ \ 00378 void finishEditing() { valueChanged(); } \ 00379 \ 00380 protected: \ 00381 /* Allocates room for num values. Copies old values (if any) into */ \ 00382 /* new area. Deletes old area, if any. Will reduce room if needed, */ \ 00383 /* so a value of newNum==0 will delete all values. */ \ 00384 virtual void allocValues(int newNum); \ 00385 \ 00386 /* Deletes all current values, resets number of values */ \ 00387 virtual void deleteAllValues(); \ 00388 \ 00389 /* Copies value indexed by "from" to value indexed by "to" */ \ 00390 virtual void copyValue(int to, int from); \ 00391 \ 00392 valueType *values 00393 00401 00402 #define SO_MFIELD_DERIVED_VALUE_HEADER(className, valueType, valueRef) \ 00403 SO__MFIELD_RW_HEADER(className); \ 00404 public: \ 00405 /* Since = operator is not inherited, we redefine it here */ \ 00406 valueRef operator =(valueRef newValue) \ 00407 { setValue(newValue); return newValue; } 00408 00415 00416 #define SO_MFIELD_HEADER(className, valueType, valueRef) \ 00417 SO_MFIELD_REQUIRED_HEADER(className); \ 00418 SO_MFIELD_CONSTRUCTOR_HEADER(className); \ 00419 SO_MFIELD_VALUE_HEADER(className, valueType, valueRef) 00420 00428 00429 #define SO_MFIELD_DERIVED_HEADER(className, valueType, valueRef) \ 00430 SO_MFIELD_REQUIRED_HEADER(className); \ 00431 SO_MFIELD_CONSTRUCTOR_HEADER(className); \ 00432 SO_MFIELD_DERIVED_VALUE_HEADER(className, valueType, valueRef) 00433 00440 00447 00448 #define SO_SFIELD_INIT_CLASS(className,parentClass) \ 00449 SO__FIELD_INIT_CLASS(className, SO__QUOTE(className), parentClass) 00450 00457 00458 #define SO_SFIELD_REQUIRED_SOURCE(className) \ 00459 \ 00460 SO__FIELD_ID_SOURCE(className); \ 00461 SO__FIELD_EQ_SAME_SOURCE(className) \ 00462 \ 00463 const className & \ 00464 className::operator =(const className &f) \ 00465 { \ 00466 setValue(f.getValue()); \ 00467 return *this; \ 00468 } 00469 00475 00476 #define SO_SFIELD_CONSTRUCTOR_SOURCE(className) \ 00477 \ 00478 className::className() \ 00479 { \ 00480 } \ 00481 className::~className() \ 00482 { \ 00483 } 00484 00491 00492 #define SO_SFIELD_VALUE_SOURCE(className, valueType, valueRef) \ 00493 \ 00494 void \ 00495 className::setValue(valueRef newValue) \ 00496 { \ 00497 value = newValue; \ 00498 valueChanged(); \ 00499 } \ 00500 \ 00501 int \ 00502 className::operator ==(const className &f) const \ 00503 { \ 00504 return getValue() == f.getValue(); \ 00505 } 00506 00513 00514 #define SO_SFIELD_SOURCE(className, valueType, valueRef) \ 00515 SO_SFIELD_REQUIRED_SOURCE(className); \ 00516 SO_SFIELD_CONSTRUCTOR_SOURCE(className); \ 00517 SO_SFIELD_VALUE_SOURCE(className, valueType, valueRef) 00518 00526 00527 #define SO_SFIELD_DERIVED_SOURCE(className, valueType, valueRef) \ 00528 SO_SFIELD_REQUIRED_SOURCE(className); \ 00529 SO_SFIELD_CONSTRUCTOR_SOURCE(className) 00530 00537 00544 00545 #define SO_MFIELD_INIT_CLASS(className,parentClass) \ 00546 SO__FIELD_INIT_CLASS(className, SO__QUOTE(className), parentClass) 00547 00554 00555 #define SO_MFIELD_REQUIRED_SOURCE(className) \ 00556 \ 00557 SO__FIELD_ID_SOURCE(className); \ 00558 SO__FIELD_EQ_SAME_SOURCE(className) \ 00559 \ 00560 const className & \ 00561 className::operator =(const className &f) \ 00562 { \ 00563 if (f.getNum() < getNum()) \ 00564 deleteAllValues(); \ 00565 setValues(0, f.getNum(), f.getValues(0)); \ 00566 return *this; \ 00567 } 00568 00577 00578 #define SO_MFIELD_CONSTRUCTOR_SOURCE(className) \ 00579 \ 00580 className::className() \ 00581 { \ 00582 values = NULL; \ 00583 } \ 00584 \ 00585 className::~className() \ 00586 { \ 00587 deleteAllValues(); \ 00588 } 00589 00597 00598 #define SO_MFIELD_DERIVED_CONSTRUCTOR_SOURCE(className) \ 00599 \ 00600 className::className() \ 00601 { \ 00602 } \ 00603 \ 00604 className::~className() \ 00605 { \ 00606 } 00607 00614 00615 #define SO_MFIELD_VALUE_SOURCE(className, valueType, valueRef) \ 00616 \ 00617 int \ 00618 className::find(valueRef targetValue, SbBool addIfNotFound) \ 00619 { \ 00620 int i, localNum = getNum(); \ 00621 \ 00622 for (i = 0; i < localNum; i++) \ 00623 if (values[i] == targetValue) \ 00624 return i; \ 00625 \ 00626 if (addIfNotFound) \ 00627 set1Value(localNum, targetValue); \ 00628 \ 00629 return -1; \ 00630 } \ 00631 \ 00632 void \ 00633 className::setValues(int start, int localNum, const valueType *newValues) \ 00634 { \ 00635 int newNum = start + localNum, i; \ 00636 \ 00637 if (newNum > getNum()) \ 00638 makeRoom(newNum); \ 00639 \ 00640 for (i = 0; i < localNum; i++) \ 00641 values[start + i] = newValues[i]; \ 00642 \ 00643 valueChanged(); \ 00644 } \ 00645 \ 00646 void \ 00647 className::set1Value(int index, valueRef newValue) \ 00648 { \ 00649 if (index >= getNum()) \ 00650 makeRoom(index + 1); \ 00651 values[index] = newValue; \ 00652 valueChanged(); \ 00653 } \ 00654 \ 00655 void \ 00656 className::setValue(valueRef newValue) \ 00657 { \ 00658 makeRoom(1); \ 00659 values[0] = newValue; \ 00660 valueChanged(); \ 00661 } \ 00662 \ 00663 int \ 00664 className::operator ==(const className &f) const \ 00665 { \ 00666 int i, localNum = getNum(); \ 00667 const valueType *myVals, *itsVals; \ 00668 \ 00669 if (localNum != f.getNum()) \ 00670 return FALSE; \ 00671 \ 00672 myVals = getValues(0); \ 00673 itsVals = f.getValues(0); \ 00674 \ 00675 for (i = 0; i < localNum; i++) \ 00676 if (! (myVals[i] == itsVals[i])) \ 00677 return FALSE; \ 00678 \ 00679 return TRUE; \ 00680 } \ 00681 \ 00682 void \ 00683 className::deleteAllValues() \ 00684 { \ 00685 allocValues(0); \ 00686 } \ 00687 \ 00688 void \ 00689 className::copyValue(int to, int from) \ 00690 { \ 00691 values[to] = values[from]; \ 00692 } 00693 00701 00702 #define SO_MFIELD_ALLOC_SOURCE(className, valueType) \ 00703 void \ 00704 className::allocValues(int newNum) \ 00705 { \ 00706 if (values == NULL) { \ 00707 if (newNum > 0) \ 00708 values = new valueType[newNum]; \ 00709 } \ 00710 else { \ 00711 valueType *oldValues = values; \ 00712 int i; \ 00713 \ 00714 if (newNum > 0) { \ 00715 values = new valueType[newNum]; \ 00716 for (i = 0; i < num && i < newNum; i++) \ 00717 values[i] = oldValues[i]; \ 00718 } \ 00719 else \ 00720 values = NULL; \ 00721 delete [] oldValues; \ 00722 } \ 00723 \ 00724 num = maxNum = newNum; \ 00725 } 00726 00736 00737 #define SO_MFIELD_MALLOC_SOURCE(className, valueType) \ 00738 void \ 00739 className::allocValues(int newNum) \ 00740 { \ 00741 if (values == NULL) { \ 00742 if (newNum > 0) \ 00743 values = (valueType *) malloc(sizeof(valueType) * newNum); \ 00744 } \ 00745 else { \ 00746 if (newNum > 0) \ 00747 values = (valueType *) realloc(values, sizeof(valueType)*newNum); \ 00748 else { \ 00749 free((char *) values); \ 00750 values = NULL; \ 00751 } \ 00752 } \ 00753 \ 00754 num = maxNum = newNum; \ 00755 } 00756 00764 00765 #define SO_MFIELD_SOURCE(className, valueType, valueRef) \ 00766 SO_MFIELD_REQUIRED_SOURCE(className) \ 00767 SO_MFIELD_CONSTRUCTOR_SOURCE(className) \ 00768 SO_MFIELD_VALUE_SOURCE(className, valueType, valueRef) \ 00769 SO_MFIELD_ALLOC_SOURCE(className, valueType) 00770 00777 00778 #define SO_MFIELD_SOURCE_MALLOC(className, valueType, valueRef) \ 00779 SO_MFIELD_REQUIRED_SOURCE(className) \ 00780 SO_MFIELD_CONSTRUCTOR_SOURCE(className) \ 00781 SO_MFIELD_VALUE_SOURCE(className, valueType, valueRef) \ 00782 SO_MFIELD_MALLOC_SOURCE(className, valueType) 00783 00791 00792 #define SO_MFIELD_DERIVED_SOURCE(className, valueType, valueRef) \ 00793 SO_MFIELD_REQUIRED_SOURCE(className); \ 00794 SO_MFIELD_DERIVED_CONSTRUCTOR_SOURCE(className) 00795 00796 00797 #endif /* _SO_SUB_FIELD_ */