Open Inventor Release 2024.1.1
 
Loading...
Searching...
No Matches
SoSubField.h
1/*=======================================================================
2 * Copyright 1991-1996, Silicon Graphics, Inc.
3 * ALL RIGHTS RESERVED
4 *
5 * UNPUBLISHED -- Rights reserved under the copyright laws of the United
6 * States. Use of a copyright notice is precautionary only and does not
7 * imply publication or disclosure.
8 *
9 * U.S. GOVERNMENT RESTRICTED RIGHTS LEGEND:
10 * Use, duplication or disclosure by the Government is subject to restrictions
11 * as set forth in FAR 52.227.19(c)(2) or subparagraph (c)(1)(ii) of the Rights
12 * in Technical Data and Computer Software clause at DFARS 252.227-7013 and/or
13 * in similar or successor clauses in the FAR, or the DOD or NASA FAR
14 * Supplement. Contractor/manufacturer is Silicon Graphics, Inc.,
15 * 2011 N. Shoreline Blvd. Mountain View, CA 94039-7311.
16 *
17 * THE CONTENT OF THIS WORK CONTAINS CONFIDENTIAL AND PROPRIETARY
18 * INFORMATION OF SILICON GRAPHICS, INC. ANY DUPLICATION, MODIFICATION,
19 * DISTRIBUTION, OR DISCLOSURE IN ANY FORM, IN WHOLE, OR IN PART, IS STRICTLY
20 * PROHIBITED WITHOUT THE PRIOR EXPRESS WRITTEN PERMISSION OF SILICON
21 * GRAPHICS, INC.
22**=======================================================================*/
23/*=======================================================================
24** Author : Paul S. Strauss (MMM yyyy)
25**=======================================================================*/
26/*=======================================================================
27 *** THE CONTENT OF THIS WORK IS PROPRIETARY TO FEI S.A.S, (FEI S.A.S.), ***
28 *** AND IS DISTRIBUTED UNDER A LICENSE AGREEMENT. ***
29 *** ***
30 *** REPRODUCTION, DISCLOSURE, OR USE, IN WHOLE OR IN PART, OTHER THAN AS ***
31 *** SPECIFIED IN THE LICENSE ARE NOT TO BE UNDERTAKEN EXCEPT WITH PRIOR ***
32 *** WRITTEN AUTHORIZATION OF FEI S.A.S. ***
33 *** ***
34 *** RESTRICTED RIGHTS LEGEND ***
35 *** USE, DUPLICATION, OR DISCLOSURE BY THE GOVERNMENT OF THE CONTENT OF THIS ***
36 *** WORK OR RELATED DOCUMENTATION IS SUBJECT TO RESTRICTIONS AS SET FORTH IN ***
37 *** SUBPARAGRAPH (C)(1) OF THE COMMERCIAL COMPUTER SOFTWARE RESTRICTED RIGHT ***
38 *** CLAUSE AT FAR 52.227-19 OR SUBPARAGRAPH (C)(1)(II) OF THE RIGHTS IN ***
39 *** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 52.227-7013. ***
40 *** ***
41 *** COPYRIGHT (C) 1996-2020 BY FEI S.A.S, ***
42 *** BORDEAUX, FRANCE ***
43 *** ALL RIGHTS RESERVED ***
44**=======================================================================*/
45/*=======================================================================
46** Modified by : VSG (MMM YYYY)
47**=======================================================================*/
48
49
50#ifndef _SO_SUB_FIELD_
51#define _SO_SUB_FIELD_
52
53#include <Inventor/fields/SoField.h>
54#include <Inventor/SoInput.h>
55#include <Inventor/SoOutput.h>
56#include <Inventor/errors/SoMemoryError.h>
57
58//===========================================================================
59//
60// These are all internal macros used by some of the public ones.
61//
62//===========================================================================
63
64#define SO__FIELD_HEADER(className) \
65 public: \
66 \
67 virtual SoType getTypeId() const; \
68 \
69 static SoType getClassTypeId(); \
70\
71 \
72 const className & operator =(const className &f); \
73\
74 private:\
75 /* Copy from another field of unknown type (assumed to be same type) */ \
76 virtual void copyFrom(const SoField &f); \
77\
78 static void * createInstance(SoType* dynamicType = NULL); \
79\
80 /* Returns TRUE if fields are same type and have same values */ \
81 virtual SbBool isSame(const SoField &f) const; \
82\
83 private: \
84 static SoType classTypeId
85
86#define SO__SFIELD_RW_HEADER(className) \
87 private: \
88 /* Reads value of field from file */ \
89 virtual SbBool readValue(SoInput *in); \
90\
91 /* Writes value of field to file */ \
92 virtual void writeValue(SoOutput *out) const
93
94#define SO__MFIELD_RW_HEADER(className) \
95 private: \
96 /* Reads indexed value of field from file */ \
97 virtual SbBool read1Value(SoInput *in, int index); \
98\
99 /* Writes one (indexed) value to file */ \
100 virtual void write1Value(SoOutput *out, int index) const
101
102#if defined(_DEBUG)
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(); \
109 }
110#else
111#define SO_FIELD_INIT_CLASS_CHECK_PARENT(className, parentClass) \
112 if (parentClass::getClassTypeId().isBad()) \
113 parentClass::initClass()
114#endif
115
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(), \
119 classPrintName, \
120 &className::createInstance)
121
122#define SO__FIELD_INIT_CLASS(className,classPrintName,parentClass) \
123 SO__FIELD_INIT_CLASS_INTERNAL(className,classPrintName,parentClass);
124
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(), \
128 classPrintName, \
129 NULL)
130
131#define SO__FIELD_INIT_ABSTRACT_CLASS(className,classPrintName,parentClass) \
132 SO__FIELD_INIT_ABSTRACT_CLASS_INTERNAL(className,classPrintName,parentClass);
133
134#if defined(_DEBUG)
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() ); \
141 } \
142 else \
143 classTypeId = SoType::badType(); \
144}
145#else
146#define SO__FIELD_EXIT_CLASS(className) \
147 SoType::removeType(classTypeId.getName()); \
148 classTypeId = SoType::badType()
149#endif
150
151#define SO__FIELD_ID_ABSTRACT_SOURCE(className) \
152 \
153 SoType className::classTypeId; \
154 \
155 SoType \
156 className::getClassTypeId() \
157 { \
158 return classTypeId; \
159 } \
160 \
161 SoType \
162 className::getTypeId() const \
163 { \
164 return classTypeId; \
165 }
166
167#define SO__FIELD_ID_SOURCE(className) \
168 SO__FIELD_ID_ABSTRACT_SOURCE(className); \
169 void * \
170 className::createInstance(SoType *) \
171 { \
172 return (void *)(new className); \
173 }
174
175
176#define SO__FIELD_EQ_SAME_SOURCE(className) \
177\
178void \
179className::copyFrom(const SoField &f) \
180{ \
181 *this = * (const className *) &f; \
182} \
183\
184SbBool \
185className::isSame(const SoField &f) const \
186{ \
187 return (getTypeId() == f.getTypeId() && \
188 (*this) == (const className &) f); \
189}
190
191//===========================================================================
192//
193// Macros to be called within the class definition header for a
194// single-value field subclass:
195//
196//===========================================================================
197
199//
200// This declares all header info required for a single-value field class.
201//
203
204#define SO_SFIELD_REQUIRED_HEADER(className) \
205 SO__FIELD_HEADER(className)
206
208//
209// This declares a constructor and destructor for a single-value field class.
210//
212
213#define SO_SFIELD_CONSTRUCTOR_HEADER(className) \
214 public: \
215 \
216 className(); \
217 \
218 \
219 virtual ~className()
220
222//
223// This declares value processing methods and variables for a
224// single-value field class.
225//
227
228#define SO_SFIELD_VALUE_HEADER(className, valueType, valueRef) \
229 SO__SFIELD_RW_HEADER(className); \
230\
231 public: \
232 \
233
234 valueRef getValue() const \
235 { evaluate(); return value; } \
236\ \
238
239 void setValue(valueRef newValue); \
240\ \
242 valueRef operator =(valueRef newValue) \
243 { setValue(newValue); return value; } \
244\ \
246 int operator ==(const className &f) const; \
247\ \
249 int operator !=(const className &f) const \
250 { return ! ((*this) == f); } \
251\ \
253 virtual size_t getValueSize() const { return sizeof(valueType); } \
254\
255 private: \
256 valueType value
257
259//
260// This is like the above macro, but can be used by a field class
261// derived from another (non-abstract) field class. It will inherit
262// most of the field processing stuff.
263//
265
266#define SO_SFIELD_DERIVED_VALUE_HEADER(className, valueType, valueRef) \
267 SO__SFIELD_RW_HEADER(className); \
268 public: \
269 \
270 valueRef operator =(valueRef newValue) \
271 { setValue(newValue); return (valueRef)value; }
272
274//
275// This macro is all that is needed for most single-value field
276// classes. It includes the relevant macros.
277//
279
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)
284
286//
287// This macro is all that is needed for most single-value field
288// classes that are derived from other field classes. It includes the
289// relevant macros.
290//
292
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)
297
298//===========================================================================
299//
300// Macros to be called within the class definition header for a
301// multiple-value field subclass:
302//
303//===========================================================================
304
306//
307// This declares all header info required for a multiple-value field class.
308//
310
311#define SO_MFIELD_REQUIRED_HEADER(className) \
312 SO__FIELD_HEADER(className)
313
315//
316// This declares a constructor and destructor for a multiple-value field class.
317//
319
320#define SO_MFIELD_CONSTRUCTOR_HEADER(className) \
321 public: \
322 \
323 className(); \
324 \
325 \
326 virtual ~className()
327
329//
330// This declares value processing methods and variables for a
331// multiple-value field class.
332//
334
335#define SO_MFIELD_VALUE_HEADER(className, valueType, valueRef) \
336 SO__MFIELD_RW_HEADER(className); \
337\
338 public: \
339 \
340
341
342 valueRef operator [](int i) const \
343 { evaluate(); return values[i]; } \
344\ \ \ \
348
349
350
351
352
353 valueType const* getValues(int start) const \
354 { evaluate(); return const_cast<valueType const*>(static_cast<valueType *>(values + start)); } \
355\ \ \ \ \
360 int find(valueRef targetValue, SbBool addIfNotFound = FALSE); \
361\ \ \ \ \
366
367
368
369
370 void setValues(int start, int num, valueType const* newValues); \
371\ \ \ \
375
376
377
378 void set1Value(int index, valueRef newValue); \
379\ \ \ \
383
384
385 void setValue(valueRef newValue); \
386\ \ \ \
390
391
392 valueRef operator =(valueRef newValue) \
393 { setValue(newValue); return newValue; } \
394\ \ \ \
398 int operator ==(const className &f) const; \
399\ \ \ \
403 int operator !=(const className &f) const \
404 { return ! ((*this) == f); } \
405\ \ \ \
409
410 virtual void enableDeleteValues() \
411 { setUserDataIsUsed(false); } \
412\ \
414 virtual void disableDeleteValues() \
415 { setUserDataIsUsed(true); } \
416\ \ \ \ \
421
422 virtual SbBool isDeleteValuesEnabled() \
423 { return (!getUserDataIsUsed())?TRUE:FALSE; } \
424\ \
426 virtual size_t getValueSize() const { return sizeof(valueType); } \
427\
428 private: \
429 /* Allocates room for num values. Copies old values (if any) into */ \
430 /* new area. Deletes old area, if any. Will reduce room if needed, */ \
431 /* so a value of newNum==0 will delete all values. */ \
432 virtual void allocValues(int newNum); \
433\
434 /* Deletes all current values, resets number of values */ \
435 virtual void deleteAllValues(); \
436\
437 /* Copies value indexed by "from" to value indexed by "to" */ \
438 virtual void copyValue(int to, int from); \
439\
440 valueType *values; \
441\
442 /* Get pointer into array of values */ \
443 virtual void* getValuesPointer(int start) \
444 { return static_cast<void*>(values + start); }
445
446
448//
449// This is like the above macro, but can be used by a field class
450// derived from another (non-abstract) field class. It will inherit
451// most of the field processing stuff.
452//
454
455#define SO_MFIELD_DERIVED_VALUE_HEADER(className, valueType, valueRef) \
456 SO__MFIELD_RW_HEADER(className); \
457 public: \
458 \
459 valueRef operator =(valueRef newValue) \
460 { setValue(newValue); return newValue; }
461
462#define SO_FIELD_SUPPORT_MEMOBJ() \
463private: \
464 virtual bool isEnabledMemObj() { return true; } \
465 virtual SoMemoryObject* getMemObj() { return m_memObj; } \
466 virtual void setMemObj( SoMemoryObject* memObj ) { m_memObj = memObj; }
467
468
470//
471// This macro defines the start and finish editing methods.
472//
474
475#define SO_MFIELD_EDITING_HEADER(className, valueType) \
476 \
477 \
478 \
479 \
480 \
481 \
482 \
483
484
485 valueType *startEditing() { \
486 evaluate(); \
487 return values; \
488 } \
489\ \
491 void finishEditing() { \
492 valueChanged(0, getNum()); \
493 }
494
496//
497// This macro is all that is needed for most multiple-value field
498// classes. It includes the relevant macros.
499//
501
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)
507
509//
510// This macro is all that is needed for most multiple-value field
511// classes that are derived from other field classes. It includes the
512// relevant macros.
513//
515
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)
520
521//===========================================================================
522//
523// Macros to be called within the source file for a single-value field
524// subclass:
525//
526//===========================================================================
527
529//
530// This initializes type identifer variables. It should be called from
531// within initClass().
532//
534
535#define SO_SFIELD_INIT_CLASS(className,parentClass) \
536 SO__FIELD_INIT_CLASS(className, SO__QUOTE(className), parentClass);
537
538#define SO_SFIELD_EXIT_CLASS(className) \
539 SO__FIELD_EXIT_CLASS(className)
540
542//
543// This defines the variables and methods declared in
544// SO_SFIELD_REQUIRED_HEADER().
545//
547
548#define SO_SFIELD_REQUIRED_SOURCE(className) \
549\
550 SO__FIELD_ID_SOURCE(className)/*;*/ \
551 SO__FIELD_EQ_SAME_SOURCE(className) \
552\
553const className & \
554className::operator =(const className &f) \
555{ \
556 setValue(f.getValue()); \
557 return *this; \
558}
559
560#if defined(_DEBUG)
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(); \
568 } \
569 SoTypedObject::checkDatabase(SO__QUOTE(className), this, className::getClassTypeId(), classTypeId); \
570}
571#else
572#define SO_FIELD_CHECK_INIT(className) { \
573 if (classTypeId.isBad()) { \
574 className::initClass(); \
575 } \
576}
577#endif
578
580//
581// This defines the constructor and destructor.
582//
584
585#define SO_SFIELD_CONSTRUCTOR_SOURCE(className) \
586\
587className::className() \
588 : value() \
589{ \
590 SO_FIELD_CHECK_INIT(className) \
591} \
592className::~className() \
593{ \
594}
595
597//
598// This defines the variables and methods declared in
599// SO_SFIELD_VALUE_HEADER().
600//
602
603#define SO_SFIELD_VALUE_SOURCE(className, valueType, valueRef) \
604\
605void \
606className::setValue(valueRef newValue) \
607{ \
608 /*If container is NULL, we are doing the first init, so don't check for equality */ \
609 /*because value has never been initialized */ \
610 if ( getSameValueNotificationEnabled() || getContainer() == NULL || !(value==newValue) ) \
611 { \
612 value = newValue; \
613 valueChanged(); \
614 } \
615} \
616\
617int \
618className::operator ==(const className &f) const \
619{ \
620 return getValue() == f.getValue(); \
621}
622
624//
625// This macro is all that is needed for most single-value field
626// classes. It includes the relevant macros.
627//
629
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)
634
636//
637// This version doesn't initialize a value field, because a derived
638// field type usually doesn't have one.
639//
641
642#define SO_SFIELD_DERIVED_CONSTRUCTOR_SOURCE(className) \
643\
644className::className() \
645{ \
646 SO_FIELD_CHECK_INIT(className) \
647} \
648className::~className() \
649{ \
650}
651
652
654//
655// This macro is all that is needed for most single-value field
656// classes that are derived from other field classes. It includes the
657// relevant macros.
658//
660
661#define SO_SFIELD_DERIVED_SOURCE(className, valueType, valueRef) \
662 SO_SFIELD_REQUIRED_SOURCE(className)/*;*/ \
663 SO_SFIELD_DERIVED_CONSTRUCTOR_SOURCE(className)
664
665//===========================================================================
666//
667// Macros to be called within the source file for a multiple-value field
668// subclass:
669//
670//===========================================================================
671
673//
674// This initializes type identifer variables. It should be called from
675// within initClass().
676//
678
679#define SO_MFIELD_INIT_CLASS(className,parentClass) \
680 SO__FIELD_INIT_CLASS(className, SO__QUOTE(className), parentClass);
681
682#define SO_MFIELD_EXIT_CLASS(className) \
683 SO__FIELD_EXIT_CLASS(className)
684
686//
687// This defines the variables and methods declared in
688// SO_MFIELD_REQUIRED_HEADER().
689//
691
692#define SO_MFIELD_REQUIRED_SOURCE(className) \
693\
694 SO__FIELD_ID_SOURCE(className) \
695 SO__FIELD_EQ_SAME_SOURCE(className) \
696\
697const className & \
698className::operator =(const className &f) \
699{ \
700 if (f.getNum() < getNum()) \
701 deleteAllValues(); \
702 setValues(0, f.getNum(), f.getValues(0)); \
703 return *this; \
704}
705
707//
708// This defines a constructor and destructor that work with the
709// variables and methods defined in SO_MFIELD_VALUE_HEADER(). If you
710// define your own value processing differently, you may not be able
711// to use these.
712//
714
715#define SO_MFIELD_CONSTRUCTOR_SOURCE(className) \
716\
717className::className() \
718{ \
719 SO_FIELD_CHECK_INIT(className) \
720 values = NULL; \
721 resetChangedStatus (); \
722 m_memObj = NULL; \
723} \
724\
725className::~className() \
726{ \
727 deleteAllValues(); \
728\
729}
730
732//
733// This defines an empty constructor and destructor for classes
734// derived from other field classes, since they inherit value
735// processing.
736//
738
739#define SO_MFIELD_DERIVED_CONSTRUCTOR_SOURCE(className) \
740\
741className::className() \
742{ \
743 SO_FIELD_CHECK_INIT(className) \
744 resetChangedStatus (); \
745} \
746\
747className::~className() \
748{ \
749}
750
752//
753// This defines the variables and methods declared in
754// SO_MFIELD_VALUE_HEADER().
755//
757
758#define SO_MFIELD_VALUE_SOURCE(className, valueType, valueRef) \
759\
760int \
761className::find(valueRef targetValue, SbBool addIfNotFound) \
762{ \
763 int i, myNum = getNum(); \
764\
765 if (values) { \
766 for (i = 0; i < myNum; i++) \
767 if (values[i] == targetValue) \
768 return i; \
769 } \
770\
771 if (addIfNotFound) \
772 set1Value(myNum, targetValue); \
773\
774 return -1; \
775} \
776\
777void \
778className::setValues(int start, int myNum, valueType const*newValues) \
779{ \
780 int newNum = start + myNum, i; \
781\
782 if (newNum > getNum()) \
783 makeRoom(newNum); \
784\
785 if (values) { \
786 for (i = 0; i < myNum; i++) \
787 values[start + i] = newValues[i]; \
788\
789 valueChanged(start, myNum); \
790 } \
791} \
792\
793void \
794className::set1Value(int index, valueRef newValue) \
795{ \
796 if (index >= getNum()) \
797 makeRoom(index + 1); \
798 else if ( !getSameValueNotificationEnabled() && (values[index]==newValue) ) \
799 return; \
800 if (values) { \
801 values[index] = newValue; \
802 valueChanged(index, 1); \
803 } \
804} \
805\
806void \
807className::setValue(valueRef newValue) \
808{ \
809 makeRoom(1); \
810 if (values) { \
811 values[0] = newValue; \
812 valueChanged(0,1); \
813 } \
814} \
815\
816int \
817className::operator ==(const className &f) const \
818{ \
819 int i, myNum = getNum(); \
820 valueType const*myVals, *itsVals; \
821\
822 if (myNum != f.getNum()) \
823 return FALSE; \
824\
825 myVals = getValues(0); \
826 itsVals = f.getValues(0); \
827\
828 for (i = 0; i < myNum; i++) \
829 if (! (myVals[i] == itsVals[i])) \
830 return FALSE; \
831\
832 return TRUE; \
833} \
834\
835void \
836className::deleteAllValues() \
837{ \
838 allocValues(0); \
839} \
840\
841void \
842className::copyValue(int to, int from) \
843{ \
844 values[to] = values[from]; \
845}
846
848//
849// This allocates/reallocates room for values, using the "new" and
850// "delete" operators, so the constructor and destructor are called
851// for new and deleted values.
852//
854
855#define SO_MFIELD_ALLOC_SOURCE(className, valueType) \
856void \
857className::allocValues(int newNum) \
858{ \
859 if (values == NULL) { \
860 if (newNum > 0) { \
861 values = new valueType[newNum]; \
862 if (values == NULL) { \
863 SoMemoryError::post( "SO_MFIELD_ALLOC_SOURCE: Cannot allocate memory for the fields!" ); \
864 newNum = 0; \
865 } \
866 } \
867 } \
868 else { \
869 valueType *oldValues = values; \
870 int i; \
871\
872 if (newNum > 0) { \
873 values = new valueType[newNum]; \
874 if (values == NULL) { \
875 SoMemoryError::post( "SO_MFIELD_ALLOC_SOURCE: Cannot allocate memory for the fields!" ); \
876 newNum = num; \
877 } \
878 else { \
879 for (i = 0; i < num && i < newNum; i++) \
880 values[i] = oldValues[i]; \
881 delete [] oldValues; \
882 } \
883 } \
884 else { \
885 values = NULL; \
886 delete [] oldValues; \
887 } \
888 } \
889\
890 num = newNum; \
891}
892
894//
895// This allocates/reallocates room for values, using malloc() and
896// realloc(). This means that constructors and destructors will NOT be
897// called for values. Therefore, this macro should not be used for any
898// value types that have constructors or destructors! (It is used for
899// fields that have simple types, like shorts and floats.)
900//
901// It's not clear why realloc won't work in the "newNum == 1" case, but
902// we definitely need to save that last value before freeing the memory!
903//
905
906#define SO_MFIELD_MALLOC_SOURCE(className, valueType) \
907void \
908className::allocValues(int newNum) \
909{ \
910 void *before = (void *)values; \
911\
912 if (values == NULL) { \
913 if (newNum > 0) { \
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!" ); \
917 newNum = 0; \
918 } \
919 } \
920 } \
921 else { \
922 /* Jerome Lague BEGIN ADDED on 7/03/06*/ \
923 /* Special case when user calls setValue(newValue) to reset field */ \
924 /* Necessary to wrap the setValuesPointer method in .NET */ \
925 if (newNum == 1) {\
926 valueType value0 = *(static_cast<valueType*>(values)); /* Save last value */ \
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!" ); \
932 newNum = num; \
933 } \
934 else { \
935 *((valueType *)values) = value0; /* Restore last value */ \
936 setUserDataIsUsed(false);\
937 } \
938 } \
939 /* Jerome Lague END ADDED on 7/03/06*/ \
940 else if (newNum > 1) { \
941 void *after = NULL; \
942 if (getUserDataIsUsed() == false) { \
943 after = realloc(values, sizeof(valueType) * newNum); \
944 } else { \
945 /* if user data is used, allocates a new buffer and copy data into without deleting the user buffer. */ \
946 after = malloc(sizeof(valueType) * newNum); \
947 if ( after ) \
948 memcpy(after, before, sizeof(valueType) * (num < newNum ? num : newNum) ); \
949 } \
950 if (after == NULL) { \
951 SoMemoryError::post( "SO_MFIELD_MALLOC_SOURCE: Cannot allocate memory for the fields!" ); \
952 newNum = num; \
953 } \
954 else \
955 values = (valueType *)after; \
956 } \
957 else { \
958 if (getUserDataIsUsed() == false) { \
959 free((char *)values); \
960 } \
961 values = NULL; \
962 } \
963 } \
964 num = newNum; \
965\
966 if (before != (void *)values) { \
967 setUserDataIsUsed(false); \
968 } \
969}
970
972//
973// This macro is all that is needed for most multiple-value field
974// classes. It includes the relevant macros, including the allocation
975// macro that uses new and delete.
976//
978
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)
984
986//
987// This is like the above macro, but uses the allocation macro that
988// uses malloc() and realloc().
989//
991
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)
997
999//
1000// This macro is all that is needed for most multiple-value field
1001// classes that are derived from other field classes. It includes the
1002// relevant macros.
1003//
1005
1006#define SO_MFIELD_DERIVED_SOURCE(className, valueType, valueRef) \
1007 SO_MFIELD_REQUIRED_SOURCE(className); \
1008 SO_MFIELD_DERIVED_CONSTRUCTOR_SOURCE(className)
1009
1010
1012//
1013// This declares header info required for setValues using user data.
1014//
1015
1016#define SO_MFIELD_SETVALUESPOINTER_HEADER(userType) \
1017public: \
1018 \
1019 \
1020 \
1021 \
1022 \
1023 \
1024 \
1025 \
1026 \
1027 \
1028 \
1029 \
1030 \
1031
1032
1033
1034
1035 void setValuesPointer(int num, userType const*userData); \
1036\ \
1038
1039 void setValuesPointer(int num, userType *userData)
1040
1041
1042
1043
1044//
1045// This macro defines setValues method using user data
1046// Data will not be duplicated into the field.
1047//
1048
1049#include <Inventor/errors/SoDebugError.h>
1050#define SO_MFIELD_SETVALUESPOINTER_SOURCE(className, valueType, userType) \
1051void \
1052className::setValuesPointer(int myNum, userType const*userData) \
1053{ \
1054 if (myNum > 0 && userData != NULL) { \
1055 if ( getUserDataIsUsed() && userData == (userType const*)values ) { \
1056 } \
1057 else if (getNum() > 0) { \
1058 makeRoom(0); \
1059 } \
1060 values = (valueType *)userData; \
1061 setUserDataIsUsed(true); \
1062 num = myNum; \
1063 valueChanged(0, num); \
1064 } \
1065} \
1066\
1067void \
1068className::setValuesPointer(int myNum, userType *userData) \
1069{ \
1070 setValuesPointer(myNum, (userType const*)userData); \
1071}
1072
1073#endif /* _SO_SUB_FIELD_ */
1074
1075
int SbBool
Boolean type.
Definition SbBase.h:87