/* -*-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 { typedef std::vector StringList; extern OSGDB_EXPORT void split( const std::string& src, StringList& list, char separator=' ' ); #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 static_cast(_stringToValue.size()); } void add( const char* str, Value value ) { if ( _valueToString.find(value)!=_valueToString.end() ) { osg::notify(osg::INFO) << "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; } StringToValue& getStringToValue() { return _stringToValue; } const StringToValue& getStringToValue() const { return _stringToValue; } ValueToString& getValueToString() { return _valueToString; } const ValueToString& getValueToString() const { return _valueToString; } 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, RW_VEC2B, RW_VEC2UB, RW_VEC2S, RW_VEC2US, RW_VEC2I, RW_VEC2UI, RW_VEC3B, RW_VEC3UB, RW_VEC3S, RW_VEC3US, RW_VEC3I, RW_VEC3UI, RW_VEC4B, RW_VEC4UB, RW_VEC4S, RW_VEC4US, RW_VEC4I, RW_VEC4UI, RW_BOUNDINGBOXF, RW_BOUNDINGBOXD, RW_BOUNDINGSPHEREF, RW_BOUNDINGSPHERED, RW_VECTOR, RW_MAP }; enum Usage { READ_WRITE_PROPERTY = 1, GET_PROPERTY = 2, SET_PROPERTY = 4, GET_SET_PROPERTY = GET_PROPERTY | SET_PROPERTY }; BaseSerializer(int usage) : _firstVersion(0), _lastVersion(INT_MAX), _usage(usage) {} virtual bool set(osg::Object& /*object*/, void* /*value*/) { return false; } virtual bool get(const osg::Object& /*object*/, void* /*value*/) { return false; } virtual bool read( InputStream&, osg::Object& ) = 0; virtual bool write( OutputStream&, const osg::Object& ) = 0; virtual const std::string& getName() const = 0; virtual IntLookup* getIntLookup() { return 0; } void setUsage(int usage) { _usage = usage; } int getUsage() const { return _usage; } void setUsage(bool hasGetter, bool hasSetter) { setUsage( ((hasGetter && hasSetter) ? BaseSerializer::READ_WRITE_PROPERTY : 0) | ((hasGetter) ? BaseSerializer::GET_PROPERTY : 0) | ((hasSetter) ? BaseSerializer::SET_PROPERTY : 0) ); } bool supportsReadWrite() const { return (_usage & READ_WRITE_PROPERTY)!=0; } bool supportsGetSet() const { return (_usage & GET_SET_PROPERTY)!=0; } bool supportsGet() const { return (_usage & GET_PROPERTY)!=0; } bool supportsSet() const { return (_usage & SET_PROPERTY)!=0; } protected: int _firstVersion; // Library version when the serializer is first introduced int _lastVersion; // Library version when the serializer is last required. int _usage; // How the Serializer can be used. }; 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(READ_WRITE_PROPERTY), _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(READ_WRITE_PROPERTY), _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) { ParentType::setUsage( _getter!=0, _setter!=0); } virtual bool read( InputStream& is, osg::Object& obj ) { C& object = OBJECT_CAST(obj); P value; if ( is.isBinary() ) { is >> 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) { ParentType::setUsage( _getter!=0, _setter!=0); } virtual bool read( InputStream& is, osg::Object& obj ) { C& object = OBJECT_CAST(obj); P value; if ( is.isBinary() ) { is >> 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) { ParentType::setUsage( _getter!=0, _setter!=0); } virtual bool read( InputStream& is, osg::Object& obj ) { C& object = OBJECT_CAST(obj); osg::Matrix value; if ( is.isBinary() ) { readMatrixImplementation( is, 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) { ParentType::setUsage( _getter!=0, _setter!=0); } virtual bool read( InputStream& is, osg::Object& obj ) { C& object = OBJECT_CAST(obj); if ( is.isBinary() ) { GLenum value; is >> 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) { ParentType::setUsage( _getter!=0, _setter!=0); } virtual bool read( InputStream& is, osg::Object& obj ) { C& object = OBJECT_CAST(obj); std::string value; if ( is.isBinary() ) { is >> value; (object.*_setter)( value ); } else if ( is.matchString(ParentType::_name) ) { is.readWrappedString( value ); if ( !value.empty() && (_setter!=0) ) (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) { ParentType::setUsage( _getter!=0, _setter!=0); } virtual bool set(osg::Object& obj, void* value) { C& object = OBJECT_CAST(obj); (object.*_setter)( *(reinterpret_cast(value)) ); return true; } virtual bool get(const osg::Object& obj, void* value) { const C& object = OBJECT_CAST(obj);*(reinterpret_cast(value )) = (object.*_getter)(); return true; } 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() ); (object.*_setter)( value ); } } else if ( is.matchString(ParentType::_name) ) { is >> hasObject; if ( hasObject ) { is >> is.BEGIN_BRACKET; P* value = dynamic_cast( is.readObject() ); (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; if (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) { ParentType::setUsage( _getter!=0, _setter!=0); } virtual bool set(osg::Object& obj, void* value) { C& object = OBJECT_CAST(obj); (object.*_setter)( *(reinterpret_cast(value)) ); return true; } virtual bool get(const osg::Object& obj, void* value) { const C& object = OBJECT_CAST(obj);*(reinterpret_cast(value )) = (object.*_getter)(); return true; } 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() ); (object.*_setter)( value ); } } else if ( is.matchString(ParentType::_name) ) { is >> hasObject; if ( hasObject ) { is >> is.BEGIN_BRACKET; P* value = dynamic_cast( is.readImage() ); (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) { ParentType::setUsage( _getter!=0, _setter!=0); } virtual IntLookup* getIntLookup() { return &_lookup; } 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; (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 ): BaseSerializer(READ_WRITE_PROPERTY), _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; }; class VectorBaseSerializer : public BaseSerializer { public: VectorBaseSerializer(BaseSerializer::Type elementType, unsigned int elementSize): BaseSerializer(READ_WRITE_PROPERTY|GET_SET_PROPERTY), _elementType(elementType),_elementSize(elementSize) {} Type getElementType() const { return _elementType; } unsigned int getElementSize() const { return _elementSize; } virtual unsigned int size(const osg::Object& /*obj*/) const { return 0; } virtual void resize(osg::Object& /*obj*/, unsigned int /*numElements*/) const {} virtual void reserve(osg::Object& /*obj*/, unsigned int /*numElements*/) const {} virtual void clear(osg::Object& /*obj*/) const {} virtual void addElement(osg::Object& /*obj*/, void* /*ptr*/) const {} virtual void insertElement(osg::Object& /*obj*/, unsigned int /*index*/, void* /*ptr*/) const {} virtual void setElement(osg::Object& /*obj*/, unsigned int /*index*/, void* /*ptr*/) const {} virtual void* getElement(osg::Object& /*obj*/, unsigned int /*index*/) const { return 0; } virtual const void* getElement(const osg::Object& /*obj*/, unsigned int /*index*/) const { return 0; } protected: Type _elementType; unsigned int _elementSize; }; template class VectorSerializer : public VectorBaseSerializer { public: typedef typename P::value_type ValueType; typedef typename P::const_iterator ConstIterator; typedef P& (C::*Getter)(); typedef const P& (C::*ConstGetter)() const; typedef void (C::*Setter)( const P& ); VectorSerializer( const char* name, ConstGetter cgf, Getter gf, Setter sf, BaseSerializer::Type elementType, unsigned int numElementsOnRow): VectorBaseSerializer(elementType, sizeof(ValueType)), _name(name), _constgetter(cgf), _getter(gf), _setter(sf), _numElementsOnRow(numElementsOnRow) {} virtual const std::string& getName() const { return _name; } virtual unsigned int size(const osg::Object& obj) const { const C& object = OBJECT_CAST(obj); const P& list = (object.*_constgetter)(); return static_cast(list.size()); } virtual void resize(osg::Object& obj, unsigned int numElements) const { C& object = OBJECT_CAST(obj); P& list = (object.*_getter)(); list.resize(numElements); } virtual void reserve(osg::Object& obj, unsigned int numElements) const { C& object = OBJECT_CAST(obj); P& list = (object.*_getter)(); list.reserve(numElements); } virtual void clear(osg::Object& obj) const { C& object = OBJECT_CAST(obj); P& list = (object.*_getter)(); list.clear(); } virtual void addElement(osg::Object& obj, void* ptr) const { C& object = OBJECT_CAST(obj); P& list = (object.*_getter)(); list.push_back(*reinterpret_cast(ptr)); } virtual void insertElement(osg::Object& obj, unsigned int index, void* ptr) const { C& object = OBJECT_CAST(obj); P& list = (object.*_getter)(); if (index>=list.size()) list.resize(index+1); list.insert(list.begin()+index, *reinterpret_cast(ptr)); } virtual void setElement(osg::Object& obj, unsigned int index, void* ptr) const { C& object = OBJECT_CAST(obj); P& list = (object.*_getter)(); if (index>=list.size()) list.resize(index+1); list[index] = *reinterpret_cast(ptr); } virtual void* getElement(osg::Object& obj, unsigned int index) const { C& object = OBJECT_CAST(obj); P& list = (object.*_getter)(); if (index>=list.size()) return 0; else return &list[index]; } virtual const void* getElement(const osg::Object& obj, unsigned int index) const { const C& object = OBJECT_CAST(obj); const P& list = (object.*_constgetter)(); if (index>=list.size()) return 0; else return &list[index]; } 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.*_constgetter)(); 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; if (_numElementsOnRow==0) { for ( ConstIterator itr=list.begin(); itr!=list.end(); ++itr ) { os << (*itr); } } else if (_numElementsOnRow==1) { for ( ConstIterator itr=list.begin(); itr!=list.end(); ++itr ) { os << (*itr); os << std::endl; } } else { unsigned int i = _numElementsOnRow-1; for (ConstIterator itr=list.begin(); itr!=list.end(); ++itr) { os << (*itr); if (i==0) { os << std::endl; i = _numElementsOnRow-1; } else --i; } if (i!=_numElementsOnRow) os << std::endl; } os << os.END_BRACKET << std::endl; } return true; } public: std::string _name; ConstGetter _constgetter; Getter _getter; Setter _setter; unsigned int _numElementsOnRow; }; template class IsAVectorSerializer : public VectorBaseSerializer { public: typedef typename C::value_type ValueType; typedef typename C::const_iterator ConstIterator; IsAVectorSerializer( const char* name, BaseSerializer::Type elementType, unsigned int numElementsOnRow) : VectorBaseSerializer(elementType, sizeof(ValueType)), _name(name), _numElementsOnRow(numElementsOnRow) {} virtual const std::string& getName() const { return _name; } virtual unsigned int size(const osg::Object& obj) const { const C& list = OBJECT_CAST(obj); return static_cast(list.size()); } virtual void resize(osg::Object& obj, unsigned int numElements) const { C& list = OBJECT_CAST(obj); list.resize(numElements); } virtual void reserve(osg::Object& obj, unsigned int numElements) const { C& list = OBJECT_CAST(obj); list.reserve(numElements); } virtual void clear(osg::Object& obj) const { C& list = OBJECT_CAST(obj); list.clear(); } virtual void addElement(osg::Object& obj, void* ptr) const { C& list = OBJECT_CAST(obj); list.push_back(*reinterpret_cast(ptr)); } virtual void insertElement(osg::Object& obj, unsigned int index, void* ptr) const { C& list = OBJECT_CAST(obj); if (index>=list.size()) list.resize(index+1); list.insert(list.begin()+index, *reinterpret_cast(ptr)); } virtual void setElement(osg::Object& obj, unsigned int index, void* ptr) const { C& list = OBJECT_CAST(obj); if (index>=list.size()) list.resize(index+1); list[index] = *reinterpret_cast(ptr); } virtual void* getElement(osg::Object& obj, unsigned int index) const { C& list = OBJECT_CAST(obj); if (index>=list.size()) return 0; else return &list[index]; } virtual const void* getElement(const osg::Object& obj, unsigned int index) const { const C& list = OBJECT_CAST(obj); if (index>=list.size()) return 0; else return &list[index]; } virtual bool read( InputStream& is, osg::Object& obj ) { C& list = OBJECT_CAST(obj); unsigned int size = 0; if ( is.isBinary() ) { is >> size; for ( unsigned int i=0; i> value; list.push_back( value ); } } 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; } } return true; } virtual bool write( OutputStream& os, const osg::Object& obj ) { const C& list = OBJECT_CAST(obj); 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; if (_numElementsOnRow==0) { for ( ConstIterator itr=list.begin(); itr!=list.end(); ++itr ) { os << (*itr); } } else if (_numElementsOnRow==1) { for ( ConstIterator itr=list.begin(); itr!=list.end(); ++itr ) { os << (*itr); os << std::endl; } } else { unsigned int i = _numElementsOnRow-1; for (ConstIterator itr=list.begin(); itr!=list.end(); ++itr) { os << (*itr); if (i==0) { os << std::endl; i = _numElementsOnRow-1; } else --i; } if (i!=_numElementsOnRow) os << std::endl; } os << os.END_BRACKET << std::endl; } return true; } public: std::string _name; unsigned int _numElementsOnRow; }; class MapIteratorObject : public osg::Object { public: MapIteratorObject(): _keyType(BaseSerializer::RW_UNDEFINED), _keySize(0), _elementType(BaseSerializer::RW_UNDEFINED),_elementSize(0) {} MapIteratorObject(BaseSerializer::Type keyType, unsigned int keySize, BaseSerializer::Type elementType, unsigned int elementSize): _keyType(keyType), _keySize(keySize), _elementType(elementType),_elementSize(elementSize) {} MapIteratorObject(const MapIteratorObject& rhs, const osg::CopyOp copyop=osg::CopyOp::SHALLOW_COPY): osg::Object(rhs, copyop), _keyType(rhs._keyType), _keySize(rhs._keySize), _elementType(rhs._elementType),_elementSize(rhs._elementSize) {} META_Object(osgDB, MapIteratorObject); BaseSerializer::Type getKeyType() const { return _keyType; } unsigned int getKeySize() const { return _keySize; } BaseSerializer::Type getElementType() const { return _elementType; } unsigned int getElementSize() const { return _elementSize; } virtual bool advance() { return false; } virtual bool valid() const { return false; } virtual const void* getKey() const { return 0; } virtual void* getElement() const { return 0; } virtual void setElement(void* /*ptr*/) const {} protected: BaseSerializer::Type _keyType; unsigned int _keySize; BaseSerializer::Type _elementType; unsigned int _elementSize; }; class MapBaseSerializer : public BaseSerializer { public: MapBaseSerializer(BaseSerializer::Type keyType, unsigned int keySize, BaseSerializer::Type elementType, unsigned int elementSize): BaseSerializer(READ_WRITE_PROPERTY|GET_SET_PROPERTY), _keyType(keyType), _keySize(keySize), _elementType(elementType),_elementSize(elementSize) {} Type getKeyType() const { return _keyType; } unsigned int getKeySize() const { return _keySize; } Type getElementType() const { return _elementType; } unsigned int getElementSize() const { return _elementSize; } virtual void clear(osg::Object& /*obj*/) const {} virtual void setElement(osg::Object& /*obj*/, void* /*ptrKey*/, void* /*ptrValue*/) const {} virtual void* getElement(osg::Object& /*obj*/, void* /*ptrKey*/) const { return 0; } virtual const void* getElement(const osg::Object& /*obj*/, void* /*ptrKey*/) const { return 0; } virtual unsigned int size(const osg::Object& /*obj*/) const { return 0; } virtual MapIteratorObject* createIterator(osg::Object& /*obj*/) const { return 0; } virtual MapIteratorObject* createReverseIterator(osg::Object& /*obj*/) const { return 0; } protected: Type _keyType; unsigned int _keySize; Type _elementType; unsigned int _elementSize; }; template class MapSerializer : public MapBaseSerializer { public: typedef typename P::value_type ValueType; typedef typename P::key_type KeyType; typedef typename P::mapped_type ElementType; typedef typename P::iterator Iterator; typedef typename P::reverse_iterator ReverseIterator; typedef typename P::const_iterator ConstIterator; typedef P& (C::*Getter)(); typedef const P& (C::*ConstGetter)() const; typedef void (C::*Setter)( const P& ); MapSerializer( const char* name, ConstGetter cgf, Getter gf, Setter sf, BaseSerializer::Type keyType, BaseSerializer::Type elementType): MapBaseSerializer(keyType, sizeof(KeyType), elementType, sizeof(ElementType)), _name(name), _constgetter(cgf), _getter(gf), _setter(sf) {} virtual const std::string& getName() const { return _name; } virtual void clear(osg::Object& obj) const { C& object = OBJECT_CAST(obj); P& map = (object.*_getter)(); map.clear(); } virtual void setElement(osg::Object& obj, void* ptrKey, void* ptrValue) const { C& object = OBJECT_CAST(obj); P& map = (object.*_getter)(); map[*reinterpret_cast(ptrKey)] = *reinterpret_cast(ptrValue); } virtual void* getElement(osg::Object& obj, void* ptrKey) const { C& object = OBJECT_CAST(obj); P& map = (object.*_getter)(); return &(map[*reinterpret_cast(ptrKey)]); } virtual const void* getElement(const osg::Object& obj, void* ptrKey) const { const C& object = OBJECT_CAST(obj); const P& map = (object.*_constgetter)(); ConstIterator itr = map.find(*reinterpret_cast(ptrKey)); if (itr==map.end()) return 0; else return &(itr->second); } virtual unsigned int size(const osg::Object& obj) const { const C& object = OBJECT_CAST(obj); const P& map = (object.*_constgetter)(); return map.size(); } struct MapIterator : public MapIteratorObject { MapIterator(BaseSerializer::Type keyType, unsigned int keySize, BaseSerializer::Type elementType, unsigned int elementSize, Iterator itr, Iterator endItr): MapIteratorObject(keyType, keySize, elementType, elementSize), _itr(itr),_endItr(endItr) {} Iterator _itr; Iterator _endItr; virtual bool advance() { if (valid()) ++_itr; return valid(); } virtual bool valid() const { return _itr!=_endItr; } virtual const void* getKey() const { return valid() ? &(_itr->first) : 0; } virtual void* getElement() const { return valid() ? &(_itr->second) : 0; } virtual void setElement(void* ptr) const { if (valid()) _itr->second = *reinterpret_cast(ptr); } }; struct ReverseMapIterator : public MapIteratorObject { ReverseMapIterator(BaseSerializer::Type keyType, unsigned int keySize, BaseSerializer::Type elementType, unsigned int elementSize, ReverseIterator itr, ReverseIterator endItr): MapIteratorObject(keyType, keySize, elementType, elementSize), _itr(itr),_endItr(endItr) {} ReverseIterator _itr; ReverseIterator _endItr; virtual bool advance() { if (valid()) ++_itr; return valid(); } virtual bool valid() const { return _itr!=_endItr; } virtual const void* getKey() const { return valid() ? &(_itr->first) : 0; } virtual void* getElement() const { return valid() ? &(_itr->second) : 0; } virtual void setElement(void* ptr) const { if (valid()) _itr->second = *reinterpret_cast(ptr); } }; virtual MapIteratorObject* createIterator(osg::Object& obj) const { C& object = OBJECT_CAST(obj); P& map = (object.*_getter)(); return new MapIterator(_keyType, _keySize, _elementType, _elementSize, map.begin(), map.end()); } virtual MapIteratorObject* createReverseIterator(osg::Object& obj) const { C& object = OBJECT_CAST(obj); P& map = (object.*_getter)(); return new ReverseMapIterator(_keyType, _keySize, _elementType, _elementSize, map.rbegin(), map.rend()); } virtual bool read( InputStream& is, osg::Object& obj ) { C& object = OBJECT_CAST(obj); unsigned int size = 0; P map; if ( is.isBinary() ) { is >> size; for ( unsigned int i=0; i> key >> value; map[key] = value; } (object.*_setter)( map ); } else if ( is.matchString(_name) ) { is >> size; if ( size>0 ) { is >> is.BEGIN_BRACKET; for ( unsigned int i=0; i> key >> value; map[key] = value; } is >> is.END_BRACKET; } (object.*_setter)( map ); } return true; } virtual bool write( OutputStream& os, const osg::Object& obj ) { const C& object = OBJECT_CAST(obj); const P& map = (object.*_constgetter)(); unsigned int size = (unsigned int)map.size(); if ( os.isBinary() ) { os << size; for ( ConstIterator itr=map.begin(); itr!=map.end(); ++itr ) { os << itr->first << itr->second; } } else if ( size>0 ) { os << os.PROPERTY((_name).c_str()) << size << os.BEGIN_BRACKET << std::endl; for ( ConstIterator itr=map.begin(); itr!=map.end(); ++itr ) { os << itr->first << itr->second; os << std::endl; } os << os.END_BRACKET << std::endl; } return true; } public: std::string _name; ConstGetter _constgetter; Getter _getter; Setter _setter; }; template class BitFlagsSerializer : public osgDB::TemplateSerializer

{ public: typedef TemplateSerializer

ParentType; typedef P (C::*Getter)() const; typedef void (C::*Setter)( P ); BitFlagsSerializer( 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( osgDB::InputStream& is, osg::Object& obj ) { C& object = OBJECT_CAST(obj); if ( is.isBinary() ) { if (is.getFileVersion()<123) { bool ok = false; is >> ok; //code from user serialized ensuring backwards-compatibility if ( !ok ) return true; } P mask; is >> mask; (object.*_setter)( mask ); } else { if ( !is.matchString(ParentType::_name) ) //code from user serialized ensuring backwards-compatibility return true; P mask=P(); std::string maskSetString; is >> maskSetString; osgDB::StringList maskList; osgDB::split( maskSetString, maskList, '|' ); for ( unsigned int i=0; i(obj); const P mask = (object.*_getter)(); bool ok = ParentType::_defaultValue!=static_cast

(mask); if ( os.isBinary() ) { if (os.getFileVersion()<123) { os << ok; if ( !ok ) return true; } os << (int)mask; //just write int value in binary case } else { if ( !ok ) return true; os << os.PROPERTY(ParentType::_name.c_str()); std::string maskString; const osgDB::IntLookup::ValueToString& v2sm = _lookup.getValueToString(); for( osgDB::IntLookup::ValueToString::const_iterator itr = v2sm.begin() ; itr != v2sm.end() ; itr++) if( (mask & itr->first) != 0 ) maskString += std::string(itr->second + "|"); if ( !maskString.size() ) maskString = std::string("NONE|"); maskString.erase(maskString.size()-1,1); os << maskString << std::endl; //remove last "|" } return true; } public: Getter _getter; Setter _setter; protected: osgDB::IntLookup _lookup; }; // 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_INT_SERIALIZER_NO_SET(PROP, DEF) \ wrapper->addSerializer( new osgDB::PropByValSerializer< MyClass, int >( \ #PROP, DEF, &MyClass::get##PROP, 0), 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_UINT_SERIALIZER_NO_SET(PROP, DEF) \ wrapper->addSerializer( new osgDB::PropByValSerializer< MyClass, unsigned int >( \ #PROP, DEF, &MyClass::get##PROP, 0), 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_VEC2B_SERIALIZER(PROP, DEF) \ wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::Vec2b >( \ #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_VEC2B ) #define ADD_VEC2UB_SERIALIZER(PROP, DEF) \ wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::Vec2ub >( \ #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_VEC2UB ) #define ADD_VEC2S_SERIALIZER(PROP, DEF) \ wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::Vec2s >( \ #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_VEC2S ) #define ADD_VEC2US_SERIALIZER(PROP, DEF) \ wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::Vec2us >( \ #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_VEC2US ) #define ADD_VEC2I_SERIALIZER(PROP, DEF) \ wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::Vec2i >( \ #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_VEC2I ) #define ADD_VEC2UI_SERIALIZER(PROP, DEF) \ wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::Vec2ui >( \ #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_VEC2UI ) #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_VEC3B_SERIALIZER(PROP, DEF) \ wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::Vec3b >( \ #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_VEC3B ) #define ADD_VEC3UB_SERIALIZER(PROP, DEF) \ wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::Vec3ub >( \ #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_VEC3UB ) #define ADD_VEC3S_SERIALIZER(PROP, DEF) \ wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::Vec3s >( \ #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_VEC3S ) #define ADD_VEC3US_SERIALIZER(PROP, DEF) \ wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::Vec3us >( \ #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_VEC3US ) #define ADD_VEC3I_SERIALIZER(PROP, DEF) \ wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::Vec3i >( \ #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_VEC3I ) #define ADD_VEC3UI_SERIALIZER(PROP, DEF) \ wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::Vec3ui >( \ #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_VEC3UI ) #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_VEC4B_SERIALIZER(PROP, DEF) \ wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::Vec4b >( \ #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_VEC4B ) #define ADD_VEC4UB_SERIALIZER(PROP, DEF) \ wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::Vec4ub >( \ #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_VEC4UB ) #define ADD_VEC4S_SERIALIZER(PROP, DEF) \ wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::Vec4s >( \ #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_VEC4S ) #define ADD_VEC4US_SERIALIZER(PROP, DEF) \ wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::Vec4us >( \ #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_VEC4US ) #define ADD_VEC4I_SERIALIZER(PROP, DEF) \ wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::Vec4i >( \ #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_VEC4I ) #define ADD_VEC4UI_SERIALIZER(PROP, DEF) \ wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::Vec4ui >( \ #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_VEC4UI ) #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_BOUNDINGBOXF_SERIALIZER(PROP, DEF) \ wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::BoundingBoxf >( \ #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_BOUNDINGBOXF ) #define ADD_BOUNDINGBOXD_SERIALIZER(PROP, DEF) \ wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::BoundingBoxd >( \ #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_BOUNDINGBOXD ) #define ADD_BOUNDINGSPHEREF_SERIALIZER(PROP, DEF) \ wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::BoundingSpheref >( \ #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_BOUNDINGSPHEREF ) #define ADD_BOUNDINGSPHERED_SERIALIZER(PROP, DEF) \ wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::BoundingSphered >( \ #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_BOUNDINGSPHERED ) #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_GLENUM_SERIALIZER_NO_SET(PROP, TYPE, DEF) \ wrapper->addSerializer( new osgDB::GLenumSerializer< MyClass, TYPE >( \ #PROP, DEF, &MyClass::get##PROP, 0), 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_OBJECT_SERIALIZER_NO_SET(PROP, TYPE, DEF) \ wrapper->addSerializer( new osgDB::ObjectSerializer< MyClass, TYPE >( \ #PROP, DEF, &MyClass::get##PROP, 0), 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 ADD_VECTOR_SERIALIZER(PROP, TYPE, ELEMENTTYPE, NUMELEMENTSONROW) \ wrapper->addSerializer( new osgDB::VectorSerializer< MyClass, TYPE >( \ #PROP, &MyClass::get##PROP, &MyClass::get##PROP, &MyClass::set##PROP, ELEMENTTYPE, NUMELEMENTSONROW), osgDB::BaseSerializer::RW_VECTOR ) #define ADD_ISAVECTOR_SERIALIZER(PROP, ELEMENTTYPE, NUMELEMENTSONROW) \ wrapper->addSerializer( new osgDB::IsAVectorSerializer< MyClass >( #PROP, ELEMENTTYPE, NUMELEMENTSONROW), osgDB::BaseSerializer::RW_VECTOR ) #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 BEGIN_ENUM_SERIALIZER_NO_SET(PROP, DEF) \ { typedef osgDB::EnumSerializer MySerializer; \ osg::ref_ptr serializer = new MySerializer( \ #PROP, MyClass::DEF, &MyClass::get##PROP, 0) #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); } /** defaults to uint bitfield type.*/ #define BEGIN_BITFLAGS_SERIALIZER(PROP, DEF) \ { typedef osgDB::BitFlagsSerializer MySerializer; \ osg::ref_ptr serializer = new MySerializer( \ #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP) #define BEGIN_UINT_BITFLAGS_SERIALIZER(PROP, DEF) \ { typedef osgDB::BitFlagsSerializer MySerializer; \ osg::ref_ptr serializer = new MySerializer( \ #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP) #define BEGIN_INT_BITFLAGS_SERIALIZER(PROP, DEF) \ { typedef osgDB::BitFlagsSerializer MySerializer; \ osg::ref_ptr serializer = new MySerializer( \ #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP) #define ADD_BITFLAG_VALUE(VALUE_NAME, VALUE) \ serializer->add(#VALUE_NAME, VALUE) #define END_BITFLAGS_SERIALIZER() \ wrapper->addSerializer(serializer.get(), osgDB::BaseSerializer::RW_INT); } // VERSION CONTROL OPERATORS #define UPDATE_TO_VERSION(VER) \ wrapper->setUpdatedVersion( (VER) ); #define UPDATE_TO_VERSION_SCOPED(VER) \ osgDB::UpdateWrapperVersionProxy uwvp(wrapper, (VER)); #define REMOVE_SERIALIZER(PROP) \ wrapper->markSerializerAsRemoved( #PROP ); #define ADD_MAP_SERIALIZER(PROP, TYPE, KEYTYPE, ELEMENTTYPE) \ wrapper->addSerializer( new osgDB::MapSerializer< MyClass, TYPE >( \ #PROP, &MyClass::get##PROP, &MyClass::get##PROP, &MyClass::set##PROP, KEYTYPE, ELEMENTTYPE), osgDB::BaseSerializer::RW_MAP ) #define ADD_METHOD_OBJECT( METHODNAME, METHODOBJECTCLASS ) wrapper->addMethodObject(METHODNAME, new METHODOBJECTCLASS()); #define ADD_METHOD(METHODNAME) \ { \ struct MethodCaller : public osgDB::MethodObject \ { \ virtual bool run(void* objectPtr, osg::Parameters&, osg::Parameters&) const \ { \ MyClass* obj = reinterpret_cast(objectPtr); \ obj->METHODNAME(); \ return true; \ } \ }; \ wrapper->addMethodObject(#METHODNAME, new MethodCaller()); \ } #define SET_USAGE(VALUE) wrapper->getLastSerializer()->setUsage(VALUE) } #endif