You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
985 lines
32 KiB
985 lines
32 KiB
/* -*-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 <osg/ref_ptr> |
|
#include <osg/Notify> |
|
#include <osg/Object> |
|
#include <osgDB/InputStream> |
|
#include <osgDB/OutputStream> |
|
|
|
#include <string> |
|
#include <sstream> |
|
#include <limits.h> |
|
|
|
namespace osgDB |
|
{ |
|
|
|
#ifndef OBJECT_CAST |
|
#define OBJECT_CAST static_cast |
|
#endif |
|
|
|
class IntLookup |
|
{ |
|
public: |
|
typedef int Value; |
|
typedef std::map<std::string, Value> StringToValue; |
|
typedef std::map<Value, std::string> 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].c_str() |
|
<< " 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<typename C> |
|
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<C&>(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<const C&>(obj); |
|
bool ok = (*_checker)(object); |
|
if ( os.isBinary() ) |
|
{ |
|
os << ok; |
|
if ( !ok ) return true; |
|
} |
|
else |
|
{ |
|
if ( !ok ) return true; |
|
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<typename P> |
|
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<typename C, typename P> |
|
class PropByValSerializer : public TemplateSerializer<P> |
|
{ |
|
public: |
|
typedef TemplateSerializer<P> 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<C&>(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<const C&>(obj); |
|
P value = (object.*_getter)(); |
|
if ( os.isBinary() ) |
|
{ |
|
os << value; |
|
} |
|
else if ( ParentType::_defaultValue!=value ) |
|
{ |
|
os << PROPERTY((ParentType::_name).c_str()); |
|
if ( _useHex ) os << std::hex; |
|
os << value; |
|
if ( _useHex ) os << std::dec; |
|
os << std::endl; |
|
} |
|
return true; |
|
} |
|
|
|
public: |
|
Getter _getter; |
|
Setter _setter; |
|
|
|
protected: |
|
bool _useHex; |
|
}; |
|
|
|
template<typename C, typename P> |
|
class PropByRefSerializer : public TemplateSerializer<P> |
|
{ |
|
public: |
|
typedef TemplateSerializer<P> 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<C&>(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<const C&>(obj); |
|
CP value = (object.*_getter)(); |
|
if ( os.isBinary() ) |
|
{ |
|
os << value; |
|
} |
|
else if ( ParentType::_defaultValue!=value ) |
|
{ |
|
os << PROPERTY((ParentType::_name).c_str()) << value << std::endl; |
|
} |
|
return true; |
|
} |
|
|
|
public: |
|
Getter _getter; |
|
Setter _setter; |
|
}; |
|
|
|
template<typename C> |
|
class MatrixSerializer : public TemplateSerializer<osg::Matrix> |
|
{ |
|
public: |
|
typedef TemplateSerializer<osg::Matrix> 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<C&>(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<const C&>(obj); |
|
const osg::Matrix& value = (object.*_getter)(); |
|
if ( os.isBinary() ) |
|
{ |
|
os << value; |
|
} |
|
else if ( ParentType::_defaultValue!=value ) |
|
{ |
|
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<typename C, typename P> |
|
class GLenumSerializer : public TemplateSerializer<P> |
|
{ |
|
public: |
|
typedef TemplateSerializer<P> 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<C&>(obj); |
|
if ( is.isBinary() ) |
|
{ |
|
GLenum value; is >> value; |
|
if ( ParentType::_defaultValue!=static_cast<P>(value) ) |
|
(object.*_setter)( static_cast<P>(value) ); |
|
} |
|
else if ( is.matchString(ParentType::_name) ) |
|
{ |
|
DEF_GLENUM(value); is >> value; |
|
(object.*_setter)( static_cast<P>(value.get()) ); |
|
} |
|
return true; |
|
} |
|
|
|
virtual bool write( OutputStream& os, const osg::Object& obj ) |
|
{ |
|
const C& object = OBJECT_CAST<const C&>(obj); |
|
const P value = (object.*_getter)(); |
|
if ( os.isBinary() ) |
|
{ |
|
os << static_cast<GLenum>(value); |
|
} |
|
else if ( ParentType::_defaultValue!=value ) |
|
{ |
|
os << PROPERTY((ParentType::_name).c_str()) << GLENUM(value) << std::endl; |
|
} |
|
return true; |
|
} |
|
|
|
public: |
|
Getter _getter; |
|
Setter _setter; |
|
}; |
|
|
|
template<typename C> |
|
class StringSerializer : public TemplateSerializer<std::string> |
|
{ |
|
public: |
|
typedef TemplateSerializer<std::string> 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<C&>(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<const C&>(obj); |
|
const std::string& value = (object.*_getter)(); |
|
if ( os.isBinary() ) |
|
{ |
|
os << value; |
|
} |
|
else if ( ParentType::_defaultValue!=value ) |
|
{ |
|
os << PROPERTY((ParentType::_name).c_str()); |
|
os.writeWrappedString( value ); |
|
os << std::endl; |
|
} |
|
return true; |
|
} |
|
|
|
public: |
|
Getter _getter; |
|
Setter _setter; |
|
}; |
|
|
|
template<typename C, typename P> |
|
class ObjectSerializer : public TemplateSerializer<P*> |
|
{ |
|
public: |
|
typedef TemplateSerializer<P*> 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<C&>(obj); |
|
bool hasObject = false; |
|
if ( is.isBinary() ) |
|
{ |
|
is >> hasObject; |
|
if ( hasObject ) |
|
{ |
|
P* value = dynamic_cast<P*>( is.readObject() ); |
|
if ( ParentType::_defaultValue!=value ) |
|
(object.*_setter)( value ); |
|
} |
|
} |
|
else if ( is.matchString(ParentType::_name) ) |
|
{ |
|
is >> hasObject; |
|
if ( hasObject ) |
|
{ |
|
is >> BEGIN_BRACKET; |
|
P* value = dynamic_cast<P*>( is.readObject() ); |
|
if ( ParentType::_defaultValue!=value ) |
|
(object.*_setter)( value ); |
|
is >> END_BRACKET; |
|
} |
|
} |
|
return true; |
|
} |
|
|
|
virtual bool write( OutputStream& os, const osg::Object& obj ) |
|
{ |
|
const C& object = OBJECT_CAST<const C&>(obj); |
|
const P* value = (object.*_getter)(); |
|
bool hasObject = (value!=NULL); |
|
if ( os.isBinary() ) |
|
{ |
|
os << hasObject; |
|
os.writeObject( value ); |
|
} |
|
else if ( ParentType::_defaultValue!=value ) |
|
{ |
|
os << PROPERTY((ParentType::_name).c_str()) << hasObject; |
|
if ( hasObject ) |
|
{ |
|
os << BEGIN_BRACKET << std::endl; |
|
os.writeObject( value ); |
|
os << END_BRACKET; |
|
} |
|
os << std::endl; |
|
} |
|
return true; |
|
} |
|
|
|
public: |
|
Getter _getter; |
|
Setter _setter; |
|
}; |
|
|
|
template<typename C, typename P> |
|
class ImageSerializer : public TemplateSerializer<P*> |
|
{ |
|
public: |
|
typedef TemplateSerializer<P*> 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<C&>(obj); |
|
bool hasObject = false; |
|
if ( is.isBinary() ) |
|
{ |
|
is >> hasObject; |
|
if ( hasObject ) |
|
{ |
|
P* value = dynamic_cast<P*>( is.readImage() ); |
|
if ( ParentType::_defaultValue!=value ) |
|
(object.*_setter)( value ); |
|
} |
|
} |
|
else if ( is.matchString(ParentType::_name) ) |
|
{ |
|
is >> hasObject; |
|
if ( hasObject ) |
|
{ |
|
is >> BEGIN_BRACKET; |
|
P* value = dynamic_cast<P*>( is.readImage() ); |
|
if ( ParentType::_defaultValue!=value ) |
|
(object.*_setter)( value ); |
|
is >> END_BRACKET; |
|
} |
|
} |
|
return true; |
|
} |
|
|
|
virtual bool write( OutputStream& os, const osg::Object& obj ) |
|
{ |
|
const C& object = OBJECT_CAST<const C&>(obj); |
|
const P* value = (object.*_getter)(); |
|
bool hasObject = (value!=NULL); |
|
if ( os.isBinary() ) |
|
{ |
|
os << hasObject; |
|
os.writeImage( value ); |
|
} |
|
else if ( ParentType::_defaultValue!=value ) |
|
{ |
|
os << PROPERTY((ParentType::_name).c_str()) << hasObject; |
|
if ( hasObject ) |
|
{ |
|
os << BEGIN_BRACKET << std::endl; |
|
os.writeImage( value ); |
|
os << END_BRACKET; |
|
} |
|
os << std::endl; |
|
} |
|
return true; |
|
} |
|
|
|
public: |
|
Getter _getter; |
|
Setter _setter; |
|
}; |
|
|
|
template<typename C, typename P, typename B> |
|
class EnumSerializer : public TemplateSerializer<P> |
|
{ |
|
public: |
|
typedef TemplateSerializer<P> 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<IntLookup::Value>(value)); } |
|
|
|
P getValue( const char* str ) |
|
{ return static_cast<P>(_lookup.getValue(str)); } |
|
|
|
const std::string& getString( P value ) |
|
{ return _lookup.getString(static_cast<IntLookup::Value>(value)); } |
|
|
|
virtual bool read( InputStream& is, osg::Object& obj ) |
|
{ |
|
C& object = OBJECT_CAST<C&>(obj); |
|
IntLookup::Value value; |
|
if ( is.isBinary() ) |
|
{ |
|
is >> value; |
|
if ( ParentType::_defaultValue!=static_cast<P>(value) ) |
|
(object.*_setter)( static_cast<P>(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<const C&>(obj); |
|
const P value = (object.*_getter)(); |
|
if ( os.isBinary() ) |
|
{ |
|
os << (IntLookup::Value)value; |
|
} |
|
else if ( ParentType::_defaultValue!=value ) |
|
{ |
|
os << PROPERTY((ParentType::_name).c_str()) << getString(value) << std::endl; |
|
} |
|
return true; |
|
} |
|
|
|
public: |
|
Getter _getter; |
|
Setter _setter; |
|
|
|
protected: |
|
IntLookup _lookup; |
|
}; |
|
|
|
|
|
template<typename C, typename P> |
|
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<C&>(obj); |
|
unsigned int size = 0; |
|
P list; |
|
if ( is.isBinary() ) |
|
{ |
|
is >> size; |
|
for ( unsigned int i=0; i<size; ++i ) |
|
{ |
|
ValueType value; |
|
is >> value; |
|
list.push_back( value ); |
|
} |
|
if ( size>0 ) (object.*_setter)( list ); |
|
} |
|
else if ( is.matchString(_name) ) |
|
{ |
|
is >> size; |
|
if ( size>0 ) is >> BEGIN_BRACKET; |
|
for ( unsigned int i=0; i<size; ++i ) |
|
{ |
|
ValueType value; |
|
is >> value; |
|
list.push_back( value ); |
|
} |
|
if ( size>0 ) |
|
{ |
|
is >> END_BRACKET; |
|
(object.*_setter)( list ); |
|
} |
|
} |
|
return true; |
|
} |
|
|
|
virtual bool write( OutputStream& os, const osg::Object& obj ) |
|
{ |
|
const C& object = OBJECT_CAST<const C&>(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 << PROPERTY((_name).c_str()) << size << BEGIN_BRACKET << std::endl; |
|
for ( ConstIterator itr=list.begin(); |
|
itr!=list.end(); ++itr ) |
|
{ |
|
os << (*itr); |
|
} |
|
os << std::endl; |
|
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<MyClass>( \ |
|
#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<MyClass, MyClass::PROP, void> MySerializer; \ |
|
osg::ref_ptr<MySerializer> serializer = new MySerializer( \ |
|
#PROP, MyClass::DEF, &MyClass::get##PROP, &MyClass::set##PROP) |
|
|
|
#define BEGIN_ENUM_SERIALIZER2(PROP, TYPE, DEF) \ |
|
{ typedef osgDB::EnumSerializer<MyClass, TYPE, void> MySerializer; \ |
|
osg::ref_ptr<MySerializer> serializer = new MySerializer( \ |
|
#PROP, MyClass::DEF, &MyClass::get##PROP, &MyClass::set##PROP) |
|
|
|
#define BEGIN_ENUM_SERIALIZER3(PROP, DEF) \ |
|
{ typedef osgDB::EnumSerializer<MyClass, MyClass::PROP, bool> MySerializer; \ |
|
osg::ref_ptr<MySerializer> serializer = new MySerializer( \ |
|
#PROP, MyClass::DEF, &MyClass::get##PROP, &MyClass::set##PROP) |
|
|
|
#define BEGIN_ENUM_SERIALIZER4(PROPERTIES_CLASS, PROP, DEF) \ |
|
{ typedef osgDB::EnumSerializer<MyClass, PROPERTIES_CLASS::PROP, void> MySerializer; \ |
|
osg::ref_ptr<MySerializer> 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
|
|
|