64#define SO__FIELD_HEADER(className) \
67 virtual SoType getTypeId() const; \
69 static SoType getClassTypeId(); \
72 const className & operator =(const className &f); \
76 virtual void copyFrom(const SoField &f); \
78 static void * createInstance(SoType* dynamicType = NULL); \
81 virtual SbBool isSame(const SoField &f) const; \
84 static SoType classTypeId
86#define SO__SFIELD_RW_HEADER(className) \
89 virtual SbBool readValue(SoInput *in); \
92 virtual void writeValue(SoOutput *out) const
94#define SO__MFIELD_RW_HEADER(className) \
97 virtual SbBool read1Value(SoInput *in, int index); \
100 virtual void write1Value(SoOutput *out, int index) const
103#define SO_FIELD_INIT_CLASS_CHECK_PARENT(className, parentClass) \
104 if (parentClass::getClassTypeId().isBad()) { \
105 SoDebugError::post( SO__QUOTE(className)"::initClass", \
106 SO__QUOTE(className)" initialized before parent class " \
107 SO__QUOTE(parentClass)"\n"); \
108 parentClass::initClass(); \
111#define SO_FIELD_INIT_CLASS_CHECK_PARENT(className, parentClass) \
112 if (parentClass::getClassTypeId().isBad()) \
113 parentClass::initClass()
116#define SO__FIELD_INIT_CLASS_INTERNAL(className,classPrintName,parentClass) \
117 SO_FIELD_INIT_CLASS_CHECK_PARENT(className, parentClass); \
118 classTypeId = SoType::createType(parentClass::getClassTypeId(), \
120 &className::createInstance)
122#define SO__FIELD_INIT_CLASS(className,classPrintName,parentClass) \
123 SO__FIELD_INIT_CLASS_INTERNAL(className,classPrintName,parentClass);
125#define SO__FIELD_INIT_ABSTRACT_CLASS_INTERNAL(className,classPrintName,parentClass) \
126 SO_FIELD_INIT_CLASS_CHECK_PARENT(className, parentClass); \
127 classTypeId = SoType::createType(parentClass::getClassTypeId(), \
131#define SO__FIELD_INIT_ABSTRACT_CLASS(className,classPrintName,parentClass) \
132 SO__FIELD_INIT_ABSTRACT_CLASS_INTERNAL(className,classPrintName,parentClass);
135#define SO__FIELD_EXIT_CLASS(className) { \
136 if (! SoType::removeType(classTypeId.getName())) { \
137 SoDebugError::post(SO__QUOTE(className)"::exitClass", \
138 "Unable to remove type (%s) for this class. Check exitClass() " \
139 "method is implemented and is called only once.\n", \
140 classTypeId.getName().getString() ); \
143 classTypeId = SoType::badType(); \
146#define SO__FIELD_EXIT_CLASS(className) \
147 SoType::removeType(classTypeId.getName()); \
148 classTypeId = SoType::badType()
151#define SO__FIELD_ID_ABSTRACT_SOURCE(className) \
153 SoType className::classTypeId; \
156 className::getClassTypeId() \
158 return classTypeId; \
162 className::getTypeId() const \
164 return classTypeId; \
167#define SO__FIELD_ID_SOURCE(className) \
168 SO__FIELD_ID_ABSTRACT_SOURCE(className); \
170 className::createInstance(SoType *) \
172 return (void *)(new className); \
176#define SO__FIELD_EQ_SAME_SOURCE(className) \
179className::copyFrom(const SoField &f) \
181 *this = * (const className *) &f; \
185className::isSame(const SoField &f) const \
187 return (getTypeId() == f.getTypeId() && \
188 (*this) == (const className &) f); \
204#define SO_SFIELD_REQUIRED_HEADER(className) \
205 SO__FIELD_HEADER(className)
213#define SO_SFIELD_CONSTRUCTOR_HEADER(className) \
228#define SO_SFIELD_VALUE_HEADER(className, valueType, valueRef) \
229 SO__SFIELD_RW_HEADER(className); \
235 { evaluate();
return value; } \
243 {
setValue(newValue);
return value; } \
250 {
return ! ((*this) == f); } \
266#define SO_SFIELD_DERIVED_VALUE_HEADER(className, valueType, valueRef) \
267 SO__SFIELD_RW_HEADER(className); \
270 valueRef operator =(valueRef newValue) \
271 { setValue(newValue); return (valueRef)value; }
280#define SO_SFIELD_HEADER(className, valueType, valueRef) \
281 SO_SFIELD_REQUIRED_HEADER(className); \
282 SO_SFIELD_CONSTRUCTOR_HEADER(className); \
283 SO_SFIELD_VALUE_HEADER(className, valueType, valueRef)
293#define SO_SFIELD_DERIVED_HEADER(className, valueType, valueRef) \
294 SO_SFIELD_REQUIRED_HEADER(className); \
295 SO_SFIELD_CONSTRUCTOR_HEADER(className); \
296 SO_SFIELD_DERIVED_VALUE_HEADER(className, valueType, valueRef)
311#define SO_MFIELD_REQUIRED_HEADER(className) \
312 SO__FIELD_HEADER(className)
320#define SO_MFIELD_CONSTRUCTOR_HEADER(className) \
335#define SO_MFIELD_VALUE_HEADER(className, valueType, valueRef) \
336 SO__MFIELD_RW_HEADER(className); \
342 valueRef operator [](
int i)
const \
343 { evaluate();
return values[i]; } \
353 valueType
const* getValues(
int start)
const \
354 { evaluate();
return const_cast<valueType const*
>(
static_cast<valueType *
>(values +
start)); } \
360 int find(valueRef targetValue,
SbBool addIfNotFound =
FALSE); \
370 void setValues(
int start,
int num, valueType
const* newValues); \
378 void set1Value(
int index, valueRef newValue); \
393 {
setValue(newValue);
return newValue; } \
404 {
return ! ((*this) == f); } \
410 virtual void enableDeleteValues() \
411 { setUserDataIsUsed(
false); } \
414 virtual void disableDeleteValues() \
415 { setUserDataIsUsed(
true); } \
422 virtual SbBool isDeleteValuesEnabled() \
423 {
return (!getUserDataIsUsed())?
TRUE:
FALSE; } \
426 virtual size_t getValueSize()
const {
return sizeof(valueType); } \
432 virtual void allocValues(
int newNum); \
435 virtual void deleteAllValues(); \
438 virtual void copyValue(
int to,
int from); \
443 virtual void* getValuesPointer(
int start) \
444 {
return static_cast<void*
>(values +
start); }
455#define SO_MFIELD_DERIVED_VALUE_HEADER(className, valueType, valueRef) \
456 SO__MFIELD_RW_HEADER(className); \
459 valueRef operator =(valueRef newValue) \
460 { setValue(newValue); return newValue; }
462#define SO_FIELD_SUPPORT_MEMOBJ() \
464 virtual bool isEnabledMemObj() { return true; } \
465 virtual SoMemoryObject* getMemObj() { return m_memObj; } \
466 virtual void setMemObj( SoMemoryObject* memObj ) { m_memObj = memObj; }
475#define SO_MFIELD_EDITING_HEADER(className, valueType) \
485 valueType *startEditing() { \
491 void finishEditing() { \
492 valueChanged(0,
getNum()); \
502#define SO_MFIELD_HEADER(className, valueType, valueRef) \
503 SO_MFIELD_REQUIRED_HEADER(className); \
504 SO_MFIELD_CONSTRUCTOR_HEADER(className); \
505 SO_MFIELD_EDITING_HEADER(className, valueType); \
506 SO_MFIELD_VALUE_HEADER(className, valueType, valueRef)
516#define SO_MFIELD_DERIVED_HEADER(className, valueType, valueRef) \
517 SO_MFIELD_REQUIRED_HEADER(className); \
518 SO_MFIELD_CONSTRUCTOR_HEADER(className); \
519 SO_MFIELD_DERIVED_VALUE_HEADER(className, valueType, valueRef)
535#define SO_SFIELD_INIT_CLASS(className,parentClass) \
536 SO__FIELD_INIT_CLASS(className, SO__QUOTE(className), parentClass);
538#define SO_SFIELD_EXIT_CLASS(className) \
539 SO__FIELD_EXIT_CLASS(className)
548#define SO_SFIELD_REQUIRED_SOURCE(className) \
550 SO__FIELD_ID_SOURCE(className) \
551 SO__FIELD_EQ_SAME_SOURCE(className) \
554className::operator =(const className &f) \
556 setValue(f.getValue()); \
561#define SO_FIELD_CHECK_INIT(className) { \
562 if (classTypeId.isBad()) { \
563 SoDebugError::post("Field Constructor", \
564 "Can't construct a field of type " \
565 SO__QUOTE(className) \
566 " until initClass() has been called"); \
567 className::initClass(); \
569 SoTypedObject::checkDatabase(SO__QUOTE(className), this, className::getClassTypeId(), classTypeId); \
572#define SO_FIELD_CHECK_INIT(className) { \
573 if (classTypeId.isBad()) { \
574 className::initClass(); \
585#define SO_SFIELD_CONSTRUCTOR_SOURCE(className) \
587className::className() \
590 SO_FIELD_CHECK_INIT(className) \
592className::~className() \
603#define SO_SFIELD_VALUE_SOURCE(className, valueType, valueRef) \
606className::setValue(valueRef newValue) \
610 if ( getSameValueNotificationEnabled() || getContainer() == NULL || !(value==newValue) ) \
618className::operator ==(const className &f) const \
620 return getValue() == f.getValue(); \
630#define SO_SFIELD_SOURCE(className, valueType, valueRef) \
631 SO_SFIELD_REQUIRED_SOURCE(className) \
632 SO_SFIELD_CONSTRUCTOR_SOURCE(className) \
633 SO_SFIELD_VALUE_SOURCE(className, valueType, valueRef)
642#define SO_SFIELD_DERIVED_CONSTRUCTOR_SOURCE(className) \
644className::className() \
646 SO_FIELD_CHECK_INIT(className) \
648className::~className() \
661#define SO_SFIELD_DERIVED_SOURCE(className, valueType, valueRef) \
662 SO_SFIELD_REQUIRED_SOURCE(className) \
663 SO_SFIELD_DERIVED_CONSTRUCTOR_SOURCE(className)
679#define SO_MFIELD_INIT_CLASS(className,parentClass) \
680 SO__FIELD_INIT_CLASS(className, SO__QUOTE(className), parentClass);
682#define SO_MFIELD_EXIT_CLASS(className) \
683 SO__FIELD_EXIT_CLASS(className)
692#define SO_MFIELD_REQUIRED_SOURCE(className) \
694 SO__FIELD_ID_SOURCE(className) \
695 SO__FIELD_EQ_SAME_SOURCE(className) \
698className::operator =(const className &f) \
700 if (f.getNum() < getNum()) \
702 setValues(0, f.getNum(), f.getValues(0)); \
715#define SO_MFIELD_CONSTRUCTOR_SOURCE(className) \
717className::className() \
719 SO_FIELD_CHECK_INIT(className) \
721 resetChangedStatus (); \
725className::~className() \
739#define SO_MFIELD_DERIVED_CONSTRUCTOR_SOURCE(className) \
741className::className() \
743 SO_FIELD_CHECK_INIT(className) \
744 resetChangedStatus (); \
747className::~className() \
758#define SO_MFIELD_VALUE_SOURCE(className, valueType, valueRef) \
761className::find(valueRef targetValue, SbBool addIfNotFound) \
763 int i, myNum = getNum(); \
766 for (i = 0; i < myNum; i++) \
767 if (values[i] == targetValue) \
772 set1Value(myNum, targetValue); \
778className::setValues(int start, int myNum, valueType const*newValues) \
780 int newNum = start + myNum, i; \
782 if (newNum > getNum()) \
786 for (i = 0; i < myNum; i++) \
787 values[start + i] = newValues[i]; \
789 valueChanged(start, myNum); \
794className::set1Value(int index, valueRef newValue) \
796 if (index >= getNum()) \
797 makeRoom(index + 1); \
798 else if ( !getSameValueNotificationEnabled() && (values[index]==newValue) ) \
801 values[index] = newValue; \
802 valueChanged(index, 1); \
807className::setValue(valueRef newValue) \
811 values[0] = newValue; \
817className::operator ==(const className &f) const \
819 int i, myNum = getNum(); \
820 valueType const*myVals, *itsVals; \
822 if (myNum != f.getNum()) \
825 myVals = getValues(0); \
826 itsVals = f.getValues(0); \
828 for (i = 0; i < myNum; i++) \
829 if (! (myVals[i] == itsVals[i])) \
836className::deleteAllValues() \
842className::copyValue(int to, int from) \
844 values[to] = values[from]; \
855#define SO_MFIELD_ALLOC_SOURCE(className, valueType) \
857className::allocValues(int newNum) \
859 if (values == NULL) { \
861 values = new valueType[newNum]; \
862 if (values == NULL) { \
863 SoMemoryError::post( "SO_MFIELD_ALLOC_SOURCE: Cannot allocate memory for the fields!" ); \
869 valueType *oldValues = values; \
873 values = new valueType[newNum]; \
874 if (values == NULL) { \
875 SoMemoryError::post( "SO_MFIELD_ALLOC_SOURCE: Cannot allocate memory for the fields!" ); \
879 for (i = 0; i < num && i < newNum; i++) \
880 values[i] = oldValues[i]; \
881 delete [] oldValues; \
886 delete [] oldValues; \
906#define SO_MFIELD_MALLOC_SOURCE(className, valueType) \
908className::allocValues(int newNum) \
910 void *before = (void *)values; \
912 if (values == NULL) { \
914 values = static_cast<valueType*>(malloc(sizeof(valueType) * newNum)); \
915 if (values == NULL) { \
916 SoMemoryError::post( "SO_MFIELD_MALLOC_SOURCE: Cannot allocate memory for the fields!" ); \
926 valueType value0 = *(static_cast<valueType*>(values)); \
927 if (isDeleteValuesEnabled()) \
928 free((char *) values);\
929 values = (valueType *) malloc(sizeof(valueType)); \
930 if (values == NULL) { \
931 SoMemoryError::post( "SO_MFIELD_MALLOC_SOURCE: Cannot allocate memory for the fields!" ); \
935 *((valueType *)values) = value0; \
936 setUserDataIsUsed(false);\
940 else if (newNum > 1) { \
941 void *after = NULL; \
942 if (getUserDataIsUsed() == false) { \
943 after = realloc(values, sizeof(valueType) * newNum); \
946 after = malloc(sizeof(valueType) * newNum); \
948 memcpy(after, before, sizeof(valueType) * (num < newNum ? num : newNum) ); \
950 if (after == NULL) { \
951 SoMemoryError::post( "SO_MFIELD_MALLOC_SOURCE: Cannot allocate memory for the fields!" ); \
955 values = (valueType *)after; \
958 if (getUserDataIsUsed() == false) { \
959 free((char *)values); \
966 if (before != (void *)values) { \
967 setUserDataIsUsed(false); \
979#define SO_MFIELD_SOURCE(className, valueType, valueRef) \
980 SO_MFIELD_REQUIRED_SOURCE(className) \
981 SO_MFIELD_CONSTRUCTOR_SOURCE(className) \
982 SO_MFIELD_VALUE_SOURCE(className, valueType, valueRef) \
983 SO_MFIELD_ALLOC_SOURCE(className, valueType)
992#define SO_MFIELD_SOURCE_MALLOC(className, valueType, valueRef) \
993 SO_MFIELD_REQUIRED_SOURCE(className) \
994 SO_MFIELD_CONSTRUCTOR_SOURCE(className) \
995 SO_MFIELD_VALUE_SOURCE(className, valueType, valueRef) \
996 SO_MFIELD_MALLOC_SOURCE(className, valueType)
1006#define SO_MFIELD_DERIVED_SOURCE(className, valueType, valueRef) \
1007 SO_MFIELD_REQUIRED_SOURCE(className); \
1008 SO_MFIELD_DERIVED_CONSTRUCTOR_SOURCE(className)
1016#define SO_MFIELD_SETVALUESPOINTER_HEADER(userType) \
1035 void setValuesPointer(
int num, userType
const*userData); \
1039 void setValuesPointer(
int num, userType *userData)
1049#include <Inventor/errors/SoDebugError.h>
1050#define SO_MFIELD_SETVALUESPOINTER_SOURCE(className, valueType, userType) \
1052className::setValuesPointer(int myNum, userType const*userData) \
1054 if (myNum > 0 && userData != NULL) { \
1055 if ( getUserDataIsUsed() && userData == (userType const*)values ) { \
1057 else if (getNum() > 0) { \
1060 values = (valueType *)userData; \
1061 setUserDataIsUsed(true); \
1063 valueChanged(0, num); \
1068className::setValuesPointer(int myNum, userType *userData) \
1070 setValuesPointer(myNum, (userType const*)userData); \
#define TRUE
Possible value of SbBool.
#define FALSE
Possible value of SbBool.
valueRef operator=(valueRef newValue)
Sets this field to newValue.
int operator==(const className &f) const
Returns TRUE if otherField is of the same type and has the same value as this field.
virtual size_t getValueSize() const
Gets the size of the value.
int operator!=(const className &f) const
Returns FALSE if otherField is of the same type and has the same value as this field.
valueRef getValue() const
void setValue(valueRef newValue)
Sets this field to newValue.
int getNum() const
Returns the number of tangents in the cache.