Introduced support for specifying whether a serializer supports different types of usage - one or more of READ_WRITE_PROPERTY, GET_PROPERTY and SET_PROPERTY.

git-svn-id: http://svn.openscenegraph.org/osg/OpenSceneGraph/trunk@14437 16af8721-9629-0410-8352-f15c8da7e697
This commit is contained in:
Robert Osfield 2014-09-05 11:05:43 +00:00
parent 21fc2fae8d
commit 9e9fe9b9c9
4 changed files with 103 additions and 51 deletions

View File

@ -81,6 +81,7 @@ public:
void addSerializer( BaseSerializer* s, BaseSerializer::Type t=BaseSerializer::RW_UNDEFINED ); void addSerializer( BaseSerializer* s, BaseSerializer::Type t=BaseSerializer::RW_UNDEFINED );
void markSerializerAsRemoved( const std::string& name ); void markSerializerAsRemoved( const std::string& name );
BaseSerializer* getLastSerializer() { return _serializers.empty() ? 0 : _serializers.back().get(); }
BaseSerializer* getSerializer( const std::string& name ); BaseSerializer* getSerializer( const std::string& name );
BaseSerializer* getSerializer( const std::string& name, BaseSerializer::Type& type); BaseSerializer* getSerializer( const std::string& name, BaseSerializer::Type& type);

View File

@ -139,7 +139,16 @@ public:
RW_VECTOR, RW_MAP RW_VECTOR, RW_MAP
}; };
BaseSerializer() : _firstVersion(0), _lastVersion(INT_MAX) {} 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 set(osg::Object& /*object*/, void* /*value*/) { return false; }
virtual bool get(const osg::Object& /*object*/, void* /*value*/) { return false; } virtual bool get(const osg::Object& /*object*/, void* /*value*/) { return false; }
@ -150,9 +159,25 @@ public:
virtual IntLookup* getIntLookup() { return 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: protected:
int _firstVersion; // Library version when the serializer is first introduced int _firstVersion; // Library version when the serializer is first introduced
int _lastVersion; // Library version when the serializer is last required. int _lastVersion; // Library version when the serializer is last required.
int _usage; // How the Serializer can be used.
}; };
template<typename C> template<typename C>
@ -164,7 +189,7 @@ public:
typedef bool (*Writer)( OutputStream&, const C& ); typedef bool (*Writer)( OutputStream&, const C& );
UserSerializer( const char* name, Checker cf, Reader rf, Writer wf ) UserSerializer( const char* name, Checker cf, Reader rf, Writer wf )
: BaseSerializer(), _name(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 ) virtual bool read( InputStream& is, osg::Object& obj )
{ {
@ -216,7 +241,7 @@ class TemplateSerializer : public BaseSerializer
public: public:
TemplateSerializer( const char* name, P def) TemplateSerializer( const char* name, P def)
: BaseSerializer(), _name(name), _defaultValue(def) {} : BaseSerializer(READ_WRITE_PROPERTY), _name(name), _defaultValue(def) {}
virtual bool read( InputStream& is, osg::Object& obj ) = 0; virtual bool read( InputStream& is, osg::Object& obj ) = 0;
virtual bool write( OutputStream& os, const osg::Object& obj ) = 0; virtual bool write( OutputStream& os, const osg::Object& obj ) = 0;
@ -235,8 +260,10 @@ public:
typedef P (C::*Getter)() const; typedef P (C::*Getter)() const;
typedef void (C::*Setter)( P ); typedef void (C::*Setter)( P );
PropByValSerializer( const char* name, P def, Getter gf, Setter sf, bool useHex=false ) PropByValSerializer( const char* name, P def, Getter gf, Setter sf, bool useHex=false ) : ParentType(name, def), _getter(gf), _setter(sf), _useHex(useHex)
: ParentType(name, def), _getter(gf), _setter(sf), _useHex(useHex) {} {
ParentType::setUsage( _getter!=0, _setter!=0);
}
virtual bool read( InputStream& is, osg::Object& obj ) virtual bool read( InputStream& is, osg::Object& obj )
{ {
@ -245,14 +272,14 @@ public:
if ( is.isBinary() ) if ( is.isBinary() )
{ {
is >> value; is >> value;
if (_setter!=0) (object.*_setter)( value ); (object.*_setter)( value );
} }
else if ( is.matchString(ParentType::_name) ) else if ( is.matchString(ParentType::_name) )
{ {
if ( _useHex ) is >> std::hex; if ( _useHex ) is >> std::hex;
is >> value; is >> value;
if ( _useHex ) is >> std::dec; if ( _useHex ) is >> std::dec;
if (_setter!=0) (object.*_setter)( value ); (object.*_setter)( value );
} }
return true; return true;
} }
@ -293,8 +320,10 @@ public:
typedef CP (C::*Getter)() const; typedef CP (C::*Getter)() const;
typedef void (C::*Setter)( CP ); typedef void (C::*Setter)( CP );
PropByRefSerializer( const char* name, CP def, Getter gf, Setter sf ) PropByRefSerializer( const char* name, CP def, Getter gf, Setter sf ) : ParentType(name, 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 ) virtual bool read( InputStream& is, osg::Object& obj )
{ {
@ -303,12 +332,12 @@ public:
if ( is.isBinary() ) if ( is.isBinary() )
{ {
is >> value; is >> value;
if (_setter!=0) (object.*_setter)( value ); (object.*_setter)( value );
} }
else if ( is.matchString(ParentType::_name) ) else if ( is.matchString(ParentType::_name) )
{ {
is >> value; is >> value;
if (_setter!=0) (object.*_setter)( value ); (object.*_setter)( value );
} }
return true; return true;
} }
@ -341,8 +370,10 @@ public:
typedef const osg::Matrix& (C::*Getter)() const; typedef const osg::Matrix& (C::*Getter)() const;
typedef void (C::*Setter)( const osg::Matrix& ); typedef void (C::*Setter)( const osg::Matrix& );
MatrixSerializer( const char* name, const osg::Matrix& def, Getter gf, Setter sf ) MatrixSerializer( const char* name, const osg::Matrix& def, Getter gf, Setter sf ) : ParentType(name, 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 ) virtual bool read( InputStream& is, osg::Object& obj )
{ {
@ -351,12 +382,12 @@ public:
if ( is.isBinary() ) if ( is.isBinary() )
{ {
readMatrixImplementation( is, value ); readMatrixImplementation( is, value );
if (_setter!=0) (object.*_setter)( value ); (object.*_setter)( value );
} }
else if ( is.matchString(ParentType::_name) ) else if ( is.matchString(ParentType::_name) )
{ {
readMatrixImplementation( is, value ); readMatrixImplementation( is, value );
if (_setter!=0) (object.*_setter)( value ); (object.*_setter)( value );
} }
return true; return true;
} }
@ -409,8 +440,10 @@ public:
typedef P (C::*Getter)() const; typedef P (C::*Getter)() const;
typedef void (C::*Setter)( P ); typedef void (C::*Setter)( P );
GLenumSerializer( const char* name, P def, Getter gf, Setter sf ) GLenumSerializer( const char* name, P def, Getter gf, Setter sf ) : ParentType(name, 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 ) virtual bool read( InputStream& is, osg::Object& obj )
{ {
@ -418,12 +451,12 @@ public:
if ( is.isBinary() ) if ( is.isBinary() )
{ {
GLenum value; is >> value; GLenum value; is >> value;
if (_setter!=0) (object.*_setter)( static_cast<P>(value) ); (object.*_setter)( static_cast<P>(value) );
} }
else if ( is.matchString(ParentType::_name) ) else if ( is.matchString(ParentType::_name) )
{ {
DEF_GLENUM(value); is >> value; DEF_GLENUM(value); is >> value;
if (_setter!=0) (object.*_setter)( static_cast<P>(value.get()) ); (object.*_setter)( static_cast<P>(value.get()) );
} }
return true; return true;
} }
@ -456,8 +489,10 @@ public:
typedef const std::string& (C::*Getter)() const; typedef const std::string& (C::*Getter)() const;
typedef void (C::*Setter)( const std::string& ); typedef void (C::*Setter)( const std::string& );
StringSerializer( const char* name, const std::string& def, Getter gf, Setter sf ) StringSerializer( const char* name, const std::string& def, Getter gf, Setter sf ) : ParentType(name, 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 ) virtual bool read( InputStream& is, osg::Object& obj )
{ {
@ -466,7 +501,7 @@ public:
if ( is.isBinary() ) if ( is.isBinary() )
{ {
is >> value; is >> value;
if (_setter!=0) (object.*_setter)( value ); (object.*_setter)( value );
} }
else if ( is.matchString(ParentType::_name) ) else if ( is.matchString(ParentType::_name) )
{ {
@ -507,11 +542,13 @@ public:
typedef const P* (C::*Getter)() const; typedef const P* (C::*Getter)() const;
typedef void (C::*Setter)( P* ); typedef void (C::*Setter)( P* );
ObjectSerializer( const char* name, P* def, Getter gf, Setter sf ) ObjectSerializer( const char* name, P* def, Getter gf, Setter sf ) : ParentType(name, 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) { if (_setter!=0) { C& object = OBJECT_CAST<C&>(obj); (object.*_setter)( *(reinterpret_cast<P**>(value)) ); return true; } else return false; } virtual bool set(osg::Object& obj, void* value) { C& object = OBJECT_CAST<C&>(obj); (object.*_setter)( *(reinterpret_cast<P**>(value)) ); return true; }
virtual bool get(const osg::Object& obj, void* value) { if (_getter!=0) { const C& object = OBJECT_CAST<const C&>(obj);*(reinterpret_cast<const P**>(value )) = (object.*_getter)(); return true; } else return false;} virtual bool get(const osg::Object& obj, void* value) { const C& object = OBJECT_CAST<const C&>(obj);*(reinterpret_cast<const P**>(value )) = (object.*_getter)(); return true; }
virtual bool read( InputStream& is, osg::Object& obj ) virtual bool read( InputStream& is, osg::Object& obj )
{ {
@ -523,7 +560,7 @@ public:
if ( hasObject ) if ( hasObject )
{ {
P* value = dynamic_cast<P*>( is.readObject() ); P* value = dynamic_cast<P*>( is.readObject() );
if (_setter!=0) (object.*_setter)( value ); (object.*_setter)( value );
} }
} }
else if ( is.matchString(ParentType::_name) ) else if ( is.matchString(ParentType::_name) )
@ -533,7 +570,7 @@ public:
{ {
is >> is.BEGIN_BRACKET; is >> is.BEGIN_BRACKET;
P* value = dynamic_cast<P*>( is.readObject() ); P* value = dynamic_cast<P*>( is.readObject() );
if (_setter!=0) (object.*_setter)( value ); (object.*_setter)( value );
is >> is.END_BRACKET; is >> is.END_BRACKET;
} }
} }
@ -577,8 +614,11 @@ public:
typedef const P* (C::*Getter)() const; typedef const P* (C::*Getter)() const;
typedef void (C::*Setter)( P* ); typedef void (C::*Setter)( P* );
ImageSerializer( const char* name, P* def, Getter gf, Setter sf ) ImageSerializer( const char* name, P* def, Getter gf, Setter sf ):
: ParentType(name, 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<C&>(obj); (object.*_setter)( *(reinterpret_cast<P**>(value)) ); return true; } virtual bool set(osg::Object& obj, void* value) { C& object = OBJECT_CAST<C&>(obj); (object.*_setter)( *(reinterpret_cast<P**>(value)) ); return true; }
virtual bool get(const osg::Object& obj, void* value) { const C& object = OBJECT_CAST<const C&>(obj);*(reinterpret_cast<const P**>(value )) = (object.*_getter)(); return true; } virtual bool get(const osg::Object& obj, void* value) { const C& object = OBJECT_CAST<const C&>(obj);*(reinterpret_cast<const P**>(value )) = (object.*_getter)(); return true; }
@ -593,7 +633,7 @@ public:
if ( hasObject ) if ( hasObject )
{ {
P* value = dynamic_cast<P*>( is.readImage() ); P* value = dynamic_cast<P*>( is.readImage() );
if (_setter!=0) (object.*_setter)( value ); (object.*_setter)( value );
} }
} }
else if ( is.matchString(ParentType::_name) ) else if ( is.matchString(ParentType::_name) )
@ -603,7 +643,7 @@ public:
{ {
is >> is.BEGIN_BRACKET; is >> is.BEGIN_BRACKET;
P* value = dynamic_cast<P*>( is.readImage() ); P* value = dynamic_cast<P*>( is.readImage() );
if (_setter!=0) (object.*_setter)( value ); (object.*_setter)( value );
is >> is.END_BRACKET; is >> is.END_BRACKET;
} }
} }
@ -647,8 +687,10 @@ public:
typedef P (C::*Getter)() const; typedef P (C::*Getter)() const;
typedef B (C::*Setter)( P ); typedef B (C::*Setter)( P );
EnumSerializer( const char* name, P def, Getter gf, Setter sf ) EnumSerializer( const char* name, P def, Getter gf, Setter sf ) : ParentType(name, def), _getter(gf), _setter(sf)
: ParentType(name, def), _getter(gf), _setter(sf) {} {
ParentType::setUsage( _getter!=0, _setter!=0);
}
virtual IntLookup* getIntLookup() { return &_lookup; } virtual IntLookup* getIntLookup() { return &_lookup; }
@ -668,12 +710,12 @@ public:
if ( is.isBinary() ) if ( is.isBinary() )
{ {
is >> value; is >> value;
if (_setter!=0) (object.*_setter)( static_cast<P>(value) ); (object.*_setter)( static_cast<P>(value) );
} }
else if ( is.matchString(ParentType::_name) ) else if ( is.matchString(ParentType::_name) )
{ {
std::string str; is >> str; std::string str; is >> str;
if (_setter!=0) (object.*_setter)( getValue(str.c_str()) ); (object.*_setter)( getValue(str.c_str()) );
} }
return true; return true;
} }
@ -711,8 +753,9 @@ public:
typedef const P& (C::*Getter)() const; typedef const P& (C::*Getter)() const;
typedef void (C::*Setter)( const P& ); typedef void (C::*Setter)( const P& );
ListSerializer( const char* name, Getter gf, Setter sf ) ListSerializer( const char* name, Getter gf, Setter sf ):
: _name(name), _getter(gf), _setter(sf) {} BaseSerializer(READ_WRITE_PROPERTY),
_name(name), _getter(gf), _setter(sf) {}
virtual const std::string& getName() const { return _name; } virtual const std::string& getName() const { return _name; }
@ -790,6 +833,7 @@ class VectorBaseSerializer : public BaseSerializer
public: public:
VectorBaseSerializer(BaseSerializer::Type elementType, unsigned int elementSize): VectorBaseSerializer(BaseSerializer::Type elementType, unsigned int elementSize):
BaseSerializer(READ_WRITE_PROPERTY|GET_SET_PROPERTY),
_elementType(elementType),_elementSize(elementSize) {} _elementType(elementType),_elementSize(elementSize) {}
Type getElementType() const { return _elementType; } Type getElementType() const { return _elementType; }
@ -1170,6 +1214,7 @@ class MapBaseSerializer : public BaseSerializer
public: public:
MapBaseSerializer(BaseSerializer::Type keyType, unsigned int keySize, BaseSerializer::Type elementType, unsigned int elementSize): MapBaseSerializer(BaseSerializer::Type keyType, unsigned int keySize, BaseSerializer::Type elementType, unsigned int elementSize):
BaseSerializer(READ_WRITE_PROPERTY|GET_SET_PROPERTY),
_keyType(keyType), _keySize(keySize), _keyType(keyType), _keySize(keySize),
_elementType(elementType),_elementSize(elementSize) {} _elementType(elementType),_elementSize(elementSize) {}
@ -1727,6 +1772,9 @@ public:
wrapper->addMethodObject(#METHODNAME, new MethodCaller()); \ wrapper->addMethodObject(#METHODNAME, new MethodCaller()); \
} }
#define SET_USAGE(VALUE) wrapper->getLastSerializer()->setUsage(VALUE)
} }
#endif #endif

View File

@ -199,7 +199,8 @@ bool ObjectWrapper::read( InputStream& is, osg::Object& obj )
{ {
BaseSerializer* serializer = itr->get(); BaseSerializer* serializer = itr->get();
if ( serializer->_firstVersion <= inputVersion && if ( serializer->_firstVersion <= inputVersion &&
inputVersion <= serializer->_lastVersion ) inputVersion <= serializer->_lastVersion &&
serializer->supportsReadWrite())
{ {
if ( !serializer->read(is, obj) ) if ( !serializer->read(is, obj) )
{ {
@ -233,7 +234,8 @@ bool ObjectWrapper::write( OutputStream& os, const osg::Object& obj )
{ {
BaseSerializer* serializer = itr->get(); BaseSerializer* serializer = itr->get();
if ( serializer->_firstVersion <= outputVersion && if ( serializer->_firstVersion <= outputVersion &&
outputVersion <= serializer->_lastVersion ) outputVersion <= serializer->_lastVersion &&
serializer->supportsReadWrite())
{ {
if ( !serializer->write(os, obj) ) if ( !serializer->write(os, obj) )
{ {
@ -295,16 +297,17 @@ bool ObjectWrapper::readSchema( const StringList& properties, const TypeList& )
void ObjectWrapper::writeSchema( StringList& properties, TypeList& types ) void ObjectWrapper::writeSchema( StringList& properties, TypeList& types )
{ {
for ( SerializerList::iterator itr=_serializers.begin(); SerializerList::iterator sitr = _serializers.begin();
itr!=_serializers.end(); ++itr ) TypeList::iterator titr = _typeList.begin();
while(sitr!=_serializers.end() && titr!=_typeList.end())
{ {
properties.push_back( (*itr)->getName() ); if ((*sitr)->supportsReadWrite())
} {
properties.push_back( (*sitr)->getName() );
for ( TypeList::iterator itr=_typeList.begin(); types.push_back( (*titr) );
itr!=_typeList.end(); ++itr ) }
{ ++sitr;
types.push_back( (*itr) ); ++titr;
} }
} }