Open Inventor Reference
SoSubField.h
Go to the documentation of this file.
1/*
2 *
3 * Copyright (C) 2000 Silicon Graphics, Inc. All Rights Reserved.
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * Further, this software is distributed without any warranty that it is
16 * free of the rightful claim of any third person regarding infringement
17 * or the like. Any license provided herein, whether implied or
18 * otherwise, applies only to this software file. Patent licenses, if
19 * any, provided herein do not apply to combinations of this program with
20 * other software, or any other product whatsoever.
21 *
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with this library; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 *
26 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
27 * Mountain View, CA 94043, or:
28 *
29 * http://www.sgi.com
30 *
31 * For further information regarding this notice, see:
32 *
33 * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
34 *
35 */
36
37
38/*
39 * Copyright (C) 1990,91 Silicon Graphics, Inc.
40 *
41 _______________________________________________________________________
42 ______________ S I L I C O N G R A P H I C S I N C . ____________
43 |
44 | $Revision: 1.1.1.1 $
45 |
46 | Description:
47 | This file defines some macros that implement things common to
48 | many subclasses of SoField (actually, subclasses of SoSField
49 | and SoMField). They may be used to make subclassing easier.
50 | In the macros, the following parameters are used consistently:
51 |
52 | className = name of new field subclass
53 |
54 | valueType = type of field value (e.g., float, SbVec3f)
55 |
56 | valueRef = type of field value that can be passed or
57 | returned. For simple types like float or
58 | int, it is the same as valueType. For
59 | aggregates such as SbVec3f, use a const
60 | reference, e.g.: const SbVec3f &
61 |
62 | Macros for single-value (SoSField) field subclasses:
63 |
64 | Within class header:
65 |
66 | SO_SFIELD_REQUIRED_HEADER()
67 | SO_SFIELD_CONSTRUCTOR_HEADER()
68 | SO_SFIELD_VALUE_HEADER()
69 | SO_SFIELD_DERIVED_VALUE_HEADER()
70 |
71 | SO_SFIELD_HEADER()
72 | [includes REQUIRED, CONSTRUCTOR, and VALUE]
73 | SO_SFIELD_DERIVED_HEADER()
74 | [includes REQUIRED, CONSTRUCTOR, and DERIVED_VALUE]
75 |
76 | Within class source:
77 |
78 | SO_SFIELD_INIT_CLASS()
79 | SO_SFIELD_REQUIRED_SOURCE()
80 | SO_SFIELD_CONSTRUCTOR_SOURCE()
81 | SO_SFIELD_VALUE_SOURCE()
82 |
83 | SO_SFIELD_SOURCE()
84 | [includes REQUIRED, CONSTRUCTOR, and VALUE]
85 | SO_SFIELD_DERIVED_SOURCE()
86 | [includes REQUIRED and CONSTRUCTOR]
87 |
88 | Macros for multiple-value (SoMField) field subclasses:
89 |
90 | Within class header:
91 |
92 | SO_MFIELD_REQUIRED_HEADER()
93 | SO_MFIELD_CONSTRUCTOR_HEADER()
94 | SO_MFIELD_VALUE_HEADER()
95 | SO_MFIELD_DERIVED_VALUE_HEADER()
96 |
97 | SO_MFIELD_HEADER()
98 | [includes REQUIRED, CONSTRUCTOR, and VALUE]
99 | SO_MFIELD_DERIVED_HEADER()
100 | [includes REQUIRED and DERIVED_VALUE ]
101 |
102 | Within class source:
103 |
104 | SO_MFIELD_INIT_CLASS()
105 | SO_MFIELD_REQUIRED_SOURCE()
106 | SO_MFIELD_CONSTRUCTOR_SOURCE()
107 | SO_MFIELD_DERIVED_CONSTRUCTOR_SOURCE()
108 | SO_MFIELD_VALUE_SOURCE()
109 | SO_MFIELD_ALLOC_SOURCE()
110 | SO_MFIELD_MALLOC_SOURCE()
111 |
112 | SO_MFIELD_SOURCE()
113 | [includes REQUIRED, CONSTRUCTOR, VALUE, and ALLOC]
114 | SO_MFIELD_SOURCE_MALLOC()
115 | [includes REQUIRED, CONSTRUCTOR, VALUE, and MALLOC]
116 | SO_MFIELD_DERIVED_SOURCE()
117 | [includes REQUIRED and DERIVED_CONSTRUCTOR]
118 |
119 | Author(s) : Paul S. Strauss
120 |
121 ______________ S I L I C O N G R A P H I C S I N C . ____________
122 _______________________________________________________________________
123 */
124
125#ifndef _SO_SUB_FIELD_
126#define _SO_SUB_FIELD_
127
130#include <Inventor/SoInput.h>
131#include <Inventor/SoOutput.h>
132
133
139
140#define SO__FIELD_HEADER(className) \
141 public: \
142 virtual SoType getTypeId() const; \
143 static SoType getClassTypeId() { return classTypeId; } \
144 \
145 /* Copy from another field of same type */ \
146 const className & operator =(const className &f); \
147 \
148 SoINTERNAL public: \
149 /* Copy from another field of unknown type (assumed to be same type) */ \
150 virtual void copyFrom(const SoField &f); \
151 \
152 static void * createInstance(); /* for SoType */ \
153 \
154 /* Returns TRUE if fields are same type and have same values */ \
155 virtual bool isSame(const SoField &f) const; \
156 \
157 private: \
158 static SoType classTypeId
159
160#define SO__SFIELD_RW_HEADER(className) \
161 private: \
162 /* Reads value of field from file */ \
163 virtual bool readValue(SoInput *in); \
164 \
165 /* Writes value of field to file */ \
166 virtual void writeValue(SoOutput *out) const
167
168#define SO__MFIELD_RW_HEADER(className) \
169 private: \
170 /* Reads indexed value of field from file */ \
171 virtual bool read1Value(SoInput *in, int index); \
172 \
173 /* Writes one (indexed) value to file */ \
174 virtual void write1Value(SoOutput *out, int index) const
175
176#define SO__FIELD_INIT_CLASS(className,classPrintName,parentClass) \
177 classTypeId = SoType::createType(parentClass::getClassTypeId(), \
178 classPrintName, \
179 &className::createInstance)
180
181#define SO__FIELD_ID_SOURCE(className) \
182 \
183SoType className::classTypeId; \
184 \
185SoType \
186className::getTypeId() const \
187{ \
188 return classTypeId; \
189} \
190void * \
191className::createInstance() \
192{ \
193 return static_cast<void *>(new className); \
194}
195
196#define SO__FIELD_EQ_SAME_SOURCE(className) \
197 \
198void \
199className::copyFrom(const SoField &f) \
200{ \
201 *this = * static_cast<const className *>(&f); \
202} \
203 \
204bool \
205className::isSame(const SoField &f) const \
206{ \
207 return (getTypeId() == f.getTypeId() && \
208 (*this) == static_cast<const className &>(f)); \
209}
210
217
223
224#define SO_SFIELD_REQUIRED_HEADER(className) \
225 SO__FIELD_HEADER(className)
226
232
233#define SO_SFIELD_CONSTRUCTOR_HEADER(className) \
234 public: \
235 className(); \
236 virtual ~className()
237
244
245#define SO_SFIELD_VALUE_HEADER(className, valueType, valueRef) \
246 SO__SFIELD_RW_HEADER(className); \
247 public: \
248 /* Get the value */ \
249 valueRef getValue() const \
250 { evaluate(); return value; } \
251 \
252 /* Set value from a value of the appropriate type */ \
253 void setValue(valueRef newValue); \
254 valueRef operator =(valueRef newValue) \
255 { setValue(newValue); return value; } \
256 \
257 /* Equality/inequality test for fields of same type */ \
258 bool operator ==(const className &f) const; \
259 bool operator !=(const className &f) const \
260 { return ! ((*this) == f); } \
261 \
262 protected: \
263 valueType value
264
272
273#define SO_SFIELD_DERIVED_VALUE_HEADER(className, valueType, valueRef) \
274 SO__SFIELD_RW_HEADER(className); \
275 public: \
276 /* Since = operator is not inherited, we redefine it here */ \
277 valueRef operator =(valueRef newValue) \
278 { setValue(newValue); return value; }
279
286
287#define SO_SFIELD_HEADER(className, valueType, valueRef) \
288 SO_SFIELD_REQUIRED_HEADER(className); \
289 SO_SFIELD_CONSTRUCTOR_HEADER(className); \
290 SO_SFIELD_VALUE_HEADER(className, valueType, valueRef)
291
299
300#define SO_SFIELD_DERIVED_HEADER(className, valueType, valueRef) \
301 SO_SFIELD_REQUIRED_HEADER(className); \
302 SO_SFIELD_CONSTRUCTOR_HEADER(className); \
303 SO_SFIELD_DERIVED_VALUE_HEADER(className, valueType, valueRef)
304
311
317
318#define SO_MFIELD_REQUIRED_HEADER(className) \
319 SO__FIELD_HEADER(className)
320
326
327#define SO_MFIELD_CONSTRUCTOR_HEADER(className) \
328 public: \
329 className(); \
330 virtual ~className()
331
338
339#define SO_MFIELD_VALUE_HEADER(className, valueType, valueRef) \
340 SO__MFIELD_RW_HEADER(className); \
341 public: \
342 /* Get indexed value */ \
343 valueRef operator [](int i) const \
344 { evaluate(); return values[i]; } \
345 \
346 /* Get pointer into array of values */ \
347 const valueType * getValues(int start) const \
348 { evaluate(); return const_cast<const valueType *>(values + start); } \
349 \
350 /* Finds index of value that is equal to given one, or -1 if not */ \
351 /* found. If not found and addIfNotFound is TRUE, the new value is */ \
352 /* appended to the field. */ \
353 int find(valueRef targetValue, \
354 bool addIfNotFound = FALSE); \
355 \
356 /* Set num values starting at index start from info in newValues */ \
357 void setValues(int start, int num, \
358 const valueType *newValues); \
359 \
360 /* Set 1 value at given index */ \
361 void set1Value(int index, valueRef newValue); \
362 \
363 /* Set field to have one value */ \
364 void setValue(valueRef newValue); \
365 valueRef operator =(valueRef newValue) \
366 { setValue(newValue); return newValue; } \
367 \
368 /* Equality/inequality test for fields of same type */ \
369 bool operator ==(const className &f) const; \
370 bool operator !=(const className &f) const \
371 { return ! ((*this) == f); } \
372 \
373 /* Get non-const pointer into array of values for batch edits */ \
374 valueType * startEditing() \
375 { evaluate(); return values; } \
376 \
377 /* Indicate that batch edits have finished */ \
378 void finishEditing() { valueChanged(); } \
379 \
380 protected: \
381 /* Allocates room for num values. Copies old values (if any) into */ \
382 /* new area. Deletes old area, if any. Will reduce room if needed, */ \
383 /* so a value of newNum==0 will delete all values. */ \
384 virtual void allocValues(int newNum); \
385 \
386 /* Deletes all current values, resets number of values */ \
387 virtual void deleteAllValues(); \
388 \
389 /* Copies value indexed by "from" to value indexed by "to" */ \
390 virtual void copyValue(int to, int from); \
391 \
392 valueType *values
393
401
402#define SO_MFIELD_DERIVED_VALUE_HEADER(className, valueType, valueRef) \
403 SO__MFIELD_RW_HEADER(className); \
404 public: \
405 /* Since = operator is not inherited, we redefine it here */ \
406 valueRef operator =(valueRef newValue) \
407 { setValue(newValue); return newValue; }
408
415
416#define SO_MFIELD_HEADER(className, valueType, valueRef) \
417 SO_MFIELD_REQUIRED_HEADER(className); \
418 SO_MFIELD_CONSTRUCTOR_HEADER(className); \
419 SO_MFIELD_VALUE_HEADER(className, valueType, valueRef)
420
428
429#define SO_MFIELD_DERIVED_HEADER(className, valueType, valueRef) \
430 SO_MFIELD_REQUIRED_HEADER(className); \
431 SO_MFIELD_CONSTRUCTOR_HEADER(className); \
432 SO_MFIELD_DERIVED_VALUE_HEADER(className, valueType, valueRef)
433
440
447
448#define SO_SFIELD_INIT_CLASS(className,parentClass) \
449 SO__FIELD_INIT_CLASS(className, SO__QUOTE(className), parentClass)
450
457
458#define SO_SFIELD_REQUIRED_SOURCE(className) \
459 \
460 SO__FIELD_ID_SOURCE(className); \
461 SO__FIELD_EQ_SAME_SOURCE(className) \
462 \
463const className & \
464className::operator =(const className &f) \
465{ \
466 setValue(f.getValue()); \
467 return *this; \
468}
469
475
476#define SO_SFIELD_CONSTRUCTOR_SOURCE(className) \
477 \
478className::className() \
479{ \
480} \
481className::~className() \
482{ \
483}
484
491
492#define SO_SFIELD_VALUE_SOURCE(className, valueType, valueRef) \
493 \
494void \
495className::setValue(valueRef newValue) \
496{ \
497 value = newValue; \
498 valueChanged(); \
499} \
500 \
501bool \
502className::operator ==(const className &f) const \
503{ \
504 return getValue() == f.getValue(); \
505}
506
513
514#define SO_SFIELD_SOURCE(className, valueType, valueRef) \
515 SO_SFIELD_REQUIRED_SOURCE(className); \
516 SO_SFIELD_CONSTRUCTOR_SOURCE(className); \
517 SO_SFIELD_VALUE_SOURCE(className, valueType, valueRef)
518
526
527#define SO_SFIELD_DERIVED_SOURCE(className, valueType, valueRef) \
528 SO_SFIELD_REQUIRED_SOURCE(className); \
529 SO_SFIELD_CONSTRUCTOR_SOURCE(className)
530
537
544
545#define SO_MFIELD_INIT_CLASS(className,parentClass) \
546 SO__FIELD_INIT_CLASS(className, SO__QUOTE(className), parentClass)
547
554
555#define SO_MFIELD_REQUIRED_SOURCE(className) \
556 \
557 SO__FIELD_ID_SOURCE(className); \
558 SO__FIELD_EQ_SAME_SOURCE(className) \
559 \
560const className & \
561className::operator =(const className &f) \
562{ \
563 if (f.getNum() < getNum()) \
564 deleteAllValues(); \
565 setValues(0, f.getNum(), f.getValues(0)); \
566 return *this; \
567}
568
577
578#define SO_MFIELD_CONSTRUCTOR_SOURCE(className) \
579 \
580className::className() \
581{ \
582 values = NULL; \
583} \
584 \
585className::~className() \
586{ \
587 deleteAllValues(); \
588}
589
597
598#define SO_MFIELD_DERIVED_CONSTRUCTOR_SOURCE(className) \
599 \
600className::className() \
601{ \
602} \
603 \
604className::~className() \
605{ \
606}
607
614
615#define SO_MFIELD_VALUE_SOURCE(className, valueType, valueRef) \
616 \
617int \
618className::find(valueRef targetValue, bool addIfNotFound) \
619{ \
620 int i, localNum = getNum(); \
621 \
622 for (i = 0; i < localNum; i++) \
623 if (values[i] == targetValue) \
624 return i; \
625 \
626 if (addIfNotFound) \
627 set1Value(localNum, targetValue); \
628 \
629 return -1; \
630} \
631 \
632void \
633className::setValues(int start, int localNum, const valueType *newValues) \
634{ \
635 int newNum = start + localNum, i; \
636 \
637 if (newNum > getNum()) \
638 makeRoom(newNum); \
639 \
640 for (i = 0; i < localNum; i++) \
641 values[start + i] = newValues[i]; \
642 \
643 valueChanged(); \
644} \
645 \
646void \
647className::set1Value(int index, valueRef newValue) \
648{ \
649 if (index >= getNum()) \
650 makeRoom(index + 1); \
651 values[index] = newValue; \
652 valueChanged(); \
653} \
654 \
655void \
656className::setValue(valueRef newValue) \
657{ \
658 makeRoom(1); \
659 values[0] = newValue; \
660 valueChanged(); \
661} \
662 \
663bool \
664className::operator ==(const className &f) const \
665{ \
666 int i, localNum = getNum(); \
667 const valueType *myVals, *itsVals; \
668 \
669 if (localNum != f.getNum()) \
670 return FALSE; \
671 \
672 myVals = getValues(0); \
673 itsVals = f.getValues(0); \
674 \
675 for (i = 0; i < localNum; i++) \
676 if (! (myVals[i] == itsVals[i])) \
677 return FALSE; \
678 \
679 return TRUE; \
680} \
681 \
682void \
683className::deleteAllValues() \
684{ \
685 allocValues(0); \
686} \
687 \
688void \
689className::copyValue(int to, int from) \
690{ \
691 values[to] = values[from]; \
692}
693
701
702#define SO_MFIELD_ALLOC_SOURCE(className, valueType) \
703void \
704className::allocValues(int newNum) \
705{ \
706 if (values == NULL) { \
707 if (newNum > 0) \
708 values = new valueType[newNum]; \
709 } \
710 else { \
711 valueType *oldValues = values; \
712 int i; \
713 \
714 if (newNum > 0) { \
715 values = new valueType[newNum]; \
716 for (i = 0; i < num && i < newNum; i++) \
717 values[i] = oldValues[i]; \
718 } \
719 else \
720 values = NULL; \
721 delete [] oldValues; \
722 } \
723 \
724 num = maxNum = newNum; \
725}
726
736
737#define SO_MFIELD_MALLOC_SOURCE(className, valueType) \
738void \
739className::allocValues(int newNum) \
740{ \
741 if (values == NULL) { \
742 if (newNum > 0) \
743 values = static_cast<valueType *>(malloc(sizeof(valueType) * newNum));\
744 } \
745 else { \
746 if (newNum > 0) \
747 values = static_cast<valueType *>(realloc(values, sizeof(valueType)*newNum));\
748 else { \
749 free(values); \
750 values = NULL; \
751 } \
752 } \
753 \
754 num = maxNum = newNum; \
755}
756
764
765#define SO_MFIELD_SOURCE(className, valueType, valueRef) \
766 SO_MFIELD_REQUIRED_SOURCE(className) \
767 SO_MFIELD_CONSTRUCTOR_SOURCE(className) \
768 SO_MFIELD_VALUE_SOURCE(className, valueType, valueRef) \
769 SO_MFIELD_ALLOC_SOURCE(className, valueType)
770
777
778#define SO_MFIELD_SOURCE_MALLOC(className, valueType, valueRef) \
779 SO_MFIELD_REQUIRED_SOURCE(className) \
780 SO_MFIELD_CONSTRUCTOR_SOURCE(className) \
781 SO_MFIELD_VALUE_SOURCE(className, valueType, valueRef) \
782 SO_MFIELD_MALLOC_SOURCE(className, valueType)
783
791
792#define SO_MFIELD_DERIVED_SOURCE(className, valueType, valueRef) \
793 SO_MFIELD_REQUIRED_SOURCE(className); \
794 SO_MFIELD_DERIVED_CONSTRUCTOR_SOURCE(className)
795
796
797#endif /* _SO_SUB_FIELD_ */