openscenegraph
Serializer
Go to the documentation of this file.
1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2010 Robert Osfield
2 *
3 * This library is open source and may be redistributed and/or modified under
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version. The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * OpenSceneGraph Public License for more details.
12*/
13// Written by Wang Rui, (C) 2010
14
15#ifndef OSGDB__SERIALIZER
16#define OSGDB__SERIALIZER
17
18#include <osg/ref_ptr>
19#include <osg/Notify>
20#include <osg/Object>
21#include <osgDB/InputStream>
22#include <osgDB/OutputStream>
23
24#include <string>
25#include <sstream>
26#include <limits.h>
27
28namespace osgDB
29{
30
31typedef std::vector<std::string> StringList;
32extern OSGDB_EXPORT void split( const std::string& src, StringList& list, char separator=' ' );
33
34
35#ifndef OBJECT_CAST
36 #define OBJECT_CAST static_cast
37#endif
38
39class IntLookup
40{
41public:
42 typedef int Value;
43 typedef std::map<std::string, Value> StringToValue;
44 typedef std::map<Value, std::string> ValueToString;
45
46 IntLookup() {}
47 unsigned int size() const { return static_cast<unsigned int>(_stringToValue.size()); }
48
49 void add( const char* str, Value value )
50 {
51 if ( _valueToString.find(value)!=_valueToString.end() )
52 {
53 osg::notify(osg::INFO) << "Duplicate enum value " << value
54 << " with old string: " << _valueToString[value]
55 << " and new string: " << str << std::endl;
56 }
57 _valueToString[value] = str;
58 _stringToValue[str] = value;
59 }
60
61 void add2(const char* str, const char* newStr, Value value) {
62 if (_valueToString.find(value) != _valueToString.end())
63 {
64 osg::notify(osg::INFO) << "Duplicate enum value " << value
65 << " with old string: " << _valueToString[value]
66 << " and new strings: " << str << " and " << newStr << std::endl;
67 }
68 _valueToString[value] = newStr;
69 _stringToValue[newStr] = value;
70 _stringToValue[str] = value;
71 }
72
73 Value getValue( const char* str )
74 {
75 StringToValue::iterator itr = _stringToValue.find(str);
76 if ( itr==_stringToValue.end() )
77 {
78 Value value;
79 std::stringstream stream;
80 stream << str; stream >> value;
81 _stringToValue[str] = value;
82 return value;
83 }
84 return itr->second;
85 }
86
87 const std::string& getString( Value value )
88 {
89 ValueToString::iterator itr = _valueToString.find(value);
90 if ( itr==_valueToString.end() )
91 {
92 std::string str;
93 std::stringstream stream;
94 stream << value; stream >> str;
95 _valueToString[value] = str;
96 return _valueToString[value];
97 }
98 return itr->second;
99 }
100
101 StringToValue& getStringToValue() { return _stringToValue; }
102 const StringToValue& getStringToValue() const { return _stringToValue; }
103
104 ValueToString& getValueToString() { return _valueToString; }
105 const ValueToString& getValueToString() const { return _valueToString; }
106
107protected:
108 StringToValue _stringToValue;
109 ValueToString _valueToString;
110};
111
112class UserLookupTableProxy
113{
114public:
115 typedef void (*AddValueFunc)( IntLookup* lookup );
116 UserLookupTableProxy( AddValueFunc func ) { if ( func ) (*func)(&_lookup); }
117
118 IntLookup _lookup;
119};
120
121#define BEGIN_USER_TABLE(NAME, CLASS) \
122 static void add_user_value_func_##NAME(osgDB::IntLookup*); \
123 static osgDB::UserLookupTableProxy s_user_lookup_table_##NAME(&add_user_value_func_##NAME); \
124 static void add_user_value_func_##NAME(osgDB::IntLookup* lookup) { typedef CLASS MyClass
125#define ADD_USER_VALUE(VALUE) lookup->add(#VALUE, MyClass::VALUE)
126#define END_USER_TABLE() }
127
128#define USER_READ_FUNC(NAME, FUNCNAME) \
129 static int FUNCNAME(osgDB::InputStream& is) { \
130 int value; if (is.isBinary()) is >> value; \
131 else { std::string str; is >> str; \
132 value = (s_user_lookup_table_##NAME)._lookup.getValue(str.c_str()); } \
133 return value; }
134
135#define USER_WRITE_FUNC(NAME, FUNCNAME) \
136 static void FUNCNAME(osgDB::OutputStream& os, int value) { \
137 if (os.isBinary()) os << value; \
138 else os << (s_user_lookup_table_##NAME)._lookup.getString(value); } \
139
140class BaseSerializer : public osg::Referenced
141{
142 friend class ObjectWrapper;
143public:
144 enum Type
145 {
146 RW_UNDEFINED = 0, RW_USER, RW_OBJECT, RW_IMAGE, RW_LIST,
147 RW_BOOL, RW_CHAR, RW_UCHAR, RW_SHORT, RW_USHORT, RW_INT, RW_UINT, RW_FLOAT, RW_DOUBLE,
148 RW_VEC2F, RW_VEC2D, RW_VEC3F, RW_VEC3D, RW_VEC4F, RW_VEC4D, RW_QUAT, RW_PLANE,
149 RW_MATRIXF, RW_MATRIXD, RW_MATRIX, RW_GLENUM, RW_STRING, RW_ENUM,
150 RW_VEC2B, RW_VEC2UB, RW_VEC2S, RW_VEC2US, RW_VEC2I, RW_VEC2UI,
151 RW_VEC3B, RW_VEC3UB, RW_VEC3S, RW_VEC3US, RW_VEC3I, RW_VEC3UI,
152 RW_VEC4B, RW_VEC4UB, RW_VEC4S, RW_VEC4US, RW_VEC4I, RW_VEC4UI,
153 RW_BOUNDINGBOXF, RW_BOUNDINGBOXD,
154 RW_BOUNDINGSPHEREF, RW_BOUNDINGSPHERED,
155 RW_VECTOR, RW_MAP
156 };
157
158 enum Usage
159 {
160 READ_WRITE_PROPERTY = 1,
161 GET_PROPERTY = 2,
162 SET_PROPERTY = 4,
163 GET_SET_PROPERTY = GET_PROPERTY | SET_PROPERTY
164 };
165
166
167 BaseSerializer(int usage) : _firstVersion(0), _lastVersion(INT_MAX), _usage(usage) {}
168
169 virtual bool set(osg::Object& /*object*/, void* /*value*/) { return false; }
170 virtual bool get(const osg::Object& /*object*/, void* /*value*/) { return false; }
171
172 virtual bool read( InputStream&, osg::Object& ) = 0;
173 virtual bool write( OutputStream&, const osg::Object& ) = 0;
174 virtual const std::string& getName() const = 0;
175
176 virtual IntLookup* getIntLookup() { return 0; }
177
178 void setUsage(int usage) { _usage = usage; }
179 int getUsage() const { return _usage; }
180
181 void setUsage(bool hasGetter, bool hasSetter)
182 {
183 setUsage( ((hasGetter && hasSetter) ? BaseSerializer::READ_WRITE_PROPERTY : 0) |
184 ((hasGetter) ? BaseSerializer::GET_PROPERTY : 0) |
185 ((hasSetter) ? BaseSerializer::SET_PROPERTY : 0) );
186 }
187
188 bool supportsReadWrite() const { return (_usage & READ_WRITE_PROPERTY)!=0; }
189 bool supportsGetSet() const { return (_usage & GET_SET_PROPERTY)!=0; }
190 bool supportsGet() const { return (_usage & GET_PROPERTY)!=0; }
191 bool supportsSet() const { return (_usage & SET_PROPERTY)!=0; }
192
193protected:
194 int _firstVersion; // Library version when the serializer is first introduced
195 int _lastVersion; // Library version when the serializer is last required.
196 int _usage; // How the Serializer can be used.
197};
198
199template<typename C>
200class UserSerializer : public BaseSerializer
201{
202public:
203 typedef bool (*Checker)( const C& );
204 typedef bool (*Reader)( InputStream&, C& );
205 typedef bool (*Writer)( OutputStream&, const C& );
206
207 UserSerializer( const char* name, Checker cf, Reader rf, Writer wf )
208 : BaseSerializer(READ_WRITE_PROPERTY), _name(name), _checker(cf), _reader(rf), _writer(wf) {}
209
210 virtual bool read( InputStream& is, osg::Object& obj )
211 {
212 C& object = OBJECT_CAST<C&>(obj);
213 if ( is.isBinary() )
214 {
215 bool ok = false; is >> ok;
216 if ( !ok ) return true;
217 }
218 else
219 {
220 if ( !is.matchString(_name) )
221 return true;
222 }
223 return (*_reader)(is, object);
224 }
225
226 virtual bool write( OutputStream& os, const osg::Object& obj )
227 {
228 const C& object = OBJECT_CAST<const C&>(obj);
229 bool ok = (*_checker)(object);
230 if ( os.isBinary() )
231 {
232 os << ok;
233 if ( !ok ) return true;
234 }
235 else
236 {
237 if ( !ok ) return true;
238 os << os.PROPERTY(_name.c_str());
239 }
240 return (*_writer)(os, object);
241 }
242
243 virtual const std::string& getName() const { return _name; }
244
245protected:
246 std::string _name;
247 Checker _checker;
248
249public:
250 Reader _reader;
251 Writer _writer;
252};
253
254template<typename P>
255class TemplateSerializer : public BaseSerializer
256{
257public:
258
259 TemplateSerializer( const char* name, P def)
260 : BaseSerializer(READ_WRITE_PROPERTY), _name(name), _defaultValue(def) {}
261
262 virtual bool read( InputStream& is, osg::Object& obj ) = 0;
263 virtual bool write( OutputStream& os, const osg::Object& obj ) = 0;
264 virtual const std::string& getName() const { return _name; }
265
266protected:
267 std::string _name;
268 P _defaultValue;
269};
270
271template<typename C, typename P>
272class PropByValSerializer : public TemplateSerializer<P>
273{
274public:
275 typedef TemplateSerializer<P> ParentType;
276 typedef P (C::*Getter)() const;
277 typedef void (C::*Setter)( P );
278
279 PropByValSerializer( const char* name, P def, Getter gf, Setter sf, bool useHex=false ) : ParentType(name, def), _getter(gf), _setter(sf), _useHex(useHex)
280 {
281 ParentType::setUsage( _getter!=0, _setter!=0);
282 }
283
284 virtual bool read( InputStream& is, osg::Object& obj )
285 {
286 C& object = OBJECT_CAST<C&>(obj);
287 P value;
288 if ( is.isBinary() )
289 {
290 is >> value;
291 (object.*_setter)( value );
292 }
293 else if ( is.matchString(ParentType::_name) )
294 {
295 if ( _useHex ) is >> std::hex;
296 is >> value;
297 if ( _useHex ) is >> std::dec;
298 (object.*_setter)( value );
299 }
300 return true;
301 }
302
303 virtual bool write( OutputStream& os, const osg::Object& obj )
304 {
305 const C& object = OBJECT_CAST<const C&>(obj);
306 P value = (object.*_getter)();
307 if ( os.isBinary() )
308 {
309 os << value;
310 }
311 else if ( ParentType::_defaultValue!=value )
312 {
313 os << os.PROPERTY((ParentType::_name).c_str());
314 if ( _useHex ) { os << std::hex << std::showbase; }
315 os << value;
316 if ( _useHex ) os << std::dec << std::noshowbase;
317 os << std::endl;
318 }
319 return true;
320 }
321
322public:
323 Getter _getter;
324 Setter _setter;
325
326protected:
327 bool _useHex;
328};
329
330template<typename C, typename P>
331class PropByRefSerializer : public TemplateSerializer<P>
332{
333public:
334 typedef TemplateSerializer<P> ParentType;
335 typedef const P& CP;
336 typedef CP (C::*Getter)() const;
337 typedef void (C::*Setter)( CP );
338
339 PropByRefSerializer( const char* name, CP def, Getter gf, Setter sf ) : ParentType(name, def), _getter(gf), _setter(sf)
340 {
341 ParentType::setUsage( _getter!=0, _setter!=0);
342 }
343
344 virtual bool read( InputStream& is, osg::Object& obj )
345 {
346 C& object = OBJECT_CAST<C&>(obj);
347 P value;
348 if ( is.isBinary() )
349 {
350 is >> value;
351 (object.*_setter)( value );
352 }
353 else if ( is.matchString(ParentType::_name) )
354 {
355 is >> value;
356 (object.*_setter)( value );
357 }
358 return true;
359 }
360
361 virtual bool write( OutputStream& os, const osg::Object& obj )
362 {
363 const C& object = OBJECT_CAST<const C&>(obj);
364 CP value = (object.*_getter)();
365 if ( os.isBinary() )
366 {
367 os << value;
368 }
369 else if ( ParentType::_defaultValue!=value )
370 {
371 os << os.PROPERTY((ParentType::_name).c_str()) << value << std::endl;
372 }
373 return true;
374 }
375
376public:
377 Getter _getter;
378 Setter _setter;
379};
380
381template<typename C>
382class MatrixSerializer : public TemplateSerializer<osg::Matrix>
383{
384public:
385 typedef TemplateSerializer<osg::Matrix> ParentType;
386 typedef const osg::Matrix& (C::*Getter)() const;
387 typedef void (C::*Setter)( const osg::Matrix& );
388
389 MatrixSerializer( const char* name, const osg::Matrix& def, Getter gf, Setter sf ) : ParentType(name, def), _getter(gf), _setter(sf)
390 {
391 ParentType::setUsage( _getter!=0, _setter!=0);
392 }
393
394 virtual bool read( InputStream& is, osg::Object& obj )
395 {
396 C& object = OBJECT_CAST<C&>(obj);
397 osg::Matrix value;
398 if ( is.isBinary() )
399 {
400 readMatrixImplementation( is, value );
401 (object.*_setter)( value );
402 }
403 else if ( is.matchString(ParentType::_name) )
404 {
405 readMatrixImplementation( is, value );
406 (object.*_setter)( value );
407 }
408 return true;
409 }
410
411 virtual bool write( OutputStream& os, const osg::Object& obj )
412 {
413
414 const C& object = OBJECT_CAST<const C&>(obj);
415 const osg::Matrix& value = (object.*_getter)();
416 if ( os.isBinary() )
417 {
418 os << value;
419 }
420 else if ( ParentType::_defaultValue!=value )
421 {
422 os << os.PROPERTY((ParentType::_name).c_str()) << value << std::endl;
423 }
424 return true;
425 }
426
427protected:
428 void readMatrixImplementation( InputStream& is, osg::Matrix& matrix )
429 {
430#if 1
431 is >> matrix;
432#else
433 if ( is.getUseFloatMatrix() )
434 {
435 osg::Matrixf realValue; is >> realValue;
436 matrix = realValue;
437 }
438 else
439 {
440 osg::Matrixd realValue; is >> realValue;
441 matrix = realValue;
442 }
443#endif
444 }
445
446public:
447 Getter _getter;
448 Setter _setter;
449};
450
451template<typename C, typename P>
452class GLenumSerializer : public TemplateSerializer<P>
453{
454public:
455 typedef TemplateSerializer<P> ParentType;
456 typedef P (C::*Getter)() const;
457 typedef void (C::*Setter)( P );
458
459 GLenumSerializer( const char* name, P def, Getter gf, Setter sf ) : ParentType(name, def), _getter(gf), _setter(sf)
460 {
461 ParentType::setUsage( _getter!=0, _setter!=0);
462 }
463
464 virtual bool read( InputStream& is, osg::Object& obj )
465 {
466 C& object = OBJECT_CAST<C&>(obj);
467 if ( is.isBinary() )
468 {
469 GLenum value; is >> value;
470 (object.*_setter)( static_cast<P>(value) );
471 }
472 else if ( is.matchString(ParentType::_name) )
473 {
474 DEF_GLENUM(value); is >> value;
475 (object.*_setter)( static_cast<P>(value.get()) );
476 }
477 return true;
478 }
479
480 virtual bool write( OutputStream& os, const osg::Object& obj )
481 {
482 const C& object = OBJECT_CAST<const C&>(obj);
483 const P value = (object.*_getter)();
484 if ( os.isBinary() )
485 {
486 os << static_cast<GLenum>(value);
487 }
488 else if ( ParentType::_defaultValue!=value )
489 {
490 os << os.PROPERTY((ParentType::_name).c_str()) << GLENUM(value) << std::endl;
491 }
492 return true;
493 }
494
495public:
496 Getter _getter;
497 Setter _setter;
498};
499
500template<typename C>
501class StringSerializer : public TemplateSerializer<std::string>
502{
503public:
504 typedef TemplateSerializer<std::string> ParentType;
505 typedef const std::string& (C::*Getter)() const;
506 typedef void (C::*Setter)( const std::string& );
507
508 StringSerializer( const char* name, const std::string& def, Getter gf, Setter sf ) : ParentType(name, def), _getter(gf), _setter(sf)
509 {
510 ParentType::setUsage( _getter!=0, _setter!=0);
511 }
512
513 virtual bool read( InputStream& is, osg::Object& obj )
514 {
515 C& object = OBJECT_CAST<C&>(obj);
516 std::string value;
517 if ( is.isBinary() )
518 {
519 is >> value;
520 (object.*_setter)( value );
521 }
522 else if ( is.matchString(ParentType::_name) )
523 {
524 is.readWrappedString( value );
525 if ( !value.empty() && (_setter!=0) )
526 (object.*_setter)( value );
527 }
528 return true;
529 }
530
531 virtual bool write( OutputStream& os, const osg::Object& obj )
532 {
533 const C& object = OBJECT_CAST<const C&>(obj);
534 const std::string& value = (object.*_getter)();
535 if ( os.isBinary() )
536 {
537 os << value;
538 }
539 else if ( ParentType::_defaultValue!=value )
540 {
541 os << os.PROPERTY((ParentType::_name).c_str());
542 os.writeWrappedString( value );
543 os << std::endl;
544 }
545 return true;
546 }
547
548public:
549 Getter _getter;
550 Setter _setter;
551};
552
553template<typename C, typename P>
554class ObjectSerializer : public BaseSerializer
555{
556public:
557 typedef const P* (C::*Getter)() const;
558 typedef void (C::*Setter)( P* );
559
560 ObjectSerializer( const char* name, P* def, Getter gf, Setter sf ) :
561 BaseSerializer(READ_WRITE_PROPERTY),
562 _name(name), _defaultValue(def), _getter(gf), _setter(sf)
563 {
564 setUsage( _getter!=0, _setter!=0);
565 }
566
567 virtual bool set(osg::Object& obj, void* value) { C& object = OBJECT_CAST<C&>(obj); (object.*_setter)( dynamic_cast<P*>(*(reinterpret_cast<osg::Object**>(value))) ); return true; }
568 virtual bool get(const osg::Object& obj, void* value) { const C& object = OBJECT_CAST<const C&>(obj);*(reinterpret_cast<const osg::Object**>(value )) = dynamic_cast<const osg::Object*>((object.*_getter)()); return true; }
569
570 virtual const std::string& getName() const { return _name; }
571
572 virtual bool read( InputStream& is, osg::Object& obj )
573 {
574 C& object = OBJECT_CAST<C&>(obj);
575 bool hasObject = false;
576 if ( is.isBinary() )
577 {
578 is >> hasObject;
579 if ( hasObject )
580 {
581 osg::ref_ptr<P> value = is.readObjectOfType<P>();
582 (object.*_setter)( value.get() );
583 }
584 }
585 else if ( is.matchString(_name) )
586 {
587 is >> hasObject;
588 if ( hasObject )
589 {
590 is >> is.BEGIN_BRACKET;
591 osg::ref_ptr<P> value = is.readObjectOfType<P>();
592 (object.*_setter)( value.get() );
593 is >> is.END_BRACKET;
594 }
595 }
596 return true;
597 }
598
599 virtual bool write( OutputStream& os, const osg::Object& obj )
600 {
601 const C& object = OBJECT_CAST<const C&>(obj);
602 const P* value = (object.*_getter)();
603 bool hasObject = (value!=NULL);
604 if ( os.isBinary() )
605 {
606 os << hasObject;
607 if (hasObject)
608 {
609 os.writeObject( value );
610 }
611 }
612 else if ( _defaultValue!=value )
613 {
614 os << os.PROPERTY(_name.c_str()) << hasObject;
615 if ( hasObject )
616 {
617 os << os.BEGIN_BRACKET << std::endl;
618 os.writeObject( value );
619 os << os.END_BRACKET;
620 }
621 os << std::endl;
622 }
623 return true;
624 }
625
626public:
627 std::string _name;
628 osg::ref_ptr<P> _defaultValue;
629 Getter _getter;
630 Setter _setter;
631};
632
633template<typename C, typename P>
634class ImageSerializer : public TemplateSerializer<P*>
635{
636public:
637 typedef TemplateSerializer<P*> ParentType;
638 typedef const P* (C::*Getter)() const;
639 typedef void (C::*Setter)( P* );
640
641 ImageSerializer( const char* name, P* def, Getter gf, Setter sf ):
642 ParentType(name, def), _getter(gf), _setter(sf)
643 {
644 ParentType::setUsage( _getter!=0, _setter!=0);
645 }
646
647 virtual bool set(osg::Object& obj, void* value) { C& object = OBJECT_CAST<C&>(obj); (object.*_setter)( *(reinterpret_cast<P**>(value)) ); return true; }
648 virtual bool get(const osg::Object& obj, void* value) { const C& object = OBJECT_CAST<const C&>(obj);*(reinterpret_cast<const P**>(value )) = (object.*_getter)(); return true; }
649
650 virtual bool read( InputStream& is, osg::Object& obj )
651 {
652 C& object = OBJECT_CAST<C&>(obj);
653 bool hasObject = false;
654 if ( is.isBinary() )
655 {
656 is >> hasObject;
657 if ( hasObject )
658 {
659 osg::ref_ptr<osg::Image> image = is.readImage();
660 P* value = dynamic_cast<P*>( image.get() );
661 (object.*_setter)( value );
662 }
663 }
664 else if ( is.matchString(ParentType::_name) )
665 {
666 is >> hasObject;
667 if ( hasObject )
668 {
669 is >> is.BEGIN_BRACKET;
670 osg::ref_ptr<osg::Image> image = is.readImage();
671 P* value = dynamic_cast<P*>( image.get() );
672 (object.*_setter)( value );
673 is >> is.END_BRACKET;
674 }
675 }
676 return true;
677 }
678
679 virtual bool write( OutputStream& os, const osg::Object& obj )
680 {
681 const C& object = OBJECT_CAST<const C&>(obj);
682 const P* value = (object.*_getter)();
683 bool hasObject = (value!=NULL);
684 if ( os.isBinary() )
685 {
686 os << hasObject;
687 os.writeImage( value );
688 }
689 else if ( ParentType::_defaultValue!=value )
690 {
691 os << os.PROPERTY((ParentType::_name).c_str()) << hasObject;
692 if ( hasObject )
693 {
694 os << os.BEGIN_BRACKET << std::endl;
695 os.writeImage( value );
696 os << os.END_BRACKET;
697 }
698 os << std::endl;
699 }
700 return true;
701 }
702
703public:
704 Getter _getter;
705 Setter _setter;
706};
707
708template<typename C, typename P, typename B>
709class EnumSerializer : public TemplateSerializer<P>
710{
711public:
712 typedef TemplateSerializer<P> ParentType;
713 typedef P (C::*Getter)() const;
714 typedef B (C::*Setter)( P );
715
716 EnumSerializer( const char* name, P def, Getter gf, Setter sf ) : ParentType(name, def), _getter(gf), _setter(sf)
717 {
718 ParentType::setUsage( _getter!=0, _setter!=0);
719 }
720
721 virtual IntLookup* getIntLookup() { return &_lookup; }
722
723 void add( const char* str, P value )
724 { _lookup.add(str, static_cast<IntLookup::Value>(value)); }
725
726 P getValue( const char* str )
727 { return static_cast<P>(_lookup.getValue(str)); }
728
729 const std::string& getString( P value )
730 { return _lookup.getString(static_cast<IntLookup::Value>(value)); }
731
732 virtual bool read( InputStream& is, osg::Object& obj )
733 {
734 C& object = OBJECT_CAST<C&>(obj);
735 IntLookup::Value value;
736 if ( is.isBinary() )
737 {
738 is >> value;
739 (object.*_setter)( static_cast<P>(value) );
740 }
741 else if ( is.matchString(ParentType::_name) )
742 {
743 std::string str; is >> str;
744 (object.*_setter)( getValue(str.c_str()) );
745 }
746 return true;
747 }
748
749 virtual bool write( osgDB::OutputStream& os, const osg::Object& obj )
750 {
751 const C& object = OBJECT_CAST<const C&>(obj);
752 const P value = (object.*_getter)();
753 if ( os.isBinary() )
754 {
755 os << (IntLookup::Value)value;
756 }
757 else if ( ParentType::_defaultValue!=value )
758 {
759 os << os.PROPERTY((ParentType::_name).c_str()) << getString(value) << std::endl;
760 }
761 return true;
762 }
763
764public:
765 Getter _getter;
766 Setter _setter;
767
768protected:
769 IntLookup _lookup;
770};
771
772
773template<typename C, typename P>
774class ListSerializer : public BaseSerializer
775{
776public:
777 typedef typename P::value_type ValueType;
778 typedef typename P::const_iterator ConstIterator;
779 typedef const P& (C::*Getter)() const;
780 typedef void (C::*Setter)( const P& );
781
782 ListSerializer( const char* name, Getter gf, Setter sf ):
783 BaseSerializer(READ_WRITE_PROPERTY),
784 _name(name), _getter(gf), _setter(sf) {}
785
786 virtual const std::string& getName() const { return _name; }
787
788 virtual bool read( InputStream& is, osg::Object& obj )
789 {
790 C& object = OBJECT_CAST<C&>(obj);
791 unsigned int size = 0;
792 P list;
793 if ( is.isBinary() )
794 {
795 is >> size;
796 for ( unsigned int i=0; i<size; ++i )
797 {
798 ValueType value;
799 is >> value;
800 list.push_back( value );
801 }
802 if ( size>0 ) (object.*_setter)( list );
803 }
804 else if ( is.matchString(_name) )
805 {
806 is >> size;
807 if ( size>0 ) is >> is.BEGIN_BRACKET;
808 for ( unsigned int i=0; i<size; ++i )
809 {
810 ValueType value;
811 is >> value;
812 list.push_back( value );
813 }
814 if ( size>0 )
815 {
816 is >> is.END_BRACKET;
817 (object.*_setter)( list );
818 }
819 }
820 return true;
821 }
822
823 virtual bool write( OutputStream& os, const osg::Object& obj )
824 {
825 const C& object = OBJECT_CAST<const C&>(obj);
826 const P& list = (object.*_getter)();
827 unsigned int size = (unsigned int)list.size();
828 if ( os.isBinary() )
829 {
830 os << size;
831 for ( ConstIterator itr=list.begin();
832 itr!=list.end(); ++itr )
833 {
834 os << (*itr);
835 }
836 }
837 else if ( size>0 )
838 {
839 os << os.PROPERTY((_name).c_str()) << size << os.BEGIN_BRACKET << std::endl;
840 for ( ConstIterator itr=list.begin();
841 itr!=list.end(); ++itr )
842 {
843 os << (*itr);
844 }
845 os << std::endl;
846 os << os.END_BRACKET << std::endl;
847 }
848 return true;
849 }
850
851public:
852 std::string _name;
853 Getter _getter;
854 Setter _setter;
855};
856
857class VectorBaseSerializer : public BaseSerializer
858{
859public:
860
861 VectorBaseSerializer(BaseSerializer::Type elementType, unsigned int elementSize):
862 BaseSerializer(READ_WRITE_PROPERTY|GET_SET_PROPERTY),
863 _elementType(elementType),_elementSize(elementSize) {}
864
865 Type getElementType() const { return _elementType; }
866 unsigned int getElementSize() const { return _elementSize; }
867
868 virtual unsigned int size(const osg::Object& /*obj*/) const { return 0; }
869 virtual void resize(osg::Object& /*obj*/, unsigned int /*numElements*/) const {}
870 virtual void reserve(osg::Object& /*obj*/, unsigned int /*numElements*/) const {}
871 virtual void clear(osg::Object& /*obj*/) const {}
872 virtual void addElement(osg::Object& /*obj*/, void* /*ptr*/) const {}
873 virtual void insertElement(osg::Object& /*obj*/, unsigned int /*index*/, void* /*ptr*/) const {}
874 virtual void setElement(osg::Object& /*obj*/, unsigned int /*index*/, void* /*ptr*/) const {}
875 virtual void* getElement(osg::Object& /*obj*/, unsigned int /*index*/) const { return 0; }
876 virtual const void* getElement(const osg::Object& /*obj*/, unsigned int /*index*/) const { return 0; }
877
878protected:
879 Type _elementType;
880 unsigned int _elementSize;
881};
882
883
884template<typename C, typename P>
885class VectorSerializer : public VectorBaseSerializer
886{
887public:
888 typedef typename P::value_type ValueType;
889 typedef typename P::const_iterator ConstIterator;
890 typedef P& (C::*Getter)();
891 typedef const P& (C::*ConstGetter)() const;
892 typedef void (C::*Setter)( const P& );
893
894 VectorSerializer( const char* name, ConstGetter cgf, Getter gf, Setter sf, BaseSerializer::Type elementType, unsigned int numElementsOnRow):
895 VectorBaseSerializer(elementType, sizeof(ValueType)),
896 _name(name),
897 _constgetter(cgf), _getter(gf), _setter(sf),
898 _numElementsOnRow(numElementsOnRow) {}
899
900 virtual const std::string& getName() const { return _name; }
901
902 virtual unsigned int size(const osg::Object& obj) const
903 {
904 const C& object = OBJECT_CAST<const C&>(obj);
905 const P& list = (object.*_constgetter)();
906 return static_cast<unsigned int>(list.size());
907 }
908 virtual void resize(osg::Object& obj, unsigned int numElements) const
909 {
910 C& object = OBJECT_CAST<C&>(obj);
911 P& list = (object.*_getter)();
912 list.resize(numElements);
913 }
914 virtual void reserve(osg::Object& obj, unsigned int numElements) const
915 {
916 C& object = OBJECT_CAST<C&>(obj);
917 P& list = (object.*_getter)();
918 list.reserve(numElements);
919 }
920 virtual void clear(osg::Object& obj) const
921 {
922 C& object = OBJECT_CAST<C&>(obj);
923 P& list = (object.*_getter)();
924 list.clear();
925 }
926 virtual void addElement(osg::Object& obj, void* ptr) const
927 {
928 C& object = OBJECT_CAST<C&>(obj);
929 P& list = (object.*_getter)();
930 list.push_back(*reinterpret_cast<ValueType*>(ptr));
931 }
932 virtual void insertElement(osg::Object& obj, unsigned int index, void* ptr) const
933 {
934 C& object = OBJECT_CAST<C&>(obj);
935 P& list = (object.*_getter)();
936 if (index>=list.size()) list.resize(index+1);
937 list.insert(list.begin()+index, *reinterpret_cast<ValueType*>(ptr));
938 }
939 virtual void setElement(osg::Object& obj, unsigned int index, void* ptr) const
940 {
941 C& object = OBJECT_CAST<C&>(obj);
942 P& list = (object.*_getter)();
943 if (index>=list.size()) list.resize(index+1);
944 list[index] = *reinterpret_cast<ValueType*>(ptr);
945 }
946 virtual void* getElement(osg::Object& obj, unsigned int index) const
947 {
948 C& object = OBJECT_CAST<C&>(obj);
949 P& list = (object.*_getter)();
950 if (index>=list.size()) return 0;
951 else return &list[index];
952 }
953 virtual const void* getElement(const osg::Object& obj, unsigned int index) const
954 {
955 const C& object = OBJECT_CAST<const C&>(obj);
956 const P& list = (object.*_constgetter)();
957 if (index>=list.size()) return 0;
958 else return &list[index];
959 }
960
961 virtual bool read( InputStream& is, osg::Object& obj )
962 {
963 C& object = OBJECT_CAST<C&>(obj);
964 unsigned int size = 0;
965 P list;
966 if ( is.isBinary() )
967 {
968 is >> size;
969 list.reserve(size);
970 for ( unsigned int i=0; i<size; ++i )
971 {
972 ValueType value;
973 is >> value;
974 list.push_back( value );
975 }
976 if ( size>0 ) (object.*_setter)( list );
977 }
978 else if ( is.matchString(_name) )
979 {
980 is >> size;
981 list.reserve(size);
982 if ( size>0 ) is >> is.BEGIN_BRACKET;
983 for ( unsigned int i=0; i<size; ++i )
984 {
985 ValueType value;
986 is >> value;
987 list.push_back( value );
988 }
989 if ( size>0 )
990 {
991 is >> is.END_BRACKET;
992 (object.*_setter)( list );
993 }
994 }
995 return true;
996 }
997
998 virtual bool write( OutputStream& os, const osg::Object& obj )
999 {
1000 const C& object = OBJECT_CAST<const C&>(obj);
1001 const P& list = (object.*_constgetter)();
1002 unsigned int size = (unsigned int)list.size();
1003 if ( os.isBinary() )
1004 {
1005 os << size;
1006 for ( ConstIterator itr=list.begin();
1007 itr!=list.end(); ++itr )
1008 {
1009 os << (*itr);
1010 }
1011 }
1012 else if ( size>0 )
1013 {
1014 os << os.PROPERTY((_name).c_str()) << size << os.BEGIN_BRACKET << std::endl;
1015 if (_numElementsOnRow==0)
1016 {
1017 for ( ConstIterator itr=list.begin(); itr!=list.end(); ++itr )
1018 {
1019 os << (*itr);
1020 }
1021 }
1022 else if (_numElementsOnRow==1)
1023 {
1024 for ( ConstIterator itr=list.begin(); itr!=list.end(); ++itr )
1025 {
1026 os << (*itr); os << std::endl;
1027 }
1028 }
1029 else
1030 {
1031 unsigned int i = _numElementsOnRow-1;
1032 for (ConstIterator itr=list.begin(); itr!=list.end(); ++itr)
1033 {
1034 os << (*itr);
1035 if (i==0) { os << std::endl; i = _numElementsOnRow-1; }
1036 else --i;
1037 }
1038 if (i!=_numElementsOnRow) os << std::endl;
1039 }
1040 os << os.END_BRACKET << std::endl;
1041 }
1042 return true;
1043 }
1044
1045public:
1046 std::string _name;
1047 ConstGetter _constgetter;
1048 Getter _getter;
1049 Setter _setter;
1050 unsigned int _numElementsOnRow;
1051};
1052
1053
1054template<typename C>
1055class IsAVectorSerializer : public VectorBaseSerializer
1056{
1057public:
1058 typedef typename C::value_type ValueType;
1059 typedef typename C::const_iterator ConstIterator;
1060
1061 IsAVectorSerializer( const char* name, BaseSerializer::Type elementType, unsigned int numElementsOnRow) :
1062 VectorBaseSerializer(elementType, sizeof(ValueType)),
1063 _name(name),
1064 _numElementsOnRow(numElementsOnRow) {}
1065
1066 virtual const std::string& getName() const { return _name; }
1067
1068 virtual unsigned int size(const osg::Object& obj) const
1069 {
1070 const C& list = OBJECT_CAST<const C&>(obj);
1071 return static_cast<unsigned int>(list.size());
1072 }
1073 virtual void resize(osg::Object& obj, unsigned int numElements) const
1074 {
1075 C& list = OBJECT_CAST<C&>(obj);
1076 list.resize(numElements);
1077 }
1078 virtual void reserve(osg::Object& obj, unsigned int numElements) const
1079 {
1080 C& list = OBJECT_CAST<C&>(obj);
1081 list.reserve(numElements);
1082 }
1083 virtual void clear(osg::Object& obj) const
1084 {
1085 C& list = OBJECT_CAST<C&>(obj);
1086 list.clear();
1087 }
1088 virtual void addElement(osg::Object& obj, void* ptr) const
1089 {
1090 C& list = OBJECT_CAST<C&>(obj);
1091 list.push_back(*reinterpret_cast<ValueType*>(ptr));
1092 }
1093 virtual void insertElement(osg::Object& obj, unsigned int index, void* ptr) const
1094 {
1095 C& list = OBJECT_CAST<C&>(obj);
1096 if (index>=list.size()) list.resize(index+1);
1097 list.insert(list.begin()+index, *reinterpret_cast<ValueType*>(ptr));
1098 }
1099 virtual void setElement(osg::Object& obj, unsigned int index, void* ptr) const
1100 {
1101 C& list = OBJECT_CAST<C&>(obj);
1102 if (index>=list.size()) list.resize(index+1);
1103 list[index] = *reinterpret_cast<ValueType*>(ptr);
1104 }
1105 virtual void* getElement(osg::Object& obj, unsigned int index) const
1106 {
1107 C& list = OBJECT_CAST<C&>(obj);
1108 if (index>=list.size()) return 0;
1109 else return &list[index];
1110 }
1111
1112 virtual const void* getElement(const osg::Object& obj, unsigned int index) const
1113 {
1114 const C& list = OBJECT_CAST<const C&>(obj);
1115 if (index>=list.size()) return 0;
1116 else return &list[index];
1117 }
1118
1119 virtual bool read( InputStream& is, osg::Object& obj )
1120 {
1121 C& list = OBJECT_CAST<C&>(obj);
1122 unsigned int size = 0;
1123 if ( is.isBinary() )
1124 {
1125 is >> size;
1126 list.reserve(size);
1127 for ( unsigned int i=0; i<size; ++i )
1128 {
1129 ValueType value;
1130 is >> value;
1131 list.push_back( value );
1132 }
1133 }
1134 else if ( is.matchString(_name) )
1135 {
1136 is >> size;
1137 list.reserve(size);
1138 if ( size>0 ) is >> is.BEGIN_BRACKET;
1139 for ( unsigned int i=0; i<size; ++i )
1140 {
1141 ValueType value;
1142 is >> value;
1143 list.push_back( value );
1144 }
1145 if ( size>0 )
1146 {
1147 is >> is.END_BRACKET;
1148 }
1149 }
1150 return true;
1151 }
1152
1153 virtual bool write( OutputStream& os, const osg::Object& obj )
1154 {
1155 const C& list = OBJECT_CAST<const C&>(obj);
1156 unsigned int size = (unsigned int)list.size();
1157 if ( os.isBinary() )
1158 {
1159 os << size;
1160 for ( ConstIterator itr=list.begin();
1161 itr!=list.end(); ++itr )
1162 {
1163 os << (*itr);
1164 }
1165 }
1166 else if ( size>0 )
1167 {
1168 os << os.PROPERTY((_name).c_str()) << size << os.BEGIN_BRACKET << std::endl;
1169 if (_numElementsOnRow==0)
1170 {
1171 for ( ConstIterator itr=list.begin(); itr!=list.end(); ++itr )
1172 {
1173 os << (*itr);
1174 }
1175 }
1176 else if (_numElementsOnRow==1)
1177 {
1178 for ( ConstIterator itr=list.begin(); itr!=list.end(); ++itr )
1179 {
1180 os << (*itr); os << std::endl;
1181 }
1182 }
1183 else
1184 {
1185 unsigned int i = _numElementsOnRow-1;
1186 for (ConstIterator itr=list.begin(); itr!=list.end(); ++itr)
1187 {
1188 os << (*itr);
1189 if (i==0) { os << std::endl; i = _numElementsOnRow-1; }
1190 else --i;
1191 }
1192 if (i!=_numElementsOnRow) os << std::endl;
1193 }
1194 os << os.END_BRACKET << std::endl;
1195 }
1196 return true;
1197 }
1198
1199public:
1200 std::string _name;
1201 unsigned int _numElementsOnRow;
1202};
1203
1204class MapIteratorObject : public osg::Object
1205{
1206public:
1207 MapIteratorObject():
1208 _keyType(BaseSerializer::RW_UNDEFINED), _keySize(0),
1209 _elementType(BaseSerializer::RW_UNDEFINED),_elementSize(0) {}
1210
1211 MapIteratorObject(BaseSerializer::Type keyType, unsigned int keySize, BaseSerializer::Type elementType, unsigned int elementSize):
1212 _keyType(keyType), _keySize(keySize),
1213 _elementType(elementType),_elementSize(elementSize) {}
1214
1215 MapIteratorObject(const MapIteratorObject& rhs, const osg::CopyOp copyop=osg::CopyOp::SHALLOW_COPY):
1216 osg::Object(rhs, copyop),
1217 _keyType(rhs._keyType), _keySize(rhs._keySize),
1218 _elementType(rhs._elementType),_elementSize(rhs._elementSize) {}
1219
1220 META_Object(osgDB, MapIteratorObject);
1221
1222 BaseSerializer::Type getKeyType() const { return _keyType; }
1223 unsigned int getKeySize() const { return _keySize; }
1224
1225 BaseSerializer::Type getElementType() const { return _elementType; }
1226 unsigned int getElementSize() const { return _elementSize; }
1227
1228 virtual bool advance() { return false; }
1229 virtual bool valid() const { return false; }
1230 virtual const void* getKey() const { return 0; }
1231 virtual void* getElement() const { return 0; }
1232 virtual void setElement(void* /*ptr*/) const {}
1233
1234protected:
1235 BaseSerializer::Type _keyType;
1236 unsigned int _keySize;
1237
1238 BaseSerializer::Type _elementType;
1239 unsigned int _elementSize;
1240};
1241
1242class MapBaseSerializer : public BaseSerializer
1243{
1244public:
1245
1246 MapBaseSerializer(BaseSerializer::Type keyType, unsigned int keySize, BaseSerializer::Type elementType, unsigned int elementSize):
1247 BaseSerializer(READ_WRITE_PROPERTY|GET_SET_PROPERTY),
1248 _keyType(keyType), _keySize(keySize),
1249 _elementType(elementType),_elementSize(elementSize) {}
1250
1251 Type getKeyType() const { return _keyType; }
1252 unsigned int getKeySize() const { return _keySize; }
1253
1254 Type getElementType() const { return _elementType; }
1255 unsigned int getElementSize() const { return _elementSize; }
1256
1257 virtual void clear(osg::Object& /*obj*/) const {}
1258 virtual void setElement(osg::Object& /*obj*/, void* /*ptrKey*/, void* /*ptrValue*/) const {}
1259 virtual void* getElement(osg::Object& /*obj*/, void* /*ptrKey*/) const { return 0; }
1260 virtual const void* getElement(const osg::Object& /*obj*/, void* /*ptrKey*/) const { return 0; }
1261 virtual unsigned int size(const osg::Object& /*obj*/) const { return 0; }
1262
1263 virtual MapIteratorObject* createIterator(osg::Object& /*obj*/) const { return 0; }
1264 virtual MapIteratorObject* createReverseIterator(osg::Object& /*obj*/) const { return 0; }
1265
1266protected:
1267 Type _keyType;
1268 unsigned int _keySize;
1269
1270 Type _elementType;
1271 unsigned int _elementSize;
1272};
1273
1274
1275template<typename C, typename P>
1276class MapSerializer : public MapBaseSerializer
1277{
1278public:
1279 typedef typename P::value_type ValueType;
1280 typedef typename P::key_type KeyType;
1281 typedef typename P::mapped_type ElementType;
1282 typedef typename P::iterator Iterator;
1283 typedef typename P::reverse_iterator ReverseIterator;
1284 typedef typename P::const_iterator ConstIterator;
1285 typedef P& (C::*Getter)();
1286 typedef const P& (C::*ConstGetter)() const;
1287 typedef void (C::*Setter)( const P& );
1288
1289 MapSerializer( const char* name, ConstGetter cgf, Getter gf, Setter sf, BaseSerializer::Type keyType, BaseSerializer::Type elementType):
1290 MapBaseSerializer(keyType, sizeof(KeyType), elementType, sizeof(ElementType)),
1291 _name(name),
1292 _constgetter(cgf), _getter(gf), _setter(sf) {}
1293
1294 virtual const std::string& getName() const { return _name; }
1295
1296 virtual void clear(osg::Object& obj) const
1297 {
1298 C& object = OBJECT_CAST<C&>(obj);
1299 P& map = (object.*_getter)();
1300 map.clear();
1301 }
1302
1303 virtual void setElement(osg::Object& obj, void* ptrKey, void* ptrValue) const
1304 {
1305 C& object = OBJECT_CAST<C&>(obj);
1306 P& map = (object.*_getter)();
1307 map[*reinterpret_cast<KeyType*>(ptrKey)] = *reinterpret_cast<ElementType*>(ptrValue);
1308 }
1309
1310 virtual void* getElement(osg::Object& obj, void* ptrKey) const
1311 {
1312 C& object = OBJECT_CAST<C&>(obj);
1313 P& map = (object.*_getter)();
1314 return &(map[*reinterpret_cast<KeyType*>(ptrKey)]);
1315 }
1316
1317 virtual const void* getElement(const osg::Object& obj, void* ptrKey) const
1318 {
1319 const C& object = OBJECT_CAST<const C&>(obj);
1320 const P& map = (object.*_constgetter)();
1321 ConstIterator itr = map.find(*reinterpret_cast<KeyType*>(ptrKey));
1322 if (itr==map.end()) return 0;
1323 else return &(itr->second);
1324 }
1325
1326 virtual unsigned int size(const osg::Object& obj) const
1327 {
1328 const C& object = OBJECT_CAST<const C&>(obj);
1329 const P& map = (object.*_constgetter)();
1330 return map.size();
1331 }
1332
1333 struct MapIterator : public MapIteratorObject
1334 {
1335 MapIterator(BaseSerializer::Type keyType, unsigned int keySize, BaseSerializer::Type elementType, unsigned int elementSize,
1336 Iterator itr, Iterator endItr):
1337 MapIteratorObject(keyType, keySize, elementType, elementSize),
1338 _itr(itr),_endItr(endItr) {}
1339
1340 Iterator _itr;
1341 Iterator _endItr;
1342
1343 virtual bool advance() { if (valid()) ++_itr; return valid(); }
1344 virtual bool valid() const { return _itr!=_endItr; }
1345 virtual const void* getKey() const { return valid() ? &(_itr->first) : 0; }
1346 virtual void* getElement() const { return valid() ? &(_itr->second) : 0; }
1347 virtual void setElement(void* ptr) const { if (valid()) _itr->second = *reinterpret_cast<ElementType*>(ptr); }
1348 };
1349
1350 struct ReverseMapIterator : public MapIteratorObject
1351 {
1352 ReverseMapIterator(BaseSerializer::Type keyType, unsigned int keySize, BaseSerializer::Type elementType, unsigned int elementSize,
1353 ReverseIterator itr, ReverseIterator endItr):
1354 MapIteratorObject(keyType, keySize, elementType, elementSize),
1355 _itr(itr),_endItr(endItr) {}
1356
1357 ReverseIterator _itr;
1358 ReverseIterator _endItr;
1359
1360 virtual bool advance() { if (valid()) ++_itr; return valid(); }
1361 virtual bool valid() const { return _itr!=_endItr; }
1362 virtual const void* getKey() const { return valid() ? &(_itr->first) : 0; }
1363 virtual void* getElement() const { return valid() ? &(_itr->second) : 0; }
1364 virtual void setElement(void* ptr) const { if (valid()) _itr->second = *reinterpret_cast<ElementType*>(ptr); }
1365 };
1366
1367 virtual MapIteratorObject* createIterator(osg::Object& obj) const
1368 {
1369 C& object = OBJECT_CAST<C&>(obj);
1370 P& map = (object.*_getter)();
1371 return new MapIterator(_keyType, _keySize, _elementType, _elementSize, map.begin(), map.end());
1372 }
1373
1374 virtual MapIteratorObject* createReverseIterator(osg::Object& obj) const
1375 {
1376 C& object = OBJECT_CAST<C&>(obj);
1377 P& map = (object.*_getter)();
1378 return new ReverseMapIterator(_keyType, _keySize, _elementType, _elementSize, map.rbegin(), map.rend());
1379 }
1380
1381 virtual bool read( InputStream& is, osg::Object& obj )
1382 {
1383 C& object = OBJECT_CAST<C&>(obj);
1384 unsigned int size = 0;
1385 P map;
1386 if ( is.isBinary() )
1387 {
1388 is >> size;
1389 for ( unsigned int i=0; i<size; ++i )
1390 {
1391 KeyType key;
1392 ElementType value;
1393 is >> key >> value;
1394 map[key] = value;
1395 }
1396 (object.*_setter)( map );
1397 }
1398 else if ( is.matchString(_name) )
1399 {
1400 is >> size;
1401 if ( size>0 )
1402 {
1403 is >> is.BEGIN_BRACKET;
1404 for ( unsigned int i=0; i<size; ++i )
1405 {
1406 KeyType key;
1407 ElementType value;
1408 is >> key >> value;
1409 map[key] = value;
1410 }
1411 is >> is.END_BRACKET;
1412 }
1413 (object.*_setter)( map );
1414 }
1415 return true;
1416 }
1417
1418 virtual bool write( OutputStream& os, const osg::Object& obj )
1419 {
1420 const C& object = OBJECT_CAST<const C&>(obj);
1421 const P& map = (object.*_constgetter)();
1422 unsigned int size = (unsigned int)map.size();
1423 if ( os.isBinary() )
1424 {
1425 os << size;
1426 for ( ConstIterator itr=map.begin();
1427 itr!=map.end(); ++itr )
1428 {
1429 os << itr->first << itr->second;
1430 }
1431 }
1432 else if ( size>0 )
1433 {
1434 os << os.PROPERTY((_name).c_str()) << size << os.BEGIN_BRACKET << std::endl;
1435 for ( ConstIterator itr=map.begin(); itr!=map.end(); ++itr )
1436 {
1437 os << itr->first << itr->second; os << std::endl;
1438 }
1439 os << os.END_BRACKET << std::endl;
1440 }
1441 return true;
1442 }
1443
1444public:
1445 std::string _name;
1446 ConstGetter _constgetter;
1447 Getter _getter;
1448 Setter _setter;
1449};
1450
1451template<typename C, typename P=unsigned int>
1452class BitFlagsSerializer : public osgDB::TemplateSerializer<P>
1453{
1454public:
1455 typedef TemplateSerializer<P> ParentType;
1456 typedef P (C::*Getter)() const;
1457 typedef void (C::*Setter)( P );
1458
1459 BitFlagsSerializer( const char* name, P def, Getter gf, Setter sf )
1460 : ParentType(name, def), _getter(gf), _setter(sf) {}
1461
1462 void add( const char* str, P value )
1463 {
1464 _lookup.add(str, static_cast<osgDB::IntLookup::Value>(value));
1465 }
1466
1467 P getValue( const char* str )
1468 { return static_cast<P>(_lookup.getValue(str)); }
1469
1470 const std::string& getString( P value )
1471 { return _lookup.getString(static_cast<osgDB::IntLookup::Value>(value)); }
1472
1473 virtual bool read( osgDB::InputStream& is, osg::Object& obj )
1474 {
1475 C& object = OBJECT_CAST<C&>(obj);
1476 if ( is.isBinary() )
1477 {
1478 if (is.getFileVersion()<123)
1479 {
1480 bool ok = false; is >> ok; //code from user serialized ensuring backwards-compatibility
1481 if ( !ok ) return true;
1482 }
1483
1484 P mask;
1485 is >> mask;
1486 (object.*_setter)( mask );
1487 }
1488 else
1489 {
1490 if ( !is.matchString(ParentType::_name) ) //code from user serialized ensuring backwards-compatibility
1491 return true;
1492 P mask=P();
1493 std::string maskSetString;
1494 is >> maskSetString;
1495 osgDB::StringList maskList;
1496 osgDB::split( maskSetString, maskList, '|' );
1497 for ( unsigned int i=0; i<maskList.size(); ++i )
1498 mask |= _lookup.getValue( maskList[i].c_str());
1499 (object.*_setter)( mask );
1500 }
1501 return true;
1502 }
1503
1504 virtual bool write( osgDB::OutputStream& os, const osg::Object& obj )
1505 {
1506 const C& object = OBJECT_CAST<const C&>(obj);
1507 const P mask = (object.*_getter)();
1508 bool ok = ParentType::_defaultValue!=static_cast<P>(mask);
1509 if ( os.isBinary() )
1510 {
1511 if (os.getFileVersion()<123)
1512 {
1513 os << ok;
1514 if ( !ok )
1515 return true;
1516 }
1517 os << (int)mask; //just write int value in binary case
1518 }
1519 else
1520 {
1521 if ( !ok )
1522 return true;
1523 os << os.PROPERTY(ParentType::_name.c_str());
1524
1525 std::string maskString;
1526 const osgDB::IntLookup::ValueToString& v2sm = _lookup.getValueToString();
1527 for( osgDB::IntLookup::ValueToString::const_iterator itr = v2sm.begin() ; itr != v2sm.end() ; itr++)
1528 if( (mask & itr->first) != 0 )
1529 maskString += std::string(itr->second + "|");
1530
1531 if ( !maskString.size() )
1532 maskString = std::string("NONE|");
1533 maskString.erase(maskString.size()-1,1);
1534 os << maskString << std::endl; //remove last "|"
1535 }
1536 return true;
1537 }
1538
1539public:
1540 Getter _getter;
1541 Setter _setter;
1542
1543protected:
1544 osgDB::IntLookup _lookup;
1545};
1546
1547// ADDING MANIPULATORS
1548#define ADD_SERIALIZER(S) \
1549 wrapper->addSerializer( (S) )
1550
1551#define ADD_USER_SERIALIZER(PROP) \
1552 wrapper->addSerializer( new osgDB::UserSerializer<MyClass>( \
1553 #PROP, &check##PROP, &read##PROP, &write##PROP), osgDB::BaseSerializer::RW_USER )
1554
1555#define ADD_BOOL_SERIALIZER(PROP, DEF) \
1556 wrapper->addSerializer( new osgDB::PropByValSerializer< MyClass, bool >( \
1557 #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_BOOL )
1558
1559#define ADD_CHAR_SERIALIZER(PROP, DEF) \
1560 wrapper->addSerializer( new osgDB::PropByValSerializer< MyClass, char >( \
1561 #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_CHAR )
1562
1563#define ADD_UCHAR_SERIALIZER(PROP, DEF) \
1564 wrapper->addSerializer( new osgDB::PropByValSerializer< MyClass, unsigned char >( \
1565 #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_UCHAR )
1566
1567#define ADD_SHORT_SERIALIZER(PROP, DEF) \
1568 wrapper->addSerializer( new osgDB::PropByValSerializer< MyClass, short >( \
1569 #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_SHORT )
1570
1571#define ADD_USHORT_SERIALIZER(PROP, DEF) \
1572 wrapper->addSerializer( new osgDB::PropByValSerializer< MyClass, unsigned short >( \
1573 #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_USHORT )
1574
1575#define ADD_HEXSHORT_SERIALIZER(PROP, DEF) \
1576 wrapper->addSerializer( new osgDB::PropByValSerializer< MyClass, unsigned short >( \
1577 #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP, true), osgDB::BaseSerializer::RW_USHORT )
1578
1579#define ADD_INT_SERIALIZER(PROP, DEF) \
1580 wrapper->addSerializer( new osgDB::PropByValSerializer< MyClass, int >( \
1581 #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_INT )
1582
1583#define ADD_INT_SERIALIZER_NO_SET(PROP, DEF) \
1584 wrapper->addSerializer( new osgDB::PropByValSerializer< MyClass, int >( \
1585 #PROP, DEF, &MyClass::get##PROP, 0), osgDB::BaseSerializer::RW_INT )
1586
1587#define ADD_UINT_SERIALIZER(PROP, DEF) \
1588 wrapper->addSerializer( new osgDB::PropByValSerializer< MyClass, unsigned int >( \
1589 #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_UINT )
1590
1591#define ADD_UINT_SERIALIZER_NO_SET(PROP, DEF) \
1592 wrapper->addSerializer( new osgDB::PropByValSerializer< MyClass, unsigned int >( \
1593 #PROP, DEF, &MyClass::get##PROP, 0), osgDB::BaseSerializer::RW_UINT )
1594
1595#define ADD_GLINT_SERIALIZER(PROP, DEF) \
1596 wrapper->addSerializer( new osgDB::PropByValSerializer< MyClass, GLint >( \
1597 #PROP, ((int)(DEF)), &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_INT )
1598
1599#define ADD_HEXINT_SERIALIZER(PROP, DEF) \
1600 wrapper->addSerializer( new osgDB::PropByValSerializer< MyClass, unsigned int >( \
1601 #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP, true), osgDB::BaseSerializer::RW_UINT )
1602
1603#define ADD_FLOAT_SERIALIZER(PROP, DEF) \
1604 wrapper->addSerializer( new osgDB::PropByValSerializer< MyClass, float >( \
1605 #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_FLOAT )
1606
1607#define ADD_DOUBLE_SERIALIZER(PROP, DEF) \
1608 wrapper->addSerializer( new osgDB::PropByValSerializer< MyClass, double >( \
1609 #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_DOUBLE )
1610
1611#define ADD_REF_BOOL_SERIALIZER(PROP, DEF) \
1612 wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, bool >( \
1613 #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_BOOL )
1614
1615#define ADD_REF_CHAR_SERIALIZER(PROP, DEF) \
1616 wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, char >( \
1617 #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_CHAR )
1618
1619#define ADD_REF_UCHAR_SERIALIZER(PROP, DEF) \
1620 wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, unsigned char >( \
1621 #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_UCHAR )
1622
1623#define ADD_REF_SHORT_SERIALIZER(PROP, DEF) \
1624 wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, short >( \
1625 #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_SHORT )
1626
1627#define ADD_REF_USHORT_SERIALIZER(PROP, DEF) \
1628 wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, unsigned short >( \
1629 #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_USHORT )
1630
1631#define ADD_REF_HEXSHORT_SERIALIZER(PROP, DEF) \
1632 wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, unsigned short >( \
1633 #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP, true), osgDB::BaseSerializer::RW_USHORT )
1634
1635#define ADD_REF_INT_SERIALIZER(PROP, DEF) \
1636 wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, int >( \
1637 #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_INT )
1638
1639#define ADD_REF_UINT_SERIALIZER(PROP, DEF) \
1640 wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, unsigned int >( \
1641 #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_UINT )
1642
1643#define ADD_REF_GLINT_SERIALIZER(PROP, DEF) \
1644 wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, GLint >( \
1645 #PROP, ((int)(DEF)), &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_INT )
1646
1647#define ADD_REF_HEXINT_SERIALIZER(PROP, DEF) \
1648 wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, unsigned int >( \
1649 #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP, true), osgDB::BaseSerializer::RW_UINT )
1650
1651#define ADD_REF_FLOAT_SERIALIZER(PROP, DEF) \
1652 wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, float >( \
1653 #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_FLOAT )
1654
1655#define ADD_REF_DOUBLE_SERIALIZER(PROP, DEF) \
1656 wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, double >( \
1657 #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_DOUBLE )
1658
1659
1660#define ADD_VEC2B_SERIALIZER(PROP, DEF) \
1661 wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::Vec2b >( \
1662 #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_VEC2B )
1663
1664#define ADD_VEC2UB_SERIALIZER(PROP, DEF) \
1665 wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::Vec2ub >( \
1666 #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_VEC2UB )
1667
1668#define ADD_VEC2S_SERIALIZER(PROP, DEF) \
1669 wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::Vec2s >( \
1670 #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_VEC2S )
1671
1672#define ADD_VEC2US_SERIALIZER(PROP, DEF) \
1673 wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::Vec2us >( \
1674 #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_VEC2US )
1675
1676#define ADD_VEC2I_SERIALIZER(PROP, DEF) \
1677 wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::Vec2i >( \
1678 #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_VEC2I )
1679
1680#define ADD_VEC2UI_SERIALIZER(PROP, DEF) \
1681 wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::Vec2ui >( \
1682 #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_VEC2UI )
1683
1684#define ADD_VEC2F_SERIALIZER(PROP, DEF) \
1685 wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::Vec2f >( \
1686 #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_VEC2F )
1687
1688#define ADD_VEC2D_SERIALIZER(PROP, DEF) \
1689 wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::Vec2d >( \
1690 #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_VEC2D )
1691
1692#define ADD_VEC2_SERIALIZER(PROP, DEF) ADD_VEC2F_SERIALIZER(PROP, DEF)
1693
1694
1695#define ADD_VEC3B_SERIALIZER(PROP, DEF) \
1696 wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::Vec3b >( \
1697 #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_VEC3B )
1698
1699#define ADD_VEC3UB_SERIALIZER(PROP, DEF) \
1700 wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::Vec3ub >( \
1701 #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_VEC3UB )
1702
1703#define ADD_VEC3S_SERIALIZER(PROP, DEF) \
1704 wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::Vec3s >( \
1705 #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_VEC3S )
1706
1707#define ADD_VEC3US_SERIALIZER(PROP, DEF) \
1708 wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::Vec3us >( \
1709 #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_VEC3US )
1710
1711#define ADD_VEC3I_SERIALIZER(PROP, DEF) \
1712 wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::Vec3i >( \
1713 #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_VEC3I )
1714
1715#define ADD_VEC3UI_SERIALIZER(PROP, DEF) \
1716 wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::Vec3ui >( \
1717 #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_VEC3UI )
1718
1719#define ADD_VEC3F_SERIALIZER(PROP, DEF) \
1720 wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::Vec3f >( \
1721 #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_VEC3F )
1722
1723#define ADD_VEC3D_SERIALIZER(PROP, DEF) \
1724 wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::Vec3d >( \
1725 #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_VEC3D )
1726
1727#define ADD_VEC3_SERIALIZER(PROP, DEF) ADD_VEC3F_SERIALIZER(PROP, DEF)
1728
1729#define ADD_VEC4B_SERIALIZER(PROP, DEF) \
1730 wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::Vec4b >( \
1731 #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_VEC4B )
1732
1733#define ADD_VEC4UB_SERIALIZER(PROP, DEF) \
1734 wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::Vec4ub >( \
1735 #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_VEC4UB )
1736
1737#define ADD_VEC4S_SERIALIZER(PROP, DEF) \
1738 wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::Vec4s >( \
1739 #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_VEC4S )
1740
1741#define ADD_VEC4US_SERIALIZER(PROP, DEF) \
1742 wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::Vec4us >( \
1743 #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_VEC4US )
1744
1745#define ADD_VEC4I_SERIALIZER(PROP, DEF) \
1746 wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::Vec4i >( \
1747 #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_VEC4I )
1748
1749#define ADD_VEC4UI_SERIALIZER(PROP, DEF) \
1750 wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::Vec4ui >( \
1751 #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_VEC4UI )
1752
1753#define ADD_VEC4F_SERIALIZER(PROP, DEF) \
1754 wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::Vec4f >( \
1755 #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_VEC4F )
1756
1757#define ADD_VEC4D_SERIALIZER(PROP, DEF) \
1758 wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::Vec4d >( \
1759 #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_VEC4D )
1760
1761#define ADD_VEC4_SERIALIZER(PROP, DEF) ADD_VEC4F_SERIALIZER(PROP, DEF)
1762
1763#define ADD_QUAT_SERIALIZER(PROP, DEF) \
1764 wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::Quat >( \
1765 #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_QUAT )
1766
1767#define ADD_PLANE_SERIALIZER(PROP, DEF) \
1768 wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::Plane >( \
1769 #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_PLANE )
1770
1771#define ADD_MATRIXF_SERIALIZER(PROP, DEF) \
1772 wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::Matrixf >( \
1773 #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_MATRIXF )
1774
1775#define ADD_MATRIXD_SERIALIZER(PROP, DEF) \
1776 wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::Matrixd >( \
1777 #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_MATRIXD )
1778
1779#define ADD_MATRIX_SERIALIZER(PROP, DEF) \
1780 wrapper->addSerializer( new osgDB::MatrixSerializer< MyClass >( \
1781 #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_MATRIX )
1782
1783
1784#define ADD_BOUNDINGBOXF_SERIALIZER(PROP, DEF) \
1785 wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::BoundingBoxf >( \
1786 #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_BOUNDINGBOXF )
1787
1788#define ADD_BOUNDINGBOXD_SERIALIZER(PROP, DEF) \
1789 wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::BoundingBoxd >( \
1790 #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_BOUNDINGBOXD )
1791
1792#define ADD_BOUNDINGSPHEREF_SERIALIZER(PROP, DEF) \
1793 wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::BoundingSpheref >( \
1794 #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_BOUNDINGSPHEREF )
1795
1796#define ADD_BOUNDINGSPHERED_SERIALIZER(PROP, DEF) \
1797 wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::BoundingSphered >( \
1798 #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_BOUNDINGSPHERED )
1799
1800
1801#define ADD_GLENUM_SERIALIZER(PROP, TYPE, DEF) \
1802 wrapper->addSerializer( new osgDB::GLenumSerializer< MyClass, TYPE >( \
1803 #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_GLENUM )
1804
1805#define ADD_GLENUM_SERIALIZER_NO_SET(PROP, TYPE, DEF) \
1806 wrapper->addSerializer( new osgDB::GLenumSerializer< MyClass, TYPE >( \
1807 #PROP, DEF, &MyClass::get##PROP, 0), osgDB::BaseSerializer::RW_GLENUM )
1808
1809#define ADD_STRING_SERIALIZER(PROP, DEF) \
1810 wrapper->addSerializer( new osgDB::StringSerializer< MyClass >( \
1811 #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_STRING )
1812
1813#define ADD_OBJECT_SERIALIZER(PROP, TYPE, DEF) \
1814 wrapper->addSerializer( new osgDB::ObjectSerializer< MyClass, TYPE >( \
1815 #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_OBJECT )
1816
1817#define ADD_OBJECT_SERIALIZER_NO_SET(PROP, TYPE, DEF) \
1818 wrapper->addSerializer( new osgDB::ObjectSerializer< MyClass, TYPE >( \
1819 #PROP, DEF, &MyClass::get##PROP, 0), osgDB::BaseSerializer::RW_OBJECT )
1820
1821#define ADD_IMAGE_SERIALIZER(PROP, TYPE, DEF) \
1822 wrapper->addSerializer( new osgDB::ImageSerializer< MyClass, TYPE >( \
1823 #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_IMAGE )
1824
1825#define ADD_LIST_SERIALIZER(PROP, TYPE) \
1826 wrapper->addSerializer( new osgDB::ListSerializer< MyClass, TYPE >( \
1827 #PROP, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_LIST )
1828
1829
1830#define ADD_VECTOR_SERIALIZER(PROP, TYPE, ELEMENTTYPE, NUMELEMENTSONROW) \
1831 wrapper->addSerializer( new osgDB::VectorSerializer< MyClass, TYPE >( \
1832 #PROP, &MyClass::get##PROP, &MyClass::get##PROP, &MyClass::set##PROP, ELEMENTTYPE, NUMELEMENTSONROW), osgDB::BaseSerializer::RW_VECTOR )
1833
1834#define ADD_ISAVECTOR_SERIALIZER(PROP, ELEMENTTYPE, NUMELEMENTSONROW) \
1835 wrapper->addSerializer( new osgDB::IsAVectorSerializer< MyClass >( #PROP, ELEMENTTYPE, NUMELEMENTSONROW), osgDB::BaseSerializer::RW_VECTOR )
1836
1837#define BEGIN_ENUM_SERIALIZER(PROP, DEF) \
1838 { typedef osgDB::EnumSerializer<MyClass, MyClass::PROP, void> MySerializer; \
1839 osg::ref_ptr<MySerializer> serializer = new MySerializer( \
1840 #PROP, MyClass::DEF, &MyClass::get##PROP, &MyClass::set##PROP)
1841
1842#define BEGIN_ENUM_SERIALIZER2(PROP, TYPE, DEF) \
1843 { typedef osgDB::EnumSerializer<MyClass, TYPE, void> MySerializer; \
1844 osg::ref_ptr<MySerializer> serializer = new MySerializer( \
1845 #PROP, MyClass::DEF, &MyClass::get##PROP, &MyClass::set##PROP)
1846
1847#define BEGIN_ENUM_SERIALIZER3(PROP, DEF) \
1848 { typedef osgDB::EnumSerializer<MyClass, MyClass::PROP, bool> MySerializer; \
1849 osg::ref_ptr<MySerializer> serializer = new MySerializer( \
1850 #PROP, MyClass::DEF, &MyClass::get##PROP, &MyClass::set##PROP)
1851
1852#define BEGIN_ENUM_SERIALIZER4(PROPERTIES_CLASS, PROP, DEF) \
1853 { typedef osgDB::EnumSerializer<MyClass, PROPERTIES_CLASS::PROP, void> MySerializer; \
1854 osg::ref_ptr<MySerializer> serializer = new MySerializer( \
1855 #PROP, PROPERTIES_CLASS::DEF, &MyClass::get##PROP, &MyClass::set##PROP)
1856
1857#define BEGIN_ENUM_SERIALIZER_NO_SET(PROP, DEF) \
1858 { typedef osgDB::EnumSerializer<MyClass, MyClass::PROP, void> MySerializer; \
1859 osg::ref_ptr<MySerializer> serializer = new MySerializer( \
1860 #PROP, MyClass::DEF, &MyClass::get##PROP, 0)
1861
1862#define ADD_ENUM_VALUE(VALUE) \
1863 serializer->add(#VALUE, MyClass::VALUE)
1864
1865#define ADD_ENUM_CLASS_VALUE(CLASS, VALUE) \
1866 serializer->add(#VALUE, CLASS::VALUE)
1867
1868#define END_ENUM_SERIALIZER() \
1869 wrapper->addSerializer(serializer.get(), osgDB::BaseSerializer::RW_ENUM); }
1870
1871/** defaults to uint bitfield type.*/
1872#define BEGIN_BITFLAGS_SERIALIZER(PROP, DEF) \
1873 { typedef osgDB::BitFlagsSerializer<MyClass> MySerializer; \
1874 osg::ref_ptr<MySerializer> serializer = new MySerializer( \
1875 #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP)
1876
1877#define BEGIN_UINT_BITFLAGS_SERIALIZER(PROP, DEF) \
1878 { typedef osgDB::BitFlagsSerializer<MyClass, unsigned int> MySerializer; \
1879 osg::ref_ptr<MySerializer> serializer = new MySerializer( \
1880 #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP)
1881
1882#define BEGIN_INT_BITFLAGS_SERIALIZER(PROP, DEF) \
1883 { typedef osgDB::BitFlagsSerializer<MyClass, int> MySerializer; \
1884 osg::ref_ptr<MySerializer> serializer = new MySerializer( \
1885 #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP)
1886
1887#define ADD_BITFLAG_VALUE(VALUE_NAME, VALUE) \
1888 serializer->add(#VALUE_NAME, VALUE)
1889
1890#define END_BITFLAGS_SERIALIZER() \
1891 wrapper->addSerializer(serializer.get(), osgDB::BaseSerializer::RW_INT); }
1892
1893// VERSION CONTROL OPERATORS
1894#define UPDATE_TO_VERSION(VER) \
1895 wrapper->setUpdatedVersion( (VER) );
1896
1897#define UPDATE_TO_VERSION_SCOPED(VER) \
1898 osgDB::UpdateWrapperVersionProxy uwvp(wrapper, (VER));
1899
1900#define ADDED_ASSOCIATE(STR) \
1901 wrapper->markAssociateAsAdded( STR );
1902
1903#define REMOVED_ASSOCIATE(STR) \
1904 wrapper->markAssociateAsRemoved( STR );
1905
1906#define REMOVE_SERIALIZER(PROP) \
1907 wrapper->markSerializerAsRemoved( #PROP );
1908
1909#define ADD_MAP_SERIALIZER(PROP, TYPE, KEYTYPE, ELEMENTTYPE) \
1910 wrapper->addSerializer( new osgDB::MapSerializer< MyClass, TYPE >( \
1911 #PROP, &MyClass::get##PROP, &MyClass::get##PROP, &MyClass::set##PROP, KEYTYPE, ELEMENTTYPE), osgDB::BaseSerializer::RW_MAP )
1912
1913#define ADD_METHOD_OBJECT( METHODNAME, METHODOBJECTCLASS ) wrapper->addMethodObject(METHODNAME, new METHODOBJECTCLASS());
1914
1915#define ADD_METHOD(METHODNAME) \
1916 { \
1917 struct MethodCaller : public osgDB::MethodObject \
1918 { \
1919 virtual bool run(void* objectPtr, osg::Parameters&, osg::Parameters&) const \
1920 { \
1921 MyClass* obj = reinterpret_cast<MyClass*>(objectPtr); \
1922 obj->METHODNAME(); \
1923 return true; \
1924 } \
1925 }; \
1926 wrapper->addMethodObject(#METHODNAME, new MethodCaller()); \
1927 }
1928
1929
1930#define SET_USAGE(VALUE) wrapper->getLastSerializer()->setUsage(VALUE)
1931
1932}
1933
1934#endif