1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2010 Robert Osfield
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.
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.
13// Written by Wang Rui, (C) 2010
15#ifndef OSGDB__SERIALIZER
16#define OSGDB__SERIALIZER
21#include <osgDB/InputStream>
22#include <osgDB/OutputStream>
31typedef std::vector<std::string> StringList;
32extern OSGDB_EXPORT void split( const std::string& src, StringList& list, char separator=' ' );
36 #define OBJECT_CAST static_cast
43 typedef std::map<std::string, Value> StringToValue;
44 typedef std::map<Value, std::string> ValueToString;
47 unsigned int size() const { return static_cast<unsigned int>(_stringToValue.size()); }
49 void add( const char* str, Value value )
51 if ( _valueToString.find(value)!=_valueToString.end() )
53 osg::notify(osg::INFO) << "Duplicate enum value " << value
54 << " with old string: " << _valueToString[value]
55 << " and new string: " << str << std::endl;
57 _valueToString[value] = str;
58 _stringToValue[str] = value;
61 void add2(const char* str, const char* newStr, Value value) {
62 if (_valueToString.find(value) != _valueToString.end())
64 osg::notify(osg::INFO) << "Duplicate enum value " << value
65 << " with old string: " << _valueToString[value]
66 << " and new strings: " << str << " and " << newStr << std::endl;
68 _valueToString[value] = newStr;
69 _stringToValue[newStr] = value;
70 _stringToValue[str] = value;
73 Value getValue( const char* str )
75 StringToValue::iterator itr = _stringToValue.find(str);
76 if ( itr==_stringToValue.end() )
79 std::stringstream stream;
80 stream << str; stream >> value;
81 _stringToValue[str] = value;
87 const std::string& getString( Value value )
89 ValueToString::iterator itr = _valueToString.find(value);
90 if ( itr==_valueToString.end() )
93 std::stringstream stream;
94 stream << value; stream >> str;
95 _valueToString[value] = str;
96 return _valueToString[value];
101 StringToValue& getStringToValue() { return _stringToValue; }
102 const StringToValue& getStringToValue() const { return _stringToValue; }
104 ValueToString& getValueToString() { return _valueToString; }
105 const ValueToString& getValueToString() const { return _valueToString; }
108 StringToValue _stringToValue;
109 ValueToString _valueToString;
112class UserLookupTableProxy
115 typedef void (*AddValueFunc)( IntLookup* lookup );
116 UserLookupTableProxy( AddValueFunc func ) { if ( func ) (*func)(&_lookup); }
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() }
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()); } \
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); } \
140class BaseSerializer : public osg::Referenced
142 friend class ObjectWrapper;
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,
160 READ_WRITE_PROPERTY = 1,
163 GET_SET_PROPERTY = GET_PROPERTY | SET_PROPERTY
167 BaseSerializer(int usage) : _firstVersion(0), _lastVersion(INT_MAX), _usage(usage) {}
169 virtual bool set(osg::Object& /*object*/, void* /*value*/) { return false; }
170 virtual bool get(const osg::Object& /*object*/, void* /*value*/) { return false; }
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;
176 virtual IntLookup* getIntLookup() { return 0; }
178 void setUsage(int usage) { _usage = usage; }
179 int getUsage() const { return _usage; }
181 void setUsage(bool hasGetter, bool hasSetter)
183 setUsage( ((hasGetter && hasSetter) ? BaseSerializer::READ_WRITE_PROPERTY : 0) |
184 ((hasGetter) ? BaseSerializer::GET_PROPERTY : 0) |
185 ((hasSetter) ? BaseSerializer::SET_PROPERTY : 0) );
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; }
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.
200class UserSerializer : public BaseSerializer
203 typedef bool (*Checker)( const C& );
204 typedef bool (*Reader)( InputStream&, C& );
205 typedef bool (*Writer)( OutputStream&, const C& );
207 UserSerializer( const char* name, Checker cf, Reader rf, Writer wf )
208 : BaseSerializer(READ_WRITE_PROPERTY), _name(name), _checker(cf), _reader(rf), _writer(wf) {}
210 virtual bool read( InputStream& is, osg::Object& obj )
212 C& object = OBJECT_CAST<C&>(obj);
215 bool ok = false; is >> ok;
216 if ( !ok ) return true;
220 if ( !is.matchString(_name) )
223 return (*_reader)(is, object);
226 virtual bool write( OutputStream& os, const osg::Object& obj )
228 const C& object = OBJECT_CAST<const C&>(obj);
229 bool ok = (*_checker)(object);
233 if ( !ok ) return true;
237 if ( !ok ) return true;
238 os << os.PROPERTY(_name.c_str());
240 return (*_writer)(os, object);
243 virtual const std::string& getName() const { return _name; }
255class TemplateSerializer : public BaseSerializer
259 TemplateSerializer( const char* name, P def)
260 : BaseSerializer(READ_WRITE_PROPERTY), _name(name), _defaultValue(def) {}
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; }
271template<typename C, typename P>
272class PropByValSerializer : public TemplateSerializer<P>
275 typedef TemplateSerializer<P> ParentType;
276 typedef P (C::*Getter)() const;
277 typedef void (C::*Setter)( P );
279 PropByValSerializer( const char* name, P def, Getter gf, Setter sf, bool useHex=false ) : ParentType(name, def), _getter(gf), _setter(sf), _useHex(useHex)
281 ParentType::setUsage( _getter!=0, _setter!=0);
284 virtual bool read( InputStream& is, osg::Object& obj )
286 C& object = OBJECT_CAST<C&>(obj);
291 (object.*_setter)( value );
293 else if ( is.matchString(ParentType::_name) )
295 if ( _useHex ) is >> std::hex;
297 if ( _useHex ) is >> std::dec;
298 (object.*_setter)( value );
303 virtual bool write( OutputStream& os, const osg::Object& obj )
305 const C& object = OBJECT_CAST<const C&>(obj);
306 P value = (object.*_getter)();
311 else if ( ParentType::_defaultValue!=value )
313 os << os.PROPERTY((ParentType::_name).c_str());
314 if ( _useHex ) { os << std::hex << std::showbase; }
316 if ( _useHex ) os << std::dec << std::noshowbase;
330template<typename C, typename P>
331class PropByRefSerializer : public TemplateSerializer<P>
334 typedef TemplateSerializer<P> ParentType;
336 typedef CP (C::*Getter)() const;
337 typedef void (C::*Setter)( CP );
339 PropByRefSerializer( const char* name, CP def, Getter gf, Setter sf ) : ParentType(name, def), _getter(gf), _setter(sf)
341 ParentType::setUsage( _getter!=0, _setter!=0);
344 virtual bool read( InputStream& is, osg::Object& obj )
346 C& object = OBJECT_CAST<C&>(obj);
351 (object.*_setter)( value );
353 else if ( is.matchString(ParentType::_name) )
356 (object.*_setter)( value );
361 virtual bool write( OutputStream& os, const osg::Object& obj )
363 const C& object = OBJECT_CAST<const C&>(obj);
364 CP value = (object.*_getter)();
369 else if ( ParentType::_defaultValue!=value )
371 os << os.PROPERTY((ParentType::_name).c_str()) << value << std::endl;
382class MatrixSerializer : public TemplateSerializer<osg::Matrix>
385 typedef TemplateSerializer<osg::Matrix> ParentType;
386 typedef const osg::Matrix& (C::*Getter)() const;
387 typedef void (C::*Setter)( const osg::Matrix& );
389 MatrixSerializer( const char* name, const osg::Matrix& def, Getter gf, Setter sf ) : ParentType(name, def), _getter(gf), _setter(sf)
391 ParentType::setUsage( _getter!=0, _setter!=0);
394 virtual bool read( InputStream& is, osg::Object& obj )
396 C& object = OBJECT_CAST<C&>(obj);
400 readMatrixImplementation( is, value );
401 (object.*_setter)( value );
403 else if ( is.matchString(ParentType::_name) )
405 readMatrixImplementation( is, value );
406 (object.*_setter)( value );
411 virtual bool write( OutputStream& os, const osg::Object& obj )
414 const C& object = OBJECT_CAST<const C&>(obj);
415 const osg::Matrix& value = (object.*_getter)();
420 else if ( ParentType::_defaultValue!=value )
422 os << os.PROPERTY((ParentType::_name).c_str()) << value << std::endl;
428 void readMatrixImplementation( InputStream& is, osg::Matrix& matrix )
433 if ( is.getUseFloatMatrix() )
435 osg::Matrixf realValue; is >> realValue;
440 osg::Matrixd realValue; is >> realValue;
451template<typename C, typename P>
452class GLenumSerializer : public TemplateSerializer<P>
455 typedef TemplateSerializer<P> ParentType;
456 typedef P (C::*Getter)() const;
457 typedef void (C::*Setter)( P );
459 GLenumSerializer( const char* name, P def, Getter gf, Setter sf ) : ParentType(name, def), _getter(gf), _setter(sf)
461 ParentType::setUsage( _getter!=0, _setter!=0);
464 virtual bool read( InputStream& is, osg::Object& obj )
466 C& object = OBJECT_CAST<C&>(obj);
469 GLenum value; is >> value;
470 (object.*_setter)( static_cast<P>(value) );
472 else if ( is.matchString(ParentType::_name) )
474 DEF_GLENUM(value); is >> value;
475 (object.*_setter)( static_cast<P>(value.get()) );
480 virtual bool write( OutputStream& os, const osg::Object& obj )
482 const C& object = OBJECT_CAST<const C&>(obj);
483 const P value = (object.*_getter)();
486 os << static_cast<GLenum>(value);
488 else if ( ParentType::_defaultValue!=value )
490 os << os.PROPERTY((ParentType::_name).c_str()) << GLENUM(value) << std::endl;
501class StringSerializer : public TemplateSerializer<std::string>
504 typedef TemplateSerializer<std::string> ParentType;
505 typedef const std::string& (C::*Getter)() const;
506 typedef void (C::*Setter)( const std::string& );
508 StringSerializer( const char* name, const std::string& def, Getter gf, Setter sf ) : ParentType(name, def), _getter(gf), _setter(sf)
510 ParentType::setUsage( _getter!=0, _setter!=0);
513 virtual bool read( InputStream& is, osg::Object& obj )
515 C& object = OBJECT_CAST<C&>(obj);
520 (object.*_setter)( value );
522 else if ( is.matchString(ParentType::_name) )
524 is.readWrappedString( value );
525 if ( !value.empty() && (_setter!=0) )
526 (object.*_setter)( value );
531 virtual bool write( OutputStream& os, const osg::Object& obj )
533 const C& object = OBJECT_CAST<const C&>(obj);
534 const std::string& value = (object.*_getter)();
539 else if ( ParentType::_defaultValue!=value )
541 os << os.PROPERTY((ParentType::_name).c_str());
542 os.writeWrappedString( value );
553template<typename C, typename P>
554class ObjectSerializer : public BaseSerializer
557 typedef const P* (C::*Getter)() const;
558 typedef void (C::*Setter)( P* );
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)
564 setUsage( _getter!=0, _setter!=0);
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; }
570 virtual const std::string& getName() const { return _name; }
572 virtual bool read( InputStream& is, osg::Object& obj )
574 C& object = OBJECT_CAST<C&>(obj);
575 bool hasObject = false;
581 osg::ref_ptr<P> value = is.readObjectOfType<P>();
582 (object.*_setter)( value.get() );
585 else if ( is.matchString(_name) )
590 is >> is.BEGIN_BRACKET;
591 osg::ref_ptr<P> value = is.readObjectOfType<P>();
592 (object.*_setter)( value.get() );
593 is >> is.END_BRACKET;
599 virtual bool write( OutputStream& os, const osg::Object& obj )
601 const C& object = OBJECT_CAST<const C&>(obj);
602 const P* value = (object.*_getter)();
603 bool hasObject = (value!=NULL);
609 os.writeObject( value );
612 else if ( _defaultValue!=value )
614 os << os.PROPERTY(_name.c_str()) << hasObject;
617 os << os.BEGIN_BRACKET << std::endl;
618 os.writeObject( value );
619 os << os.END_BRACKET;
628 osg::ref_ptr<P> _defaultValue;
633template<typename C, typename P>
634class ImageSerializer : public TemplateSerializer<P*>
637 typedef TemplateSerializer<P*> ParentType;
638 typedef const P* (C::*Getter)() const;
639 typedef void (C::*Setter)( P* );
641 ImageSerializer( const char* name, P* def, Getter gf, Setter sf ):
642 ParentType(name, def), _getter(gf), _setter(sf)
644 ParentType::setUsage( _getter!=0, _setter!=0);
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; }
650 virtual bool read( InputStream& is, osg::Object& obj )
652 C& object = OBJECT_CAST<C&>(obj);
653 bool hasObject = false;
659 osg::ref_ptr<osg::Image> image = is.readImage();
660 P* value = dynamic_cast<P*>( image.get() );
661 (object.*_setter)( value );
664 else if ( is.matchString(ParentType::_name) )
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;
679 virtual bool write( OutputStream& os, const osg::Object& obj )
681 const C& object = OBJECT_CAST<const C&>(obj);
682 const P* value = (object.*_getter)();
683 bool hasObject = (value!=NULL);
687 os.writeImage( value );
689 else if ( ParentType::_defaultValue!=value )
691 os << os.PROPERTY((ParentType::_name).c_str()) << hasObject;
694 os << os.BEGIN_BRACKET << std::endl;
695 os.writeImage( value );
696 os << os.END_BRACKET;
708template<typename C, typename P, typename B>
709class EnumSerializer : public TemplateSerializer<P>
712 typedef TemplateSerializer<P> ParentType;
713 typedef P (C::*Getter)() const;
714 typedef B (C::*Setter)( P );
716 EnumSerializer( const char* name, P def, Getter gf, Setter sf ) : ParentType(name, def), _getter(gf), _setter(sf)
718 ParentType::setUsage( _getter!=0, _setter!=0);
721 virtual IntLookup* getIntLookup() { return &_lookup; }
723 void add( const char* str, P value )
724 { _lookup.add(str, static_cast<IntLookup::Value>(value)); }
726 P getValue( const char* str )
727 { return static_cast<P>(_lookup.getValue(str)); }
729 const std::string& getString( P value )
730 { return _lookup.getString(static_cast<IntLookup::Value>(value)); }
732 virtual bool read( InputStream& is, osg::Object& obj )
734 C& object = OBJECT_CAST<C&>(obj);
735 IntLookup::Value value;
739 (object.*_setter)( static_cast<P>(value) );
741 else if ( is.matchString(ParentType::_name) )
743 std::string str; is >> str;
744 (object.*_setter)( getValue(str.c_str()) );
749 virtual bool write( osgDB::OutputStream& os, const osg::Object& obj )
751 const C& object = OBJECT_CAST<const C&>(obj);
752 const P value = (object.*_getter)();
755 os << (IntLookup::Value)value;
757 else if ( ParentType::_defaultValue!=value )
759 os << os.PROPERTY((ParentType::_name).c_str()) << getString(value) << std::endl;
773template<typename C, typename P>
774class ListSerializer : public BaseSerializer
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& );
782 ListSerializer( const char* name, Getter gf, Setter sf ):
783 BaseSerializer(READ_WRITE_PROPERTY),
784 _name(name), _getter(gf), _setter(sf) {}
786 virtual const std::string& getName() const { return _name; }
788 virtual bool read( InputStream& is, osg::Object& obj )
790 C& object = OBJECT_CAST<C&>(obj);
791 unsigned int size = 0;
796 for ( unsigned int i=0; i<size; ++i )
800 list.push_back( value );
802 if ( size>0 ) (object.*_setter)( list );
804 else if ( is.matchString(_name) )
807 if ( size>0 ) is >> is.BEGIN_BRACKET;
808 for ( unsigned int i=0; i<size; ++i )
812 list.push_back( value );
816 is >> is.END_BRACKET;
817 (object.*_setter)( list );
823 virtual bool write( OutputStream& os, const osg::Object& obj )
825 const C& object = OBJECT_CAST<const C&>(obj);
826 const P& list = (object.*_getter)();
827 unsigned int size = (unsigned int)list.size();
831 for ( ConstIterator itr=list.begin();
832 itr!=list.end(); ++itr )
839 os << os.PROPERTY((_name).c_str()) << size << os.BEGIN_BRACKET << std::endl;
840 for ( ConstIterator itr=list.begin();
841 itr!=list.end(); ++itr )
846 os << os.END_BRACKET << std::endl;
857class VectorBaseSerializer : public BaseSerializer
861 VectorBaseSerializer(BaseSerializer::Type elementType, unsigned int elementSize):
862 BaseSerializer(READ_WRITE_PROPERTY|GET_SET_PROPERTY),
863 _elementType(elementType),_elementSize(elementSize) {}
865 Type getElementType() const { return _elementType; }
866 unsigned int getElementSize() const { return _elementSize; }
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; }
880 unsigned int _elementSize;
884template<typename C, typename P>
885class VectorSerializer : public VectorBaseSerializer
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& );
894 VectorSerializer( const char* name, ConstGetter cgf, Getter gf, Setter sf, BaseSerializer::Type elementType, unsigned int numElementsOnRow):
895 VectorBaseSerializer(elementType, sizeof(ValueType)),
897 _constgetter(cgf), _getter(gf), _setter(sf),
898 _numElementsOnRow(numElementsOnRow) {}
900 virtual const std::string& getName() const { return _name; }
902 virtual unsigned int size(const osg::Object& obj) const
904 const C& object = OBJECT_CAST<const C&>(obj);
905 const P& list = (object.*_constgetter)();
906 return static_cast<unsigned int>(list.size());
908 virtual void resize(osg::Object& obj, unsigned int numElements) const
910 C& object = OBJECT_CAST<C&>(obj);
911 P& list = (object.*_getter)();
912 list.resize(numElements);
914 virtual void reserve(osg::Object& obj, unsigned int numElements) const
916 C& object = OBJECT_CAST<C&>(obj);
917 P& list = (object.*_getter)();
918 list.reserve(numElements);
920 virtual void clear(osg::Object& obj) const
922 C& object = OBJECT_CAST<C&>(obj);
923 P& list = (object.*_getter)();
926 virtual void addElement(osg::Object& obj, void* ptr) const
928 C& object = OBJECT_CAST<C&>(obj);
929 P& list = (object.*_getter)();
930 list.push_back(*reinterpret_cast<ValueType*>(ptr));
932 virtual void insertElement(osg::Object& obj, unsigned int index, void* ptr) const
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));
939 virtual void setElement(osg::Object& obj, unsigned int index, void* ptr) const
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);
946 virtual void* getElement(osg::Object& obj, unsigned int index) const
948 C& object = OBJECT_CAST<C&>(obj);
949 P& list = (object.*_getter)();
950 if (index>=list.size()) return 0;
951 else return &list[index];
953 virtual const void* getElement(const osg::Object& obj, unsigned int index) const
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];
961 virtual bool read( InputStream& is, osg::Object& obj )
963 C& object = OBJECT_CAST<C&>(obj);
964 unsigned int size = 0;
970 for ( unsigned int i=0; i<size; ++i )
974 list.push_back( value );
976 if ( size>0 ) (object.*_setter)( list );
978 else if ( is.matchString(_name) )
982 if ( size>0 ) is >> is.BEGIN_BRACKET;
983 for ( unsigned int i=0; i<size; ++i )
987 list.push_back( value );
991 is >> is.END_BRACKET;
992 (object.*_setter)( list );
998 virtual bool write( OutputStream& os, const osg::Object& obj )
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() )
1006 for ( ConstIterator itr=list.begin();
1007 itr!=list.end(); ++itr )
1014 os << os.PROPERTY((_name).c_str()) << size << os.BEGIN_BRACKET << std::endl;
1015 if (_numElementsOnRow==0)
1017 for ( ConstIterator itr=list.begin(); itr!=list.end(); ++itr )
1022 else if (_numElementsOnRow==1)
1024 for ( ConstIterator itr=list.begin(); itr!=list.end(); ++itr )
1026 os << (*itr); os << std::endl;
1031 unsigned int i = _numElementsOnRow-1;
1032 for (ConstIterator itr=list.begin(); itr!=list.end(); ++itr)
1035 if (i==0) { os << std::endl; i = _numElementsOnRow-1; }
1038 if (i!=_numElementsOnRow) os << std::endl;
1040 os << os.END_BRACKET << std::endl;
1047 ConstGetter _constgetter;
1050 unsigned int _numElementsOnRow;
1055class IsAVectorSerializer : public VectorBaseSerializer
1058 typedef typename C::value_type ValueType;
1059 typedef typename C::const_iterator ConstIterator;
1061 IsAVectorSerializer( const char* name, BaseSerializer::Type elementType, unsigned int numElementsOnRow) :
1062 VectorBaseSerializer(elementType, sizeof(ValueType)),
1064 _numElementsOnRow(numElementsOnRow) {}
1066 virtual const std::string& getName() const { return _name; }
1068 virtual unsigned int size(const osg::Object& obj) const
1070 const C& list = OBJECT_CAST<const C&>(obj);
1071 return static_cast<unsigned int>(list.size());
1073 virtual void resize(osg::Object& obj, unsigned int numElements) const
1075 C& list = OBJECT_CAST<C&>(obj);
1076 list.resize(numElements);
1078 virtual void reserve(osg::Object& obj, unsigned int numElements) const
1080 C& list = OBJECT_CAST<C&>(obj);
1081 list.reserve(numElements);
1083 virtual void clear(osg::Object& obj) const
1085 C& list = OBJECT_CAST<C&>(obj);
1088 virtual void addElement(osg::Object& obj, void* ptr) const
1090 C& list = OBJECT_CAST<C&>(obj);
1091 list.push_back(*reinterpret_cast<ValueType*>(ptr));
1093 virtual void insertElement(osg::Object& obj, unsigned int index, void* ptr) const
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));
1099 virtual void setElement(osg::Object& obj, unsigned int index, void* ptr) const
1101 C& list = OBJECT_CAST<C&>(obj);
1102 if (index>=list.size()) list.resize(index+1);
1103 list[index] = *reinterpret_cast<ValueType*>(ptr);
1105 virtual void* getElement(osg::Object& obj, unsigned int index) const
1107 C& list = OBJECT_CAST<C&>(obj);
1108 if (index>=list.size()) return 0;
1109 else return &list[index];
1112 virtual const void* getElement(const osg::Object& obj, unsigned int index) const
1114 const C& list = OBJECT_CAST<const C&>(obj);
1115 if (index>=list.size()) return 0;
1116 else return &list[index];
1119 virtual bool read( InputStream& is, osg::Object& obj )
1121 C& list = OBJECT_CAST<C&>(obj);
1122 unsigned int size = 0;
1123 if ( is.isBinary() )
1127 for ( unsigned int i=0; i<size; ++i )
1131 list.push_back( value );
1134 else if ( is.matchString(_name) )
1138 if ( size>0 ) is >> is.BEGIN_BRACKET;
1139 for ( unsigned int i=0; i<size; ++i )
1143 list.push_back( value );
1147 is >> is.END_BRACKET;
1153 virtual bool write( OutputStream& os, const osg::Object& obj )
1155 const C& list = OBJECT_CAST<const C&>(obj);
1156 unsigned int size = (unsigned int)list.size();
1157 if ( os.isBinary() )
1160 for ( ConstIterator itr=list.begin();
1161 itr!=list.end(); ++itr )
1168 os << os.PROPERTY((_name).c_str()) << size << os.BEGIN_BRACKET << std::endl;
1169 if (_numElementsOnRow==0)
1171 for ( ConstIterator itr=list.begin(); itr!=list.end(); ++itr )
1176 else if (_numElementsOnRow==1)
1178 for ( ConstIterator itr=list.begin(); itr!=list.end(); ++itr )
1180 os << (*itr); os << std::endl;
1185 unsigned int i = _numElementsOnRow-1;
1186 for (ConstIterator itr=list.begin(); itr!=list.end(); ++itr)
1189 if (i==0) { os << std::endl; i = _numElementsOnRow-1; }
1192 if (i!=_numElementsOnRow) os << std::endl;
1194 os << os.END_BRACKET << std::endl;
1201 unsigned int _numElementsOnRow;
1204class MapIteratorObject : public osg::Object
1207 MapIteratorObject():
1208 _keyType(BaseSerializer::RW_UNDEFINED), _keySize(0),
1209 _elementType(BaseSerializer::RW_UNDEFINED),_elementSize(0) {}
1211 MapIteratorObject(BaseSerializer::Type keyType, unsigned int keySize, BaseSerializer::Type elementType, unsigned int elementSize):
1212 _keyType(keyType), _keySize(keySize),
1213 _elementType(elementType),_elementSize(elementSize) {}
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) {}
1220 META_Object(osgDB, MapIteratorObject);
1222 BaseSerializer::Type getKeyType() const { return _keyType; }
1223 unsigned int getKeySize() const { return _keySize; }
1225 BaseSerializer::Type getElementType() const { return _elementType; }
1226 unsigned int getElementSize() const { return _elementSize; }
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 {}
1235 BaseSerializer::Type _keyType;
1236 unsigned int _keySize;
1238 BaseSerializer::Type _elementType;
1239 unsigned int _elementSize;
1242class MapBaseSerializer : public BaseSerializer
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) {}
1251 Type getKeyType() const { return _keyType; }
1252 unsigned int getKeySize() const { return _keySize; }
1254 Type getElementType() const { return _elementType; }
1255 unsigned int getElementSize() const { return _elementSize; }
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; }
1263 virtual MapIteratorObject* createIterator(osg::Object& /*obj*/) const { return 0; }
1264 virtual MapIteratorObject* createReverseIterator(osg::Object& /*obj*/) const { return 0; }
1268 unsigned int _keySize;
1271 unsigned int _elementSize;
1275template<typename C, typename P>
1276class MapSerializer : public MapBaseSerializer
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& );
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)),
1292 _constgetter(cgf), _getter(gf), _setter(sf) {}
1294 virtual const std::string& getName() const { return _name; }
1296 virtual void clear(osg::Object& obj) const
1298 C& object = OBJECT_CAST<C&>(obj);
1299 P& map = (object.*_getter)();
1303 virtual void setElement(osg::Object& obj, void* ptrKey, void* ptrValue) const
1305 C& object = OBJECT_CAST<C&>(obj);
1306 P& map = (object.*_getter)();
1307 map[*reinterpret_cast<KeyType*>(ptrKey)] = *reinterpret_cast<ElementType*>(ptrValue);
1310 virtual void* getElement(osg::Object& obj, void* ptrKey) const
1312 C& object = OBJECT_CAST<C&>(obj);
1313 P& map = (object.*_getter)();
1314 return &(map[*reinterpret_cast<KeyType*>(ptrKey)]);
1317 virtual const void* getElement(const osg::Object& obj, void* ptrKey) const
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);
1326 virtual unsigned int size(const osg::Object& obj) const
1328 const C& object = OBJECT_CAST<const C&>(obj);
1329 const P& map = (object.*_constgetter)();
1333 struct MapIterator : public MapIteratorObject
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) {}
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); }
1350 struct ReverseMapIterator : public MapIteratorObject
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) {}
1357 ReverseIterator _itr;
1358 ReverseIterator _endItr;
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); }
1367 virtual MapIteratorObject* createIterator(osg::Object& obj) const
1369 C& object = OBJECT_CAST<C&>(obj);
1370 P& map = (object.*_getter)();
1371 return new MapIterator(_keyType, _keySize, _elementType, _elementSize, map.begin(), map.end());
1374 virtual MapIteratorObject* createReverseIterator(osg::Object& obj) const
1376 C& object = OBJECT_CAST<C&>(obj);
1377 P& map = (object.*_getter)();
1378 return new ReverseMapIterator(_keyType, _keySize, _elementType, _elementSize, map.rbegin(), map.rend());
1381 virtual bool read( InputStream& is, osg::Object& obj )
1383 C& object = OBJECT_CAST<C&>(obj);
1384 unsigned int size = 0;
1386 if ( is.isBinary() )
1389 for ( unsigned int i=0; i<size; ++i )
1396 (object.*_setter)( map );
1398 else if ( is.matchString(_name) )
1403 is >> is.BEGIN_BRACKET;
1404 for ( unsigned int i=0; i<size; ++i )
1411 is >> is.END_BRACKET;
1413 (object.*_setter)( map );
1418 virtual bool write( OutputStream& os, const osg::Object& obj )
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() )
1426 for ( ConstIterator itr=map.begin();
1427 itr!=map.end(); ++itr )
1429 os << itr->first << itr->second;
1434 os << os.PROPERTY((_name).c_str()) << size << os.BEGIN_BRACKET << std::endl;
1435 for ( ConstIterator itr=map.begin(); itr!=map.end(); ++itr )
1437 os << itr->first << itr->second; os << std::endl;
1439 os << os.END_BRACKET << std::endl;
1446 ConstGetter _constgetter;
1451template<typename C, typename P=unsigned int>
1452class BitFlagsSerializer : public osgDB::TemplateSerializer<P>
1455 typedef TemplateSerializer<P> ParentType;
1456 typedef P (C::*Getter)() const;
1457 typedef void (C::*Setter)( P );
1459 BitFlagsSerializer( const char* name, P def, Getter gf, Setter sf )
1460 : ParentType(name, def), _getter(gf), _setter(sf) {}
1462 void add( const char* str, P value )
1464 _lookup.add(str, static_cast<osgDB::IntLookup::Value>(value));
1467 P getValue( const char* str )
1468 { return static_cast<P>(_lookup.getValue(str)); }
1470 const std::string& getString( P value )
1471 { return _lookup.getString(static_cast<osgDB::IntLookup::Value>(value)); }
1473 virtual bool read( osgDB::InputStream& is, osg::Object& obj )
1475 C& object = OBJECT_CAST<C&>(obj);
1476 if ( is.isBinary() )
1478 if (is.getFileVersion()<123)
1480 bool ok = false; is >> ok; //code from user serialized ensuring backwards-compatibility
1481 if ( !ok ) return true;
1486 (object.*_setter)( mask );
1490 if ( !is.matchString(ParentType::_name) ) //code from user serialized ensuring backwards-compatibility
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 );
1504 virtual bool write( osgDB::OutputStream& os, const osg::Object& obj )
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() )
1511 if (os.getFileVersion()<123)
1517 os << (int)mask; //just write int value in binary case
1523 os << os.PROPERTY(ParentType::_name.c_str());
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 + "|");
1531 if ( !maskString.size() )
1532 maskString = std::string("NONE|");
1533 maskString.erase(maskString.size()-1,1);
1534 os << maskString << std::endl; //remove last "|"
1544 osgDB::IntLookup _lookup;
1547// ADDING MANIPULATORS
1548#define ADD_SERIALIZER(S) \
1549 wrapper->addSerializer( (S) )
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 )
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 )
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 )
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 )
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 )
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 )
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 )
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 )
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 )
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 )
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 )
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 )
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 )
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 )
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 )
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 )
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 )
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 )
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 )
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 )
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 )
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 )
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 )
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 )
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 )
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 )
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 )
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 )
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 )
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 )
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 )
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 )
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 )
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 )
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 )
1692#define ADD_VEC2_SERIALIZER(PROP, DEF) ADD_VEC2F_SERIALIZER(PROP, DEF)
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 )
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 )
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 )
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 )
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 )
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 )
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 )
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 )
1727#define ADD_VEC3_SERIALIZER(PROP, DEF) ADD_VEC3F_SERIALIZER(PROP, DEF)
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 )
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 )
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 )
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 )
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 )
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 )
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 )
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 )
1761#define ADD_VEC4_SERIALIZER(PROP, DEF) ADD_VEC4F_SERIALIZER(PROP, DEF)
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 )
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 )
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 )
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 )
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 )
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 )
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 )
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 )
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 )
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 )
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 )
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 )
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 )
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 )
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 )
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 )
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 )
1834#define ADD_ISAVECTOR_SERIALIZER(PROP, ELEMENTTYPE, NUMELEMENTSONROW) \
1835 wrapper->addSerializer( new osgDB::IsAVectorSerializer< MyClass >( #PROP, ELEMENTTYPE, NUMELEMENTSONROW), osgDB::BaseSerializer::RW_VECTOR )
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)
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)
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)
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)
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)
1862#define ADD_ENUM_VALUE(VALUE) \
1863 serializer->add(#VALUE, MyClass::VALUE)
1865#define ADD_ENUM_CLASS_VALUE(CLASS, VALUE) \
1866 serializer->add(#VALUE, CLASS::VALUE)
1868#define END_ENUM_SERIALIZER() \
1869 wrapper->addSerializer(serializer.get(), osgDB::BaseSerializer::RW_ENUM); }
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)
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)
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)
1887#define ADD_BITFLAG_VALUE(VALUE_NAME, VALUE) \
1888 serializer->add(#VALUE_NAME, VALUE)
1890#define END_BITFLAGS_SERIALIZER() \
1891 wrapper->addSerializer(serializer.get(), osgDB::BaseSerializer::RW_INT); }
1893// VERSION CONTROL OPERATORS
1894#define UPDATE_TO_VERSION(VER) \
1895 wrapper->setUpdatedVersion( (VER) );
1897#define UPDATE_TO_VERSION_SCOPED(VER) \
1898 osgDB::UpdateWrapperVersionProxy uwvp(wrapper, (VER));
1900#define ADDED_ASSOCIATE(STR) \
1901 wrapper->markAssociateAsAdded( STR );
1903#define REMOVED_ASSOCIATE(STR) \
1904 wrapper->markAssociateAsRemoved( STR );
1906#define REMOVE_SERIALIZER(PROP) \
1907 wrapper->markSerializerAsRemoved( #PROP );
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 )
1913#define ADD_METHOD_OBJECT( METHODNAME, METHODOBJECTCLASS ) wrapper->addMethodObject(METHODNAME, new METHODOBJECTCLASS());
1915#define ADD_METHOD(METHODNAME) \
1917 struct MethodCaller : public osgDB::MethodObject \
1919 virtual bool run(void* objectPtr, osg::Parameters&, osg::Parameters&) const \
1921 MyClass* obj = reinterpret_cast<MyClass*>(objectPtr); \
1922 obj->METHODNAME(); \
1926 wrapper->addMethodObject(#METHODNAME, new MethodCaller()); \
1930#define SET_USAGE(VALUE) wrapper->getLastSerializer()->setUsage(VALUE)