/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2010 Robert Osfield * * This library is open source and may be redistributed and/or modified under * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or * (at your option) any later version. The full license is in LICENSE file * included with this distribution, and on the openscenegraph.org website. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * OpenSceneGraph Public License for more details. */ // Written by Wang Rui, (C) 2010 #ifndef OSGDB__SERIALIZER #define OSGDB__SERIALIZER #include #include #include #include #include #include #include #include namespace osgDB { #ifndef OBJECT_CAST #define OBJECT_CAST static_cast #endif class IntLookup { public: typedef int Value; typedef std::map StringToValue; typedef std::map ValueToString; IntLookup() {} unsigned int size() const { return _stringToValue.size(); } void add( const char* str, Value value ) { if ( _valueToString.find(value)!=_valueToString.end() ) { osg::notify(osg::WARN) << "Duplicate enum value " << value << " with old string: " << _valueToString[value] << " and new string: " << str << std::endl; } _valueToString[value] = str; _stringToValue[str] = value; } Value getValue( const char* str ) { StringToValue::iterator itr = _stringToValue.find(str); if ( itr==_stringToValue.end() ) { Value value; std::stringstream stream; stream << str; stream >> value; _stringToValue[str] = value; return value; } return itr->second; } const std::string& getString( Value value ) { ValueToString::iterator itr = _valueToString.find(value); if ( itr==_valueToString.end() ) { std::string str; std::stringstream stream; stream << value; stream >> str; _valueToString[value] = str; return _valueToString[value]; } return itr->second; } protected: StringToValue _stringToValue; ValueToString _valueToString; }; class UserLookupTableProxy { public: typedef void (*AddValueFunc)( IntLookup* lookup ); UserLookupTableProxy( AddValueFunc func ) { if ( func ) (*func)(&_lookup); } IntLookup _lookup; }; #define BEGIN_USER_TABLE(NAME, CLASS) \ static void add_user_value_func_##NAME(osgDB::IntLookup*); \ static osgDB::UserLookupTableProxy s_user_lookup_table_##NAME(&add_user_value_func_##NAME); \ static void add_user_value_func_##NAME(osgDB::IntLookup* lookup) { typedef CLASS MyClass #define ADD_USER_VALUE(VALUE) lookup->add(#VALUE, MyClass::VALUE) #define END_USER_TABLE() } #define USER_READ_FUNC(NAME, FUNCNAME) \ static int FUNCNAME(osgDB::InputStream& is) { \ int value; if (is.isBinary()) is >> value; \ else { std::string str; is >> str; \ value = (s_user_lookup_table_##NAME)._lookup.getValue(str.c_str()); } \ return value; } #define USER_WRITE_FUNC(NAME, FUNCNAME) \ static void FUNCNAME(osgDB::OutputStream& os, int value) { \ if (os.isBinary()) os << value; \ else os << (s_user_lookup_table_##NAME)._lookup.getString(value); } \ class BaseSerializer : public osg::Referenced { friend class ObjectWrapper; public: enum Type { RW_UNDEFINED = 0, RW_USER, RW_OBJECT, RW_IMAGE, RW_LIST, RW_BOOL, RW_CHAR, RW_UCHAR, RW_SHORT, RW_USHORT, RW_INT, RW_UINT, RW_FLOAT, RW_DOUBLE, RW_VEC2F, RW_VEC2D, RW_VEC3F, RW_VEC3D, RW_VEC4F, RW_VEC4D, RW_QUAT, RW_PLANE, RW_MATRIXF, RW_MATRIXD, RW_MATRIX, RW_GLENUM, RW_STRING, RW_ENUM }; BaseSerializer() : _firstVersion(0), _lastVersion(INT_MAX) {} virtual bool read( InputStream&, osg::Object& ) = 0; virtual bool write( OutputStream&, const osg::Object& ) = 0; virtual const std::string& getName() const = 0; protected: int _firstVersion; // Library version when the serializer is first introduced int _lastVersion; // Library version when the serializer is last required. }; template class UserSerializer : public BaseSerializer { public: typedef bool (*Checker)( const C& ); typedef bool (*Reader)( InputStream&, C& ); typedef bool (*Writer)( OutputStream&, const C& ); UserSerializer( const char* name, Checker cf, Reader rf, Writer wf ) : BaseSerializer(), _name(name), _checker(cf), _reader(rf), _writer(wf) {} virtual bool read( InputStream& is, osg::Object& obj ) { C& object = OBJECT_CAST(obj); if ( is.isBinary() ) { bool ok = false; is >> ok; if ( !ok ) return true; } else { if ( !is.matchString(_name) ) return true; } return (*_reader)(is, object); } virtual bool write( OutputStream& os, const osg::Object& obj ) { const C& object = OBJECT_CAST(obj); bool ok = (*_checker)(object); if ( os.isBinary() ) { os << ok; if ( !ok ) return true; } else { if ( !ok ) return true; os << os.PROPERTY(_name.c_str()); } return (*_writer)(os, object); } virtual const std::string& getName() const { return _name; } protected: std::string _name; Checker _checker; public: Reader _reader; Writer _writer; }; template class TemplateSerializer : public BaseSerializer { public: TemplateSerializer( const char* name, P def) : BaseSerializer(), _name(name), _defaultValue(def) {} virtual bool read( InputStream& is, osg::Object& obj ) = 0; virtual bool write( OutputStream& os, const osg::Object& obj ) = 0; virtual const std::string& getName() const { return _name; } protected: std::string _name; P _defaultValue; }; template class PropByValSerializer : public TemplateSerializer

{ public: typedef TemplateSerializer

ParentType; typedef P (C::*Getter)() const; typedef void (C::*Setter)( P ); PropByValSerializer( const char* name, P def, Getter gf, Setter sf, bool useHex=false ) : ParentType(name, def), _getter(gf), _setter(sf), _useHex(useHex) {} virtual bool read( InputStream& is, osg::Object& obj ) { C& object = OBJECT_CAST(obj); P value; if ( is.isBinary() ) { is >> value; if ( ParentType::_defaultValue!=value ) (object.*_setter)( value ); } else if ( is.matchString(ParentType::_name) ) { if ( _useHex ) is >> std::hex; is >> value; if ( _useHex ) is >> std::dec; (object.*_setter)( value ); } return true; } virtual bool write( OutputStream& os, const osg::Object& obj ) { const C& object = OBJECT_CAST(obj); P value = (object.*_getter)(); if ( os.isBinary() ) { os << value; } else if ( ParentType::_defaultValue!=value ) { os << os.PROPERTY((ParentType::_name).c_str()); if ( _useHex ) { os << std::hex << std::showbase; } os << value; if ( _useHex ) os << std::dec << std::noshowbase; os << std::endl; } return true; } public: Getter _getter; Setter _setter; protected: bool _useHex; }; template class PropByRefSerializer : public TemplateSerializer

{ public: typedef TemplateSerializer

ParentType; typedef const P& CP; typedef CP (C::*Getter)() const; typedef void (C::*Setter)( CP ); PropByRefSerializer( const char* name, CP def, Getter gf, Setter sf ) : ParentType(name, def), _getter(gf), _setter(sf) {} virtual bool read( InputStream& is, osg::Object& obj ) { C& object = OBJECT_CAST(obj); P value; if ( is.isBinary() ) { is >> value; if ( ParentType::_defaultValue!=value ) (object.*_setter)( value ); } else if ( is.matchString(ParentType::_name) ) { is >> value; (object.*_setter)( value ); } return true; } virtual bool write( OutputStream& os, const osg::Object& obj ) { const C& object = OBJECT_CAST(obj); CP value = (object.*_getter)(); if ( os.isBinary() ) { os << value; } else if ( ParentType::_defaultValue!=value ) { os << os.PROPERTY((ParentType::_name).c_str()) << value << std::endl; } return true; } public: Getter _getter; Setter _setter; }; template class MatrixSerializer : public TemplateSerializer { public: typedef TemplateSerializer ParentType; typedef const osg::Matrix& (C::*Getter)() const; typedef void (C::*Setter)( const osg::Matrix& ); MatrixSerializer( const char* name, const osg::Matrix& def, Getter gf, Setter sf ) : ParentType(name, def), _getter(gf), _setter(sf) {} virtual bool read( InputStream& is, osg::Object& obj ) { C& object = OBJECT_CAST(obj); osg::Matrix value; if ( is.isBinary() ) { readMatrixImplementation( is, value ); if ( ParentType::_defaultValue!=value ) (object.*_setter)( value ); } else if ( is.matchString(ParentType::_name) ) { readMatrixImplementation( is, value ); (object.*_setter)( value ); } return true; } virtual bool write( OutputStream& os, const osg::Object& obj ) { const C& object = OBJECT_CAST(obj); const osg::Matrix& value = (object.*_getter)(); if ( os.isBinary() ) { os << value; } else if ( ParentType::_defaultValue!=value ) { os << os.PROPERTY((ParentType::_name).c_str()) << value << std::endl; } return true; } protected: void readMatrixImplementation( InputStream& is, osg::Matrix& matrix ) { #if 1 is >> matrix; #else if ( is.getUseFloatMatrix() ) { osg::Matrixf realValue; is >> realValue; matrix = realValue; } else { osg::Matrixd realValue; is >> realValue; matrix = realValue; } #endif } public: Getter _getter; Setter _setter; }; template class GLenumSerializer : public TemplateSerializer

{ public: typedef TemplateSerializer

ParentType; typedef P (C::*Getter)() const; typedef void (C::*Setter)( P ); GLenumSerializer( const char* name, P def, Getter gf, Setter sf ) : ParentType(name, def), _getter(gf), _setter(sf) {} virtual bool read( InputStream& is, osg::Object& obj ) { C& object = OBJECT_CAST(obj); if ( is.isBinary() ) { GLenum value; is >> value; if ( ParentType::_defaultValue!=static_cast

(value) ) (object.*_setter)( static_cast

(value) ); } else if ( is.matchString(ParentType::_name) ) { DEF_GLENUM(value); is >> value; (object.*_setter)( static_cast

(value.get()) ); } return true; } virtual bool write( OutputStream& os, const osg::Object& obj ) { const C& object = OBJECT_CAST(obj); const P value = (object.*_getter)(); if ( os.isBinary() ) { os << static_cast(value); } else if ( ParentType::_defaultValue!=value ) { os << os.PROPERTY((ParentType::_name).c_str()) << GLENUM(value) << std::endl; } return true; } public: Getter _getter; Setter _setter; }; template class StringSerializer : public TemplateSerializer { public: typedef TemplateSerializer ParentType; typedef const std::string& (C::*Getter)() const; typedef void (C::*Setter)( const std::string& ); StringSerializer( const char* name, const std::string& def, Getter gf, Setter sf ) : ParentType(name, def), _getter(gf), _setter(sf) {} virtual bool read( InputStream& is, osg::Object& obj ) { C& object = OBJECT_CAST(obj); std::string value; if ( is.isBinary() ) { is >> value; if ( ParentType::_defaultValue!=value ) (object.*_setter)( value ); } else if ( is.matchString(ParentType::_name) ) { is.readWrappedString( value ); if ( !value.empty() ) (object.*_setter)( value ); } return true; } virtual bool write( OutputStream& os, const osg::Object& obj ) { const C& object = OBJECT_CAST(obj); const std::string& value = (object.*_getter)(); if ( os.isBinary() ) { os << value; } else if ( ParentType::_defaultValue!=value ) { os << os.PROPERTY((ParentType::_name).c_str()); os.writeWrappedString( value ); os << std::endl; } return true; } public: Getter _getter; Setter _setter; }; template class ObjectSerializer : public TemplateSerializer { public: typedef TemplateSerializer ParentType; typedef const P* (C::*Getter)() const; typedef void (C::*Setter)( P* ); ObjectSerializer( const char* name, P* def, Getter gf, Setter sf ) : ParentType(name, def), _getter(gf), _setter(sf) {} virtual bool read( InputStream& is, osg::Object& obj ) { C& object = OBJECT_CAST(obj); bool hasObject = false; if ( is.isBinary() ) { is >> hasObject; if ( hasObject ) { P* value = dynamic_cast( is.readObject() ); if ( ParentType::_defaultValue!=value ) (object.*_setter)( value ); } } else if ( is.matchString(ParentType::_name) ) { is >> hasObject; if ( hasObject ) { is >> is.BEGIN_BRACKET; P* value = dynamic_cast( is.readObject() ); if ( ParentType::_defaultValue!=value ) (object.*_setter)( value ); is >> is.END_BRACKET; } } return true; } virtual bool write( OutputStream& os, const osg::Object& obj ) { const C& object = OBJECT_CAST(obj); const P* value = (object.*_getter)(); bool hasObject = (value!=NULL); if ( os.isBinary() ) { os << hasObject; os.writeObject( value ); } else if ( ParentType::_defaultValue!=value ) { os << os.PROPERTY((ParentType::_name).c_str()) << hasObject; if ( hasObject ) { os << os.BEGIN_BRACKET << std::endl; os.writeObject( value ); os << os.END_BRACKET; } os << std::endl; } return true; } public: Getter _getter; Setter _setter; }; template class ImageSerializer : public TemplateSerializer { public: typedef TemplateSerializer ParentType; typedef const P* (C::*Getter)() const; typedef void (C::*Setter)( P* ); ImageSerializer( const char* name, P* def, Getter gf, Setter sf ) : ParentType(name, def), _getter(gf), _setter(sf) {} virtual bool read( InputStream& is, osg::Object& obj ) { C& object = OBJECT_CAST(obj); bool hasObject = false; if ( is.isBinary() ) { is >> hasObject; if ( hasObject ) { P* value = dynamic_cast( is.readImage() ); if ( ParentType::_defaultValue!=value ) (object.*_setter)( value ); } } else if ( is.matchString(ParentType::_name) ) { is >> hasObject; if ( hasObject ) { is >> is.BEGIN_BRACKET; P* value = dynamic_cast( is.readImage() ); if ( ParentType::_defaultValue!=value ) (object.*_setter)( value ); is >> is.END_BRACKET; } } return true; } virtual bool write( OutputStream& os, const osg::Object& obj ) { const C& object = OBJECT_CAST(obj); const P* value = (object.*_getter)(); bool hasObject = (value!=NULL); if ( os.isBinary() ) { os << hasObject; os.writeImage( value ); } else if ( ParentType::_defaultValue!=value ) { os << os.PROPERTY((ParentType::_name).c_str()) << hasObject; if ( hasObject ) { os << os.BEGIN_BRACKET << std::endl; os.writeImage( value ); os << os.END_BRACKET; } os << std::endl; } return true; } public: Getter _getter; Setter _setter; }; template class EnumSerializer : public TemplateSerializer

{ public: typedef TemplateSerializer

ParentType; typedef P (C::*Getter)() const; typedef B (C::*Setter)( P ); EnumSerializer( const char* name, P def, Getter gf, Setter sf ) : ParentType(name, def), _getter(gf), _setter(sf) {} void add( const char* str, P value ) { _lookup.add(str, static_cast(value)); } P getValue( const char* str ) { return static_cast

(_lookup.getValue(str)); } const std::string& getString( P value ) { return _lookup.getString(static_cast(value)); } virtual bool read( InputStream& is, osg::Object& obj ) { C& object = OBJECT_CAST(obj); IntLookup::Value value; if ( is.isBinary() ) { is >> value; if ( ParentType::_defaultValue!=static_cast

(value) ) (object.*_setter)( static_cast

(value) ); } else if ( is.matchString(ParentType::_name) ) { std::string str; is >> str; (object.*_setter)( getValue(str.c_str()) ); } return true; } virtual bool write( osgDB::OutputStream& os, const osg::Object& obj ) { const C& object = OBJECT_CAST(obj); const P value = (object.*_getter)(); if ( os.isBinary() ) { os << (IntLookup::Value)value; } else if ( ParentType::_defaultValue!=value ) { os << os.PROPERTY((ParentType::_name).c_str()) << getString(value) << std::endl; } return true; } public: Getter _getter; Setter _setter; protected: IntLookup _lookup; }; template class ListSerializer : public BaseSerializer { public: typedef typename P::value_type ValueType; typedef typename P::const_iterator ConstIterator; typedef const P& (C::*Getter)() const; typedef void (C::*Setter)( const P& ); ListSerializer( const char* name, Getter gf, Setter sf ) : _name(name), _getter(gf), _setter(sf) {} virtual const std::string& getName() const { return _name; } virtual bool read( InputStream& is, osg::Object& obj ) { C& object = OBJECT_CAST(obj); unsigned int size = 0; P list; if ( is.isBinary() ) { is >> size; for ( unsigned int i=0; i> value; list.push_back( value ); } if ( size>0 ) (object.*_setter)( list ); } else if ( is.matchString(_name) ) { is >> size; if ( size>0 ) is >> is.BEGIN_BRACKET; for ( unsigned int i=0; i> value; list.push_back( value ); } if ( size>0 ) { is >> is.END_BRACKET; (object.*_setter)( list ); } } return true; } virtual bool write( OutputStream& os, const osg::Object& obj ) { const C& object = OBJECT_CAST(obj); const P& list = (object.*_getter)(); unsigned int size = (unsigned int)list.size(); if ( os.isBinary() ) { os << size; for ( ConstIterator itr=list.begin(); itr!=list.end(); ++itr ) { os << (*itr); } } else if ( size>0 ) { os << os.PROPERTY((_name).c_str()) << size << os.BEGIN_BRACKET << std::endl; for ( ConstIterator itr=list.begin(); itr!=list.end(); ++itr ) { os << (*itr); } os << std::endl; os << os.END_BRACKET << std::endl; } return true; } public: std::string _name; Getter _getter; Setter _setter; }; // ADDING MANIPULATORS #define ADD_SERIALIZER(S) \ wrapper->addSerializer( (S) ) #define ADD_USER_SERIALIZER(PROP) \ wrapper->addSerializer( new osgDB::UserSerializer( \ #PROP, &check##PROP, &read##PROP, &write##PROP), osgDB::BaseSerializer::RW_USER ) #define ADD_BOOL_SERIALIZER(PROP, DEF) \ wrapper->addSerializer( new osgDB::PropByValSerializer< MyClass, bool >( \ #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_BOOL ) #define ADD_CHAR_SERIALIZER(PROP, DEF) \ wrapper->addSerializer( new osgDB::PropByValSerializer< MyClass, char >( \ #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_CHAR ) #define ADD_UCHAR_SERIALIZER(PROP, DEF) \ wrapper->addSerializer( new osgDB::PropByValSerializer< MyClass, unsigned char >( \ #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_UCHAR ) #define ADD_SHORT_SERIALIZER(PROP, DEF) \ wrapper->addSerializer( new osgDB::PropByValSerializer< MyClass, short >( \ #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_SHORT ) #define ADD_USHORT_SERIALIZER(PROP, DEF) \ wrapper->addSerializer( new osgDB::PropByValSerializer< MyClass, unsigned short >( \ #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_USHORT ) #define ADD_HEXSHORT_SERIALIZER(PROP, DEF) \ wrapper->addSerializer( new osgDB::PropByValSerializer< MyClass, unsigned short >( \ #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP, true), osgDB::BaseSerializer::RW_USHORT ) #define ADD_INT_SERIALIZER(PROP, DEF) \ wrapper->addSerializer( new osgDB::PropByValSerializer< MyClass, int >( \ #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_INT ) #define ADD_UINT_SERIALIZER(PROP, DEF) \ wrapper->addSerializer( new osgDB::PropByValSerializer< MyClass, unsigned int >( \ #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_UINT ) #define ADD_GLINT_SERIALIZER(PROP, DEF) \ wrapper->addSerializer( new osgDB::PropByValSerializer< MyClass, GLint >( \ #PROP, ((int)(DEF)), &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_INT ) #define ADD_HEXINT_SERIALIZER(PROP, DEF) \ wrapper->addSerializer( new osgDB::PropByValSerializer< MyClass, unsigned int >( \ #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP, true), osgDB::BaseSerializer::RW_UINT ) #define ADD_FLOAT_SERIALIZER(PROP, DEF) \ wrapper->addSerializer( new osgDB::PropByValSerializer< MyClass, float >( \ #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_FLOAT ) #define ADD_DOUBLE_SERIALIZER(PROP, DEF) \ wrapper->addSerializer( new osgDB::PropByValSerializer< MyClass, double >( \ #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_DOUBLE ) #define ADD_REF_BOOL_SERIALIZER(PROP, DEF) \ wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, bool >( \ #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_BOOL ) #define ADD_REF_CHAR_SERIALIZER(PROP, DEF) \ wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, char >( \ #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_CHAR ) #define ADD_REF_UCHAR_SERIALIZER(PROP, DEF) \ wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, unsigned char >( \ #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_UCHAR ) #define ADD_REF_SHORT_SERIALIZER(PROP, DEF) \ wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, short >( \ #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_SHORT ) #define ADD_REF_USHORT_SERIALIZER(PROP, DEF) \ wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, unsigned short >( \ #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_USHORT ) #define ADD_REF_HEXSHORT_SERIALIZER(PROP, DEF) \ wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, unsigned short >( \ #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP, true), osgDB::BaseSerializer::RW_USHORT ) #define ADD_REF_INT_SERIALIZER(PROP, DEF) \ wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, int >( \ #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_INT ) #define ADD_REF_UINT_SERIALIZER(PROP, DEF) \ wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, unsigned int >( \ #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_UINT ) #define ADD_REF_GLINT_SERIALIZER(PROP, DEF) \ wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, GLint >( \ #PROP, ((int)(DEF)), &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_INT ) #define ADD_REF_HEXINT_SERIALIZER(PROP, DEF) \ wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, unsigned int >( \ #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP, true), osgDB::BaseSerializer::RW_UINT ) #define ADD_REF_FLOAT_SERIALIZER(PROP, DEF) \ wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, float >( \ #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_FLOAT ) #define ADD_REF_DOUBLE_SERIALIZER(PROP, DEF) \ wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, double >( \ #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_DOUBLE ) #define ADD_VEC2F_SERIALIZER(PROP, DEF) \ wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::Vec2f >( \ #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_VEC2F ) #define ADD_VEC2D_SERIALIZER(PROP, DEF) \ wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::Vec2d >( \ #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_VEC2D ) #define ADD_VEC2_SERIALIZER(PROP, DEF) ADD_VEC2F_SERIALIZER(PROP, DEF) #define ADD_VEC3F_SERIALIZER(PROP, DEF) \ wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::Vec3f >( \ #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_VEC3F ) #define ADD_VEC3D_SERIALIZER(PROP, DEF) \ wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::Vec3d >( \ #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_VEC3D ) #define ADD_VEC3_SERIALIZER(PROP, DEF) ADD_VEC3F_SERIALIZER(PROP, DEF) #define ADD_VEC4F_SERIALIZER(PROP, DEF) \ wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::Vec4f >( \ #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_VEC4F ) #define ADD_VEC4D_SERIALIZER(PROP, DEF) \ wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::Vec4d >( \ #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_VEC4D ) #define ADD_VEC4_SERIALIZER(PROP, DEF) ADD_VEC4F_SERIALIZER(PROP, DEF) #define ADD_QUAT_SERIALIZER(PROP, DEF) \ wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::Quat >( \ #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_QUAT ) #define ADD_PLANE_SERIALIZER(PROP, DEF) \ wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::Plane >( \ #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_PLANE ) #define ADD_MATRIXF_SERIALIZER(PROP, DEF) \ wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::Matrixf >( \ #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_MATRIXF ) #define ADD_MATRIXD_SERIALIZER(PROP, DEF) \ wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::Matrixd >( \ #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_MATRIXD ) #define ADD_MATRIX_SERIALIZER(PROP, DEF) \ wrapper->addSerializer( new osgDB::MatrixSerializer< MyClass >( \ #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_MATRIX ) #define ADD_GLENUM_SERIALIZER(PROP, TYPE, DEF) \ wrapper->addSerializer( new osgDB::GLenumSerializer< MyClass, TYPE >( \ #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_GLENUM ) #define ADD_STRING_SERIALIZER(PROP, DEF) \ wrapper->addSerializer( new osgDB::StringSerializer< MyClass >( \ #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_STRING ) #define ADD_OBJECT_SERIALIZER(PROP, TYPE, DEF) \ wrapper->addSerializer( new osgDB::ObjectSerializer< MyClass, TYPE >( \ #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_OBJECT ) #define ADD_IMAGE_SERIALIZER(PROP, TYPE, DEF) \ wrapper->addSerializer( new osgDB::ImageSerializer< MyClass, TYPE >( \ #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_IMAGE ) #define ADD_LIST_SERIALIZER(PROP, TYPE) \ wrapper->addSerializer( new osgDB::ListSerializer< MyClass, TYPE >( \ #PROP, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_LIST ) #define BEGIN_ENUM_SERIALIZER(PROP, DEF) \ { typedef osgDB::EnumSerializer MySerializer; \ osg::ref_ptr serializer = new MySerializer( \ #PROP, MyClass::DEF, &MyClass::get##PROP, &MyClass::set##PROP) #define BEGIN_ENUM_SERIALIZER2(PROP, TYPE, DEF) \ { typedef osgDB::EnumSerializer MySerializer; \ osg::ref_ptr serializer = new MySerializer( \ #PROP, MyClass::DEF, &MyClass::get##PROP, &MyClass::set##PROP) #define BEGIN_ENUM_SERIALIZER3(PROP, DEF) \ { typedef osgDB::EnumSerializer MySerializer; \ osg::ref_ptr serializer = new MySerializer( \ #PROP, MyClass::DEF, &MyClass::get##PROP, &MyClass::set##PROP) #define BEGIN_ENUM_SERIALIZER4(PROPERTIES_CLASS, PROP, DEF) \ { typedef osgDB::EnumSerializer MySerializer; \ osg::ref_ptr serializer = new MySerializer( \ #PROP, PROPERTIES_CLASS::DEF, &MyClass::get##PROP, &MyClass::set##PROP) #define ADD_ENUM_VALUE(VALUE) \ serializer->add(#VALUE, MyClass::VALUE) #define ADD_ENUM_CLASS_VALUE(CLASS, VALUE) \ serializer->add(#VALUE, CLASS::VALUE) #define END_ENUM_SERIALIZER() \ wrapper->addSerializer(serializer.get(), osgDB::BaseSerializer::RW_ENUM); } // VERSION CONTROL OPERATORS #define UPDATE_TO_VERSION(VER) \ wrapper->setUpdatedVersion( (VER) ); #define REMOVE_SERIALIZER(PROP) \ wrapper->markSerializerAsRemoved( #PROP ); } #endif