53#include <Inventor/fields/SoField.h>
54#include <Inventor/SoInput.h>
55#include <Inventor/SoOutput.h>
56#include <Inventor/errors/SoMemoryError.h>
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); \
234 valueRef getValue() const \
235 { evaluate();
return value; } \
239 void setValue(valueRef newValue); \
242 valueRef operator =(valueRef newValue) \
243 { setValue(newValue);
return value; } \
246 int operator ==(
const className &f)
const; \
249 int operator !=(
const className &f)
const \
250 {
return ! ((*this) == f); } \
253 virtual size_t getValueSize()
const {
return sizeof(valueType); } \
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); \
385 void setValue(valueRef newValue); \
392 valueRef operator =(valueRef newValue) \
393 { setValue(newValue);
return newValue; } \
398 int operator ==(
const className &f)
const; \
403 int operator !=(
const className &f)
const \
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); \