From Wang Rui, new native binary/ascii format infrastructure and wrappers.
From Robert Osfield, refactor of Wang Rui's original osg2 into 3 parts - parts placed into osgDB, the ReaderWriter placed into src/osg/Plugin/osg and wrappers into src/osgWrappers/serializers/osg
This commit is contained in:
127
include/osgDB/DataTypes
Normal file
127
include/osgDB/DataTypes
Normal file
@@ -0,0 +1,127 @@
|
||||
/* -*-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 H_DATATYPES
|
||||
#define H_DATATYPES
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace osgDB
|
||||
{
|
||||
|
||||
// OSG Header (MD5, 16Bit)
|
||||
#define OSG_HEADER_LOW 0x6C910EA1
|
||||
#define OSG_HEADER_HIGH 0x1AFB4545
|
||||
|
||||
// Reader/writer plugin version
|
||||
#define PLUGIN_VERSION 2
|
||||
|
||||
#define BOOL_SIZE 1
|
||||
#define CHAR_SIZE 1
|
||||
#define SHORT_SIZE 2
|
||||
#define INT_SIZE 4
|
||||
#define LONG_SIZE 4
|
||||
#define FLOAT_SIZE 4
|
||||
#define DOUBLE_SIZE 8
|
||||
#define GLENUM_SIZE 4
|
||||
|
||||
#define ID_BYTE_ARRAY 0
|
||||
#define ID_UBYTE_ARRAY 1
|
||||
#define ID_SHORT_ARRAY 2
|
||||
#define ID_USHORT_ARRAY 3
|
||||
#define ID_INT_ARRAY 4
|
||||
#define ID_UINT_ARRAY 5
|
||||
#define ID_FLOAT_ARRAY 6
|
||||
#define ID_DOUBLE_ARRAY 7
|
||||
#define ID_VEC2B_ARRAY 8
|
||||
#define ID_VEC3B_ARRAY 9
|
||||
#define ID_VEC4B_ARRAY 10
|
||||
#define ID_VEC4UB_ARRAY 11
|
||||
#define ID_VEC2S_ARRAY 12
|
||||
#define ID_VEC3S_ARRAY 13
|
||||
#define ID_VEC4S_ARRAY 14
|
||||
#define ID_VEC2_ARRAY 15
|
||||
#define ID_VEC3_ARRAY 16
|
||||
#define ID_VEC4_ARRAY 17
|
||||
#define ID_VEC2D_ARRAY 18
|
||||
#define ID_VEC3D_ARRAY 19
|
||||
#define ID_VEC4D_ARRAY 20
|
||||
|
||||
#define ID_DRAWARRAYS 50
|
||||
#define ID_DRAWARRAY_LENGTH 51
|
||||
#define ID_DRAWELEMENTS_UBYTE 52
|
||||
#define ID_DRAWELEMENTS_USHORT 53
|
||||
#define ID_DRAWELEMENTS_UINT 54
|
||||
|
||||
// Used by BEGIN_BRACKET and END_BRACKET
|
||||
#define INDENT_VALUE 2
|
||||
|
||||
// Used by the writeImage/readImage parameter
|
||||
#define IMAGE_INLINE_DATA 0
|
||||
#define IMAGE_INLINE_FILE 1
|
||||
#define IMAGE_EXTERNAL 2
|
||||
#define IMAGE_WRITE_OUT 3
|
||||
|
||||
struct ObjectGLenum
|
||||
{
|
||||
ObjectGLenum( GLenum value=0 ) : _value(value) {}
|
||||
ObjectGLenum( const ObjectGLenum& copy ) : _value(copy._value) {}
|
||||
void set( GLenum e ) { _value = e; }
|
||||
GLenum get() const { return _value; }
|
||||
GLenum _value;
|
||||
};
|
||||
#define GLENUM(value) osgDB::ObjectGLenum(value)
|
||||
#define DEF_GLENUM(var) osgDB::ObjectGLenum var;
|
||||
|
||||
struct ObjectProperty
|
||||
{
|
||||
ObjectProperty( const char* name, int value=0, bool useMap=false )
|
||||
: _name(name), _value(value), _mapProperty(useMap) {}
|
||||
|
||||
ObjectProperty( const ObjectProperty& copy )
|
||||
: _name(copy._name), _value(copy._value), _mapProperty(copy._mapProperty) {}
|
||||
|
||||
ObjectProperty& proto( const char* name )
|
||||
{ _name = name; return *this; }
|
||||
|
||||
void set( int v ) { _value = v; }
|
||||
int get() const { return _value; }
|
||||
|
||||
std::string _name;
|
||||
int _value;
|
||||
bool _mapProperty;
|
||||
};
|
||||
static ObjectProperty defaultProp("");
|
||||
|
||||
#define PROPERTY(name) defaultProp.proto(name)
|
||||
#define MAPPEE(pairName, value) osgDB::ObjectProperty(#pairName, value, true)
|
||||
#define DEF_PROPERTY(name, var) osgDB::ObjectProperty var(name);
|
||||
#define DEF_MAPPEE(pairName, var) osgDB::ObjectProperty var(#pairName, 0, true);
|
||||
|
||||
struct ObjectMark
|
||||
{
|
||||
ObjectMark( const char* name, int delta=0 )
|
||||
: _name(name), _indentDelta(delta) {}
|
||||
|
||||
ObjectMark( const ObjectMark& copy )
|
||||
: _name(copy._name), _indentDelta(copy._indentDelta) {}
|
||||
|
||||
std::string _name;
|
||||
int _indentDelta;
|
||||
};
|
||||
static ObjectMark BEGIN_BRACKET("{", +INDENT_VALUE);
|
||||
static ObjectMark END_BRACKET ("}", -INDENT_VALUE);
|
||||
|
||||
}
|
||||
#endif
|
||||
@@ -79,6 +79,44 @@ class OSGDB_EXPORT DotOsgWrapper : public osg::Referenced
|
||||
ReadWriteMode _readWriteMode;
|
||||
};
|
||||
|
||||
/** Proxy class for automatic registration of DotOsgWrappers with the Registry.*/
|
||||
class RegisterDotOsgWrapperProxy
|
||||
{
|
||||
public:
|
||||
|
||||
RegisterDotOsgWrapperProxy(osg::Object* proto,
|
||||
const std::string& name,
|
||||
const std::string& associates,
|
||||
DotOsgWrapper::ReadFunc readFunc,
|
||||
DotOsgWrapper::WriteFunc writeFunc,
|
||||
DotOsgWrapper::ReadWriteMode readWriteMode=DotOsgWrapper::READ_AND_WRITE);
|
||||
|
||||
~RegisterDotOsgWrapperProxy();
|
||||
|
||||
protected:
|
||||
osg::ref_ptr<DotOsgWrapper> _wrapper;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
class TemplateRegisterDotOsgWrapperProxy : public RegisterDotOsgWrapperProxy, public T
|
||||
{
|
||||
public:
|
||||
|
||||
TemplateRegisterDotOsgWrapperProxy(osg::Object* proto,
|
||||
const std::string& name,
|
||||
const std::string& associates,
|
||||
DotOsgWrapper::ReadFunc readFunc,
|
||||
DotOsgWrapper::WriteFunc writeFunc,
|
||||
DotOsgWrapper::ReadWriteMode readWriteMode=DotOsgWrapper::READ_AND_WRITE):
|
||||
RegisterDotOsgWrapperProxy(proto, name, associates, readFunc, writeFunc, readWriteMode) {}
|
||||
|
||||
};
|
||||
|
||||
|
||||
#define REGISTER_DOTOSGWRAPPER(classname) \
|
||||
extern "C" void dotosgwrapper_##classname(void) {} \
|
||||
static osgDB::RegisterDotOsgWrapperProxy dotosgwrapper_proxy_##classname
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
438
include/osgDB/InputStream
Normal file
438
include/osgDB/InputStream
Normal file
@@ -0,0 +1,438 @@
|
||||
/* -*-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 H_INPUTSTREAM
|
||||
#define H_INPUTSTREAM
|
||||
|
||||
#include <osg/Endian>
|
||||
#include <osg/Vec2>
|
||||
#include <osg/Vec3>
|
||||
#include <osg/Vec4>
|
||||
#include <osg/Quat>
|
||||
#include <osg/Matrix>
|
||||
#include <osg/Array>
|
||||
#include <osg/PrimitiveSet>
|
||||
#include <osgDB/ReaderWriter>
|
||||
#include <osgDB/DataTypes>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
namespace osgDB
|
||||
{
|
||||
|
||||
class InputException
|
||||
{
|
||||
public:
|
||||
InputException( const std::string& field, const std::string& err )
|
||||
: _field(field), _error(err) {}
|
||||
|
||||
const std::string& getField() const { return _field; }
|
||||
const std::string& getError() const { return _error; }
|
||||
|
||||
protected:
|
||||
std::string _field;
|
||||
std::string _error;
|
||||
};
|
||||
|
||||
class InputStream
|
||||
{
|
||||
public:
|
||||
typedef std::map< unsigned int, osg::ref_ptr<osg::Array> > ArrayMap;
|
||||
typedef std::map< unsigned int, osg::ref_ptr<osg::Object> > IdentifierMap;
|
||||
|
||||
enum ReadMode
|
||||
{
|
||||
READ_BINARY = 0,
|
||||
READ_ASCII
|
||||
};
|
||||
|
||||
enum ReadType
|
||||
{
|
||||
READ_UNKNOWN = 0,
|
||||
READ_SCENE,
|
||||
READ_IMAGE
|
||||
};
|
||||
|
||||
InputStream( std::istream* istream, const osgDB::Options* options );
|
||||
virtual ~InputStream();
|
||||
|
||||
bool isBinary() const { return _readMode==READ_BINARY; }
|
||||
bool getUseFloatMatrix() const { return _useFloatMatrix; }
|
||||
|
||||
// Serialization related functions
|
||||
inline InputStream& operator>>( bool& b );
|
||||
inline InputStream& operator>>( char& c );
|
||||
inline InputStream& operator>>( signed char& c );
|
||||
inline InputStream& operator>>( unsigned char& c );
|
||||
inline InputStream& operator>>( short& s );
|
||||
inline InputStream& operator>>( unsigned short& s );
|
||||
inline InputStream& operator>>( int& i );
|
||||
inline InputStream& operator>>( unsigned int& i );
|
||||
inline InputStream& operator>>( long& l );
|
||||
inline InputStream& operator>>( unsigned long& l );
|
||||
inline InputStream& operator>>( float& f );
|
||||
inline InputStream& operator>>( double& d );
|
||||
inline InputStream& operator>>( std::string& s );
|
||||
inline InputStream& operator>>( std::istream& (*fn)(std::istream&) );
|
||||
inline InputStream& operator>>( std::ios_base& (*fn)(std::ios_base&) );
|
||||
|
||||
InputStream& operator>>( osg::Vec2b& v );
|
||||
InputStream& operator>>( osg::Vec3b& v );
|
||||
InputStream& operator>>( osg::Vec4b& v );
|
||||
InputStream& operator>>( osg::Vec4ub& v );
|
||||
InputStream& operator>>( osg::Vec2s& v );
|
||||
InputStream& operator>>( osg::Vec3s& v );
|
||||
InputStream& operator>>( osg::Vec4s& v );
|
||||
InputStream& operator>>( osg::Vec2f& v );
|
||||
InputStream& operator>>( osg::Vec3f& v );
|
||||
InputStream& operator>>( osg::Vec4f& v );
|
||||
InputStream& operator>>( osg::Vec2d& v );
|
||||
InputStream& operator>>( osg::Vec3d& v );
|
||||
InputStream& operator>>( osg::Vec4d& v );
|
||||
InputStream& operator>>( osg::Quat& q );
|
||||
InputStream& operator>>( osg::Plane& p );
|
||||
InputStream& operator>>( osg::Matrixf& mat );
|
||||
InputStream& operator>>( osg::Matrixd& mat );
|
||||
|
||||
InputStream& operator>>( osg::Array*& a ) { a = readArray(); return *this; }
|
||||
InputStream& operator>>( osg::Image*& img ) { img = readImage(); return *this; }
|
||||
InputStream& operator>>( osg::PrimitiveSet*& p ) { p = readPrimitiveSet(); return *this; }
|
||||
InputStream& operator>>( osg::Object*& obj ) { obj = readObject(); return *this; }
|
||||
|
||||
InputStream& operator>>( osg::ref_ptr<osg::Array>& ptr ) { ptr = readArray(); return *this; }
|
||||
InputStream& operator>>( osg::ref_ptr<osg::Image>& ptr ) { ptr = readImage(); return *this; }
|
||||
InputStream& operator>>( osg::ref_ptr<osg::PrimitiveSet>& ptr ) { ptr = readPrimitiveSet(); return *this; }
|
||||
|
||||
template<typename T> InputStream& operator>>( osg::ref_ptr<T>& ptr )
|
||||
{ ptr = static_cast<T*>(readObject()); return *this; }
|
||||
|
||||
InputStream& operator>>( ObjectGLenum& value );
|
||||
InputStream& operator>>( ObjectProperty& prop );
|
||||
InputStream& operator>>( ObjectMark& mark );
|
||||
|
||||
// Convenient methods for reading
|
||||
inline bool matchString( const std::string& str );
|
||||
inline void advanceToCurrentEndBracket();
|
||||
inline void readWrappedString( std::string& str );
|
||||
inline void readCharArray( char* s, unsigned int size );
|
||||
|
||||
// Global reading functions
|
||||
osg::Array* readArray();
|
||||
osg::PrimitiveSet* readPrimitiveSet();
|
||||
osg::Image* readImage();
|
||||
osg::Object* readObject( osg::Object* existingObj=0 );
|
||||
|
||||
ReadType start();
|
||||
void decompress();
|
||||
|
||||
// Schema handlers
|
||||
void readSchema( std::istream& fin );
|
||||
void resetSchema();
|
||||
|
||||
protected:
|
||||
inline void checkStream() const;
|
||||
void setWrapperSchema( const std::string& name, const std::string& properties );
|
||||
|
||||
template<typename T>
|
||||
void readArrayImplementation( T* a, int readSize, bool useByteSwap=false );
|
||||
|
||||
ArrayMap _arrayMap;
|
||||
IdentifierMap _identifierMap;
|
||||
|
||||
ReadMode _readMode;
|
||||
int _byteSwap;
|
||||
bool _useFloatMatrix;
|
||||
std::string _currentField;
|
||||
std::istream* _in;
|
||||
};
|
||||
|
||||
// INLINE METHODS
|
||||
|
||||
InputStream& InputStream::operator>>( bool& b )
|
||||
{
|
||||
if ( isBinary() )
|
||||
{
|
||||
char c = 0;
|
||||
_in->read( &c, CHAR_SIZE ); checkStream();
|
||||
b = (c!=0);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string boolString;
|
||||
*_in >> boolString; checkStream();
|
||||
if ( boolString=="TRUE" ) b = true;
|
||||
else b = false;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
InputStream& InputStream::operator>>( char& c )
|
||||
{
|
||||
if ( isBinary() )
|
||||
{
|
||||
_in->read( &c, CHAR_SIZE ); checkStream();
|
||||
}
|
||||
else
|
||||
{
|
||||
short s = 0;
|
||||
*_in >> s; checkStream();
|
||||
c = (char)s;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
InputStream& InputStream::operator>>( signed char& c )
|
||||
{
|
||||
if ( isBinary() )
|
||||
{
|
||||
_in->read( (char*)&c, CHAR_SIZE ); checkStream();
|
||||
}
|
||||
else
|
||||
{
|
||||
short s = 0;
|
||||
*_in >> s; checkStream();
|
||||
c = (signed char)s;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
InputStream& InputStream::operator>>( unsigned char& c )
|
||||
{
|
||||
if ( isBinary() )
|
||||
{
|
||||
_in->read( (char*)&c, CHAR_SIZE ); checkStream();
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned short s = 0;
|
||||
*_in >> s; checkStream();
|
||||
c = (unsigned char)s;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
InputStream& InputStream::operator>>( short& s )
|
||||
{
|
||||
if ( isBinary() )
|
||||
{
|
||||
_in->read( (char*)&s, SHORT_SIZE ); checkStream();
|
||||
if ( _byteSwap ) osg::swapBytes( (char*)&s, SHORT_SIZE );
|
||||
}
|
||||
else
|
||||
{
|
||||
*_in >> s; checkStream();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
InputStream& InputStream::operator>>( unsigned short& s )
|
||||
{
|
||||
if ( isBinary() )
|
||||
{
|
||||
_in->read( (char*)&s, SHORT_SIZE ); checkStream();
|
||||
if ( _byteSwap ) osg::swapBytes( (char*)&s, SHORT_SIZE );
|
||||
}
|
||||
else
|
||||
{
|
||||
*_in >> s; checkStream();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
InputStream& InputStream::operator>>( int& i )
|
||||
{
|
||||
if ( isBinary() )
|
||||
{
|
||||
_in->read( (char*)&i, INT_SIZE ); checkStream();
|
||||
if ( _byteSwap ) osg::swapBytes( (char*)&i, INT_SIZE );
|
||||
}
|
||||
else
|
||||
{
|
||||
*_in >> i; checkStream();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
InputStream& InputStream::operator>>( unsigned int& i )
|
||||
{
|
||||
if ( isBinary() )
|
||||
{
|
||||
_in->read( (char*)&i, INT_SIZE ); checkStream();
|
||||
if ( _byteSwap ) osg::swapBytes( (char*)&i, INT_SIZE );
|
||||
}
|
||||
else
|
||||
{
|
||||
*_in >> i; checkStream();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
InputStream& InputStream::operator>>( long& l )
|
||||
{
|
||||
if ( isBinary() )
|
||||
{
|
||||
_in->read( (char*)&l, LONG_SIZE ); checkStream();
|
||||
if ( _byteSwap ) osg::swapBytes( (char*)&l, LONG_SIZE );
|
||||
}
|
||||
else
|
||||
{
|
||||
*_in >> l; checkStream();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
InputStream& InputStream::operator>>( unsigned long& l )
|
||||
{
|
||||
if ( isBinary() )
|
||||
{
|
||||
_in->read( (char*)&l, LONG_SIZE ); checkStream();
|
||||
if ( _byteSwap ) osg::swapBytes( (char*)&l, LONG_SIZE );
|
||||
}
|
||||
else
|
||||
{
|
||||
*_in >> l; checkStream();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
InputStream& InputStream::operator>>( float& f )
|
||||
{
|
||||
if ( isBinary() )
|
||||
{
|
||||
_in->read( (char*)&f, FLOAT_SIZE ); checkStream();
|
||||
if ( _byteSwap ) osg::swapBytes( (char*)&f, FLOAT_SIZE );
|
||||
}
|
||||
else
|
||||
{
|
||||
*_in >> f; checkStream();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
InputStream& InputStream::operator>>( double& d )
|
||||
{
|
||||
if ( isBinary() )
|
||||
{
|
||||
_in->read( (char*)&d, DOUBLE_SIZE ); checkStream();
|
||||
if ( _byteSwap ) osg::swapBytes( (char*)&d, DOUBLE_SIZE );
|
||||
}
|
||||
else
|
||||
{
|
||||
*_in >> d; checkStream();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
InputStream& InputStream::operator>>( std::string& s )
|
||||
{
|
||||
if ( isBinary() )
|
||||
{
|
||||
int size = 0; *this >> size;
|
||||
if ( size )
|
||||
{
|
||||
s.resize( size );
|
||||
_in->read( (char*)s.c_str(), size ); checkStream();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*_in >> s; checkStream();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
InputStream& InputStream::operator>>( std::istream& (*fn)(std::istream&) )
|
||||
{
|
||||
if ( !isBinary() ) *_in >> fn;
|
||||
return *this;
|
||||
}
|
||||
|
||||
InputStream& InputStream::operator>>( std::ios_base& (*fn)(std::ios_base&) )
|
||||
{
|
||||
if ( !isBinary() ) *_in >> fn;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool InputStream::matchString( const std::string& str )
|
||||
{
|
||||
if ( !isBinary() )
|
||||
{
|
||||
std::string s;
|
||||
*_in >> s; checkStream();
|
||||
if ( s==str ) return true;
|
||||
else _in->seekg( -(int)(s.length()), std::ios::cur );
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void InputStream::advanceToCurrentEndBracket()
|
||||
{
|
||||
if ( isBinary() )
|
||||
return;
|
||||
|
||||
std::string passString;
|
||||
unsigned int blocks = 0;
|
||||
while ( !_in->eof() )
|
||||
{
|
||||
passString.clear();
|
||||
*_in >> passString;
|
||||
|
||||
if ( passString=="}" )
|
||||
{
|
||||
if ( blocks<=0 ) return;
|
||||
else blocks--;
|
||||
}
|
||||
else if ( passString=="{" )
|
||||
blocks++;
|
||||
}
|
||||
}
|
||||
|
||||
void InputStream::readWrappedString( std::string& str )
|
||||
{
|
||||
*this >> str;
|
||||
if ( !isBinary() )
|
||||
{
|
||||
if ( str[0]=='\"' )
|
||||
{
|
||||
if ( str.size()==1 || (*str.rbegin())!='\"' )
|
||||
{
|
||||
char ch;
|
||||
do
|
||||
{
|
||||
_in->get( ch ); checkStream();
|
||||
str.append( 1, ch );
|
||||
} while ( ch!='\"' );
|
||||
}
|
||||
str = str.substr(1, str.size()-2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void InputStream::readCharArray( char* s, unsigned int size )
|
||||
{
|
||||
if ( size>0 )
|
||||
{
|
||||
_in->read( s, size ); checkStream();
|
||||
}
|
||||
}
|
||||
|
||||
void InputStream::checkStream() const
|
||||
{
|
||||
if ( _in->rdstate()&_in->failbit )
|
||||
throw InputException(_currentField, "InputStream: Failed to read from stream.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
177
include/osgDB/ObjectWrapper
Normal file
177
include/osgDB/ObjectWrapper
Normal file
@@ -0,0 +1,177 @@
|
||||
/* -*-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 H_OBJECTWRAPPER
|
||||
#define H_OBJECTWRAPPER
|
||||
|
||||
#include <osgDB/Serializer>
|
||||
|
||||
namespace osgDB
|
||||
{
|
||||
|
||||
typedef std::vector<std::string> StringList;
|
||||
extern void split( const std::string& src, StringList& list, char separator=' ' );
|
||||
|
||||
class BaseCompressor : public osg::Referenced
|
||||
{
|
||||
public:
|
||||
BaseCompressor() {}
|
||||
void setName( const std::string& name ) { _name = name; }
|
||||
const std::string& getName() const { return _name; }
|
||||
|
||||
virtual bool compress( std::ostream&, const std::string& ) = 0;
|
||||
virtual bool decompress( std::istream&, std::string& ) = 0;
|
||||
|
||||
protected:
|
||||
std::string _name;
|
||||
};
|
||||
|
||||
class ObjectWrapper : public osg::Referenced
|
||||
{
|
||||
public:
|
||||
typedef std::vector< osg::ref_ptr<BaseSerializer> > SerializerList;
|
||||
|
||||
ObjectWrapper( osg::Object* proto, const std::string& name,
|
||||
const std::string& associates );
|
||||
|
||||
const osg::Object* getProto() const { return _proto.get(); }
|
||||
const std::string& getName() const { return _name; }
|
||||
const StringList& getAssociates() const { return _associates; }
|
||||
|
||||
void addSerializer( BaseSerializer* s ) { _serializers.push_back(s); }
|
||||
bool read( InputStream&, osg::Object& );
|
||||
bool write( OutputStream&, const osg::Object& );
|
||||
|
||||
bool readSchema( const StringList& properties );
|
||||
void writeSchema( StringList& properties );
|
||||
void resetSchema()
|
||||
{ if ( _backupSerializers.size()>0 ) _serializers = _backupSerializers; }
|
||||
|
||||
protected:
|
||||
ObjectWrapper() {}
|
||||
virtual ~ObjectWrapper() {}
|
||||
|
||||
osg::ref_ptr<osg::Object> _proto;
|
||||
std::string _name;
|
||||
StringList _associates;
|
||||
SerializerList _serializers;
|
||||
SerializerList _backupSerializers;
|
||||
};
|
||||
|
||||
class ObjectRegistry : public osg::Referenced
|
||||
{
|
||||
public:
|
||||
static ObjectRegistry* instance();
|
||||
|
||||
// Wrapper handlers
|
||||
void addWrapper( ObjectWrapper* wrapper );
|
||||
void removeWrapper( ObjectWrapper* wrapper );
|
||||
ObjectWrapper* findWrapper( const std::string& name );
|
||||
|
||||
typedef std::map< std::string, osg::ref_ptr<ObjectWrapper> > WrapperMap;
|
||||
WrapperMap& getWrapperMap() { return _wrappers; }
|
||||
const WrapperMap& getWrapperMap() const { return _wrappers; }
|
||||
|
||||
// Compressor handlers
|
||||
void addCompressor( BaseCompressor* compressor );
|
||||
void removeCompressor( BaseCompressor* compressor );
|
||||
BaseCompressor* findCompressor( const std::string& name );
|
||||
|
||||
typedef std::map< std::string, osg::ref_ptr<BaseCompressor> > CompressorMap;
|
||||
CompressorMap& getCompressorMap() { return _compressors; }
|
||||
const CompressorMap& getCompressorMap() const { return _compressors; }
|
||||
|
||||
protected:
|
||||
ObjectRegistry() {}
|
||||
virtual ~ObjectRegistry() {}
|
||||
|
||||
WrapperMap _wrappers;
|
||||
CompressorMap _compressors;
|
||||
};
|
||||
|
||||
|
||||
class RegisterWrapperProxy
|
||||
{
|
||||
public:
|
||||
typedef void (*AddPropFunc)( ObjectWrapper* );
|
||||
|
||||
RegisterWrapperProxy( osg::Object* proto, const std::string& name,
|
||||
const std::string& associates, AddPropFunc func );
|
||||
|
||||
virtual ~RegisterWrapperProxy();
|
||||
|
||||
protected:
|
||||
osg::ref_ptr<ObjectWrapper> _wrapper;
|
||||
};
|
||||
|
||||
#define REGISTER_OBJECT_WRAPPER(NAME, PROTO, CLASS, ASSOCIATES) \
|
||||
extern void wrapper_propfunc_##NAME(osgDB::ObjectWrapper*); \
|
||||
static osgDB::RegisterWrapperProxy wrapper_proxy_##NAME( \
|
||||
PROTO, #CLASS, ASSOCIATES, &wrapper_propfunc_##NAME); \
|
||||
typedef CLASS MyClass; \
|
||||
void wrapper_propfunc_##NAME(osgDB::ObjectWrapper* wrapper)
|
||||
|
||||
template<typename T>
|
||||
class RegisterCompressorProxy
|
||||
{
|
||||
public:
|
||||
RegisterCompressorProxy( const std::string& name )
|
||||
{
|
||||
_compressor = new T;
|
||||
_compressor->setName( name );
|
||||
ObjectRegistry::instance()->addCompressor( _compressor.get() );
|
||||
}
|
||||
|
||||
virtual ~RegisterCompressorProxy()
|
||||
{
|
||||
ObjectRegistry::instance()->removeCompressor( _compressor.get() );
|
||||
}
|
||||
|
||||
protected:
|
||||
osg::ref_ptr<BaseCompressor> _compressor;
|
||||
};
|
||||
|
||||
#define REGISTER_COMPRESSOR(NAME, CLASS) \
|
||||
static osgDB::RegisterCompressorProxy<CLASS> compressor_proxy_##CLASS(NAME);
|
||||
|
||||
class GlobalLookupTable : public osg::Referenced
|
||||
{
|
||||
public:
|
||||
typedef std::map<std::string, IntLookup> IntLookupMap;
|
||||
|
||||
static GlobalLookupTable* instance();
|
||||
|
||||
IntLookup::Value getValue( const std::string& group, const std::string& str )
|
||||
{ return findLookup(group).getValue(str.c_str()); }
|
||||
|
||||
const std::string& getString( const std::string& group, IntLookup::Value value )
|
||||
{ return findLookup(group).getString(value); }
|
||||
|
||||
protected:
|
||||
GlobalLookupTable();
|
||||
virtual ~GlobalLookupTable() {}
|
||||
|
||||
IntLookup& findLookup( const std::string& group )
|
||||
{
|
||||
IntLookupMap::iterator itr = _globalMap.find(group);
|
||||
if ( itr!=_globalMap.end() ) return itr->second;
|
||||
else return _globalMap["GL"];
|
||||
}
|
||||
|
||||
IntLookupMap _globalMap;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
381
include/osgDB/OutputStream
Normal file
381
include/osgDB/OutputStream
Normal file
@@ -0,0 +1,381 @@
|
||||
/* -*-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 H_OUTPUTSTREAM
|
||||
#define H_OUTPUTSTREAM
|
||||
|
||||
#include <osg/Vec2>
|
||||
#include <osg/Vec3>
|
||||
#include <osg/Vec4>
|
||||
#include <osg/Quat>
|
||||
#include <osg/Matrix>
|
||||
#include <osg/Array>
|
||||
#include <osg/PrimitiveSet>
|
||||
#include <osgDB/ReaderWriter>
|
||||
#include <osgDB/DataTypes>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
namespace osgDB
|
||||
{
|
||||
|
||||
class OutputException
|
||||
{
|
||||
public:
|
||||
OutputException( const std::string& field, const std::string& err )
|
||||
: _field(field), _error(err) {}
|
||||
|
||||
const std::string& getField() const { return _field; }
|
||||
const std::string& getError() const { return _error; }
|
||||
|
||||
protected:
|
||||
std::string _field;
|
||||
std::string _error;
|
||||
};
|
||||
|
||||
class OutputStream
|
||||
{
|
||||
public:
|
||||
typedef std::map<const osg::Array*, unsigned int> ArrayMap;
|
||||
typedef std::map<const osg::Object*, unsigned int> ObjectMap;
|
||||
|
||||
enum WriteMode
|
||||
{
|
||||
WRITE_BINARY = 0,
|
||||
WRITE_ASCII
|
||||
};
|
||||
|
||||
enum WriteType
|
||||
{
|
||||
WRITE_UNKNOWN = 0,
|
||||
WRITE_SCENE,
|
||||
WRITE_IMAGE
|
||||
};
|
||||
|
||||
enum WriteImageHint
|
||||
{
|
||||
WRITE_USE_IMAGE_HINT = 0, /*!< Use image hint, write inline data or use external */
|
||||
WRITE_USE_EXTERNAL, /*!< Use external file on disk and write only the filename */
|
||||
WRITE_INLINE_DATA, /*!< Write Image::data() to stream */
|
||||
WRITE_INLINE_FILE, /*!< Write the image file itself to stream */
|
||||
WRITE_EXTERNAL_FILE /*!< Write Image::data() to disk and use it as external file */
|
||||
};
|
||||
|
||||
OutputStream( std::ostream* ostream, const osgDB::Options* options );
|
||||
virtual ~OutputStream();
|
||||
|
||||
bool isBinary() const { return _writeMode==WRITE_BINARY; }
|
||||
|
||||
void setWriteImageHint( WriteImageHint hint ) { _writeImageHint = hint; }
|
||||
WriteImageHint getWriteImageHint() const { return _writeImageHint; }
|
||||
|
||||
// Serialization related functions
|
||||
inline OutputStream& operator<<( bool b );
|
||||
inline OutputStream& operator<<( char c );
|
||||
inline OutputStream& operator<<( unsigned char c );
|
||||
inline OutputStream& operator<<( short s );
|
||||
inline OutputStream& operator<<( unsigned short s );
|
||||
inline OutputStream& operator<<( int i );
|
||||
inline OutputStream& operator<<( unsigned int i );
|
||||
inline OutputStream& operator<<( long l );
|
||||
inline OutputStream& operator<<( unsigned long l );
|
||||
inline OutputStream& operator<<( float f );
|
||||
inline OutputStream& operator<<( double d );
|
||||
inline OutputStream& operator<<( const std::string& s );
|
||||
inline OutputStream& operator<<( std::ostream& (*fn)(std::ostream&) );
|
||||
inline OutputStream& operator<<( std::ios_base& (*fn)(std::ios_base&) );
|
||||
|
||||
OutputStream& operator<<( const osg::Vec2b& v );
|
||||
OutputStream& operator<<( const osg::Vec3b& v );
|
||||
OutputStream& operator<<( const osg::Vec4b& v );
|
||||
OutputStream& operator<<( const osg::Vec4ub& v );
|
||||
OutputStream& operator<<( const osg::Vec2s& v );
|
||||
OutputStream& operator<<( const osg::Vec3s& v );
|
||||
OutputStream& operator<<( const osg::Vec4s& v );
|
||||
OutputStream& operator<<( const osg::Vec2f& v );
|
||||
OutputStream& operator<<( const osg::Vec3f& v );
|
||||
OutputStream& operator<<( const osg::Vec4f& v );
|
||||
OutputStream& operator<<( const osg::Vec2d& v );
|
||||
OutputStream& operator<<( const osg::Vec3d& v );
|
||||
OutputStream& operator<<( const osg::Vec4d& v );
|
||||
OutputStream& operator<<( const osg::Quat& q );
|
||||
OutputStream& operator<<( const osg::Plane& p );
|
||||
OutputStream& operator<<( const osg::Matrixf& mat );
|
||||
OutputStream& operator<<( const osg::Matrixd& mat );
|
||||
|
||||
OutputStream& operator<<( const osg::Array* a ) { writeArray(a); return *this; }
|
||||
OutputStream& operator<<( const osg::Image* img ) { writeImage(img); return *this; }
|
||||
OutputStream& operator<<( const osg::PrimitiveSet* p ) { writePrimitiveSet(p); return *this; }
|
||||
OutputStream& operator<<( const osg::Object* obj ) { writeObject(obj); return *this; }
|
||||
|
||||
OutputStream& operator<<( const osg::ref_ptr<osg::Array>& ptr ) { writeArray(ptr.get()); return *this; }
|
||||
OutputStream& operator<<( const osg::ref_ptr<osg::Image>& ptr ) { writeImage(ptr.get()); return *this; }
|
||||
OutputStream& operator<<( const osg::ref_ptr<osg::PrimitiveSet>& ptr ) { writePrimitiveSet(ptr.get()); return *this; }
|
||||
|
||||
template<typename T> OutputStream& operator<<( const osg::ref_ptr<T>& ptr )
|
||||
{ writeObject(ptr.get()); return *this; }
|
||||
|
||||
OutputStream& operator<<( const ObjectGLenum& value );
|
||||
OutputStream& operator<<( const ObjectProperty& prop );
|
||||
OutputStream& operator<<( const ObjectMark& mark );
|
||||
|
||||
// Convenient methods for writing
|
||||
inline void writeWrappedString( const std::string& str );
|
||||
inline void writeCharArray( const char* s, unsigned int size );
|
||||
|
||||
// Global writing functions
|
||||
void writeArray( const osg::Array* a );
|
||||
void writePrimitiveSet( const osg::PrimitiveSet* p );
|
||||
void writeImage( const osg::Image* img );
|
||||
void writeObject( const osg::Object* obj );
|
||||
|
||||
void start( WriteType type );
|
||||
void compress( std::ostream* ostream );
|
||||
|
||||
// Schema handlers
|
||||
void writeSchema( std::ostream& fout );
|
||||
|
||||
protected:
|
||||
template<typename T>
|
||||
void writeArrayImplementation( const T*, int writeSize, unsigned int numInRow=1 );
|
||||
|
||||
unsigned int findOrCreateArrayID( const osg::Array* array );
|
||||
unsigned int findOrCreateObjectID( const osg::Object* obj );
|
||||
|
||||
ArrayMap _arrayMap;
|
||||
ObjectMap _objectMap;
|
||||
|
||||
WriteMode _writeMode;
|
||||
WriteImageHint _writeImageHint;
|
||||
|
||||
bool _readyForEndBracket;
|
||||
int _indent;
|
||||
std::string _currentField;
|
||||
std::string _compressorName;
|
||||
std::stringstream _compressSource;
|
||||
std::ostream* _out;
|
||||
};
|
||||
|
||||
// INLINE METHODS
|
||||
|
||||
OutputStream& OutputStream::operator<<( bool b )
|
||||
{
|
||||
if ( isBinary() )
|
||||
{
|
||||
char c = b?1:0;
|
||||
_out->write( &c, CHAR_SIZE );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( b ) *_out << "TRUE ";
|
||||
else *_out << "FALSE ";
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
OutputStream& OutputStream::operator<<( char c )
|
||||
{
|
||||
if ( isBinary() )
|
||||
{
|
||||
_out->write( &c, CHAR_SIZE );
|
||||
}
|
||||
else
|
||||
{
|
||||
*_out << (short)c << ' ';
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
OutputStream& OutputStream::operator<<( unsigned char c )
|
||||
{
|
||||
if ( isBinary() )
|
||||
{
|
||||
_out->write( (char*)&c, CHAR_SIZE );
|
||||
}
|
||||
else
|
||||
{
|
||||
*_out << (unsigned short)c << ' ';
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
OutputStream& OutputStream::operator<<( short s )
|
||||
{
|
||||
if ( isBinary() )
|
||||
{
|
||||
_out->write( (char*)&s, SHORT_SIZE );
|
||||
}
|
||||
else
|
||||
{
|
||||
*_out << s << ' ';
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
OutputStream& OutputStream::operator<<( unsigned short s )
|
||||
{
|
||||
if ( isBinary() )
|
||||
{
|
||||
_out->write( (char*)&s, SHORT_SIZE );
|
||||
}
|
||||
else
|
||||
{
|
||||
*_out << s << ' ';
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
OutputStream& OutputStream::operator<<( int i )
|
||||
{
|
||||
if ( isBinary() )
|
||||
{
|
||||
_out->write( (char*)&i, INT_SIZE );
|
||||
}
|
||||
else
|
||||
{
|
||||
*_out << i << ' ';
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
OutputStream& OutputStream::operator<<( unsigned int i )
|
||||
{
|
||||
if ( isBinary() )
|
||||
{
|
||||
_out->write( (char*)&i, INT_SIZE );
|
||||
}
|
||||
else
|
||||
{
|
||||
*_out << i << ' ';
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
OutputStream& OutputStream::operator<<( long l )
|
||||
{
|
||||
if ( isBinary() )
|
||||
{
|
||||
_out->write( (char*)&l, LONG_SIZE );
|
||||
}
|
||||
else
|
||||
{
|
||||
*_out << l << ' ';
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
OutputStream& OutputStream::operator<<( unsigned long l )
|
||||
{
|
||||
if ( isBinary() )
|
||||
{
|
||||
_out->write( (char*)&l, LONG_SIZE );
|
||||
}
|
||||
else
|
||||
{
|
||||
*_out << l << ' ';
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
OutputStream& OutputStream::operator<<( float f )
|
||||
{
|
||||
if ( isBinary() )
|
||||
{
|
||||
_out->write( (char*)&f, FLOAT_SIZE );
|
||||
}
|
||||
else
|
||||
{
|
||||
*_out << f << ' ';
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
OutputStream& OutputStream::operator<<( double d )
|
||||
{
|
||||
if ( isBinary() )
|
||||
{
|
||||
_out->write((char*)&d, DOUBLE_SIZE);
|
||||
}
|
||||
else
|
||||
{
|
||||
*_out << d << ' ';
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
OutputStream& OutputStream::operator<<( const std::string& s )
|
||||
{
|
||||
if ( isBinary() )
|
||||
{
|
||||
int size = s.size();
|
||||
_out->write( (char*)&size, INT_SIZE );
|
||||
_out->write( s.c_str(), s.size() );
|
||||
}
|
||||
else
|
||||
{
|
||||
*_out << s << ' ';
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
OutputStream& OutputStream::operator<<( std::ostream& (*fn)(std::ostream&) )
|
||||
{
|
||||
if ( !isBinary() )
|
||||
{
|
||||
*_out << fn;
|
||||
if ( fn==static_cast<std::ostream& (*)(std::ostream&)>(std::endl) )
|
||||
{
|
||||
_readyForEndBracket = true;
|
||||
for (int i=0; i<_indent; ++i)
|
||||
*_out << ' ';
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
OutputStream& OutputStream::operator<<( std::ios_base& (*fn)(std::ios_base&) )
|
||||
{
|
||||
if ( !isBinary() ) *_out << fn;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void OutputStream::writeWrappedString( const std::string& str )
|
||||
{
|
||||
if ( !isBinary() )
|
||||
{
|
||||
std::string wrappedStr = std::string("\"") + str + std::string("\"");
|
||||
*this << wrappedStr;
|
||||
}
|
||||
else
|
||||
*this << str;
|
||||
}
|
||||
|
||||
void OutputStream::writeCharArray( const char* s, unsigned int size )
|
||||
{
|
||||
if ( size>0 )
|
||||
{
|
||||
if ( isBinary() )
|
||||
{
|
||||
_out->write( s, size );
|
||||
}
|
||||
else
|
||||
{
|
||||
*_out << s << ' ';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -621,52 +621,6 @@ inline void readCommandLine(osg::ArgumentParser& parser)
|
||||
Registry::instance()->readCommandLine(parser);
|
||||
}
|
||||
|
||||
/** Proxy class for automatic registration of DotOsgWrappers with the Registry.*/
|
||||
class RegisterDotOsgWrapperProxy
|
||||
{
|
||||
public:
|
||||
|
||||
RegisterDotOsgWrapperProxy(osg::Object* proto,
|
||||
const std::string& name,
|
||||
const std::string& associates,
|
||||
DotOsgWrapper::ReadFunc readFunc,
|
||||
DotOsgWrapper::WriteFunc writeFunc,
|
||||
DotOsgWrapper::ReadWriteMode readWriteMode=DotOsgWrapper::READ_AND_WRITE)
|
||||
{
|
||||
if (Registry::instance())
|
||||
{
|
||||
_wrapper = new DotOsgWrapper(proto,name,associates,readFunc,writeFunc,readWriteMode);
|
||||
Registry::instance()->addDotOsgWrapper(_wrapper.get());
|
||||
}
|
||||
}
|
||||
|
||||
~RegisterDotOsgWrapperProxy()
|
||||
{
|
||||
if (Registry::instance())
|
||||
{
|
||||
Registry::instance()->removeDotOsgWrapper(_wrapper.get());
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
osg::ref_ptr<DotOsgWrapper> _wrapper;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
class TemplateRegisterDotOsgWrapperProxy : public RegisterDotOsgWrapperProxy, public T
|
||||
{
|
||||
public:
|
||||
|
||||
TemplateRegisterDotOsgWrapperProxy(osg::Object* proto,
|
||||
const std::string& name,
|
||||
const std::string& associates,
|
||||
DotOsgWrapper::ReadFunc readFunc,
|
||||
DotOsgWrapper::WriteFunc writeFunc,
|
||||
DotOsgWrapper::ReadWriteMode readWriteMode=DotOsgWrapper::READ_AND_WRITE):
|
||||
RegisterDotOsgWrapperProxy(proto, name, associates, readFunc, writeFunc, readWriteMode) {}
|
||||
|
||||
};
|
||||
|
||||
/** Proxy class for automatic registration of reader/writers with the Registry.*/
|
||||
template<class T>
|
||||
class RegisterReaderWriterProxy
|
||||
@@ -705,19 +659,15 @@ struct PluginFunctionProxy
|
||||
extern "C" void osgdb_##ext(void); \
|
||||
static osgDB::PluginFunctionProxy proxy_##ext(osgdb_##ext);
|
||||
|
||||
#define USE_DOTOSGWRAPPER(classname) \
|
||||
extern "C" void dotosgwrapper_##classname(void); \
|
||||
static osgDB::PluginFunctionProxy proxy_dotosgwrapper_##classname(dotosgwrapper_##classname);
|
||||
|
||||
#define REGISTER_OSGPLUGIN(ext, classname) \
|
||||
extern "C" void osgdb_##ext(void) {} \
|
||||
static osgDB::RegisterReaderWriterProxy<classname> g_proxy_##classname;
|
||||
|
||||
|
||||
#define USE_DOTOSGWRAPPER(classname) \
|
||||
extern "C" void dotosgwrapper_##classname(void); \
|
||||
static osgDB::PluginFunctionProxy proxy_dotosgwrapper_##classname(dotosgwrapper_##classname);
|
||||
|
||||
#define REGISTER_DOTOSGWRAPPER(classname) \
|
||||
extern "C" void dotosgwrapper_##classname(void) {} \
|
||||
static osgDB::RegisterDotOsgWrapperProxy dotosgwrapper_proxy_##classname
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
853
include/osgDB/Serializer
Normal file
853
include/osgDB/Serializer
Normal file
@@ -0,0 +1,853 @@
|
||||
/* -*-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 H_SERIALIZER
|
||||
#define H_SERIALIZER
|
||||
|
||||
#include <osg/ref_ptr>
|
||||
#include <osg/Notify>
|
||||
#include <osg/Object>
|
||||
#include <osgDB/InputStream>
|
||||
#include <osgDB/OutputStream>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
|
||||
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]
|
||||
<< " 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
|
||||
{
|
||||
public:
|
||||
BaseSerializer() {}
|
||||
virtual bool read( InputStream&, osg::Object& ) = 0;
|
||||
virtual bool write( OutputStream&, const osg::Object& ) = 0;
|
||||
virtual const std::string& getName() const = 0;
|
||||
};
|
||||
|
||||
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 )
|
||||
: _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() && !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);
|
||||
if ( !os.isBinary() )
|
||||
{
|
||||
if ( !(*_checker)(object) ) return true;
|
||||
os << _name;
|
||||
}
|
||||
return (*_writer)(os, object);
|
||||
}
|
||||
|
||||
virtual const std::string& getName() const { return _name; }
|
||||
|
||||
protected:
|
||||
std::string _name;
|
||||
Checker _checker;
|
||||
Reader _reader;
|
||||
Writer _writer;
|
||||
};
|
||||
|
||||
template<typename P>
|
||||
class TemplateSerializer : public BaseSerializer
|
||||
{
|
||||
public:
|
||||
TemplateSerializer( const char* name )
|
||||
: _name(name) {}
|
||||
|
||||
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), _getter(gf), _setter(sf), _useHex(useHex)
|
||||
{ ParentType::_defaultValue = def; }
|
||||
|
||||
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);
|
||||
if ( os.isBinary() )
|
||||
{
|
||||
os << (object.*_getter)();
|
||||
}
|
||||
else if ( ParentType::_defaultValue!=(object.*_getter)() )
|
||||
{
|
||||
os << ParentType::_name;
|
||||
if ( _useHex ) os << std::hex;
|
||||
os << (object.*_getter)();
|
||||
if ( _useHex ) os << std::dec;
|
||||
os << std::endl;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected:
|
||||
Getter _getter;
|
||||
Setter _setter;
|
||||
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), _getter(gf), _setter(sf)
|
||||
{ ParentType::_defaultValue = def; }
|
||||
|
||||
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);
|
||||
if ( os.isBinary() )
|
||||
{
|
||||
os << (object.*_getter)();
|
||||
}
|
||||
else if ( ParentType::_defaultValue!=(object.*_getter)() )
|
||||
{
|
||||
os << ParentType::_name << (object.*_getter)() << std::endl;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected:
|
||||
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), _getter(gf), _setter(sf)
|
||||
{ ParentType::_defaultValue = def; }
|
||||
|
||||
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);
|
||||
if ( os.isBinary() )
|
||||
{
|
||||
os << (object.*_getter)();
|
||||
}
|
||||
else if ( ParentType::_defaultValue!=(object.*_getter)() )
|
||||
{
|
||||
os << ParentType::_name << (object.*_getter)() << std::endl;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected:
|
||||
void readMatrixImplementation( InputStream& is, osg::Matrix& matrix )
|
||||
{
|
||||
if ( is.getUseFloatMatrix() )
|
||||
{
|
||||
osg::Matrixf realValue; is >> realValue;
|
||||
matrix = realValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
osg::Matrixd realValue; is >> realValue;
|
||||
matrix = realValue;
|
||||
}
|
||||
}
|
||||
|
||||
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), _getter(gf), _setter(sf)
|
||||
{ ParentType::_defaultValue = def; }
|
||||
|
||||
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);
|
||||
if ( os.isBinary() )
|
||||
{
|
||||
os << static_cast<GLenum>((object.*_getter)());
|
||||
}
|
||||
else if ( ParentType::_defaultValue!=(object.*_getter)() )
|
||||
{
|
||||
os << ParentType::_name << GLENUM((object.*_getter)()) << std::endl;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected:
|
||||
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), _getter(gf), _setter(sf)
|
||||
{ ParentType::_defaultValue = def; }
|
||||
|
||||
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);
|
||||
if ( os.isBinary() )
|
||||
{
|
||||
os << (object.*_getter)();
|
||||
}
|
||||
else if ( ParentType::_defaultValue!=(object.*_getter)() )
|
||||
{
|
||||
os << ParentType::_name;
|
||||
os.writeWrappedString( (object.*_getter)() );
|
||||
os << std::endl;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected:
|
||||
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), _getter(gf), _setter(sf)
|
||||
{ ParentType::_defaultValue = def; }
|
||||
|
||||
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() );
|
||||
(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);
|
||||
bool hasObject = ((object.*_getter)()!=NULL);
|
||||
if ( os.isBinary() )
|
||||
{
|
||||
os << hasObject;
|
||||
os.writeObject( (object.*_getter)() );
|
||||
}
|
||||
else if ( ParentType::_defaultValue!=(object.*_getter)() )
|
||||
{
|
||||
os << ParentType::_name << hasObject;
|
||||
if ( hasObject )
|
||||
{
|
||||
os << BEGIN_BRACKET << std::endl;
|
||||
os.writeObject( (object.*_getter)() );
|
||||
os << END_BRACKET;
|
||||
}
|
||||
os << std::endl;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected:
|
||||
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), _getter(gf), _setter(sf)
|
||||
{ ParentType::_defaultValue = def; }
|
||||
|
||||
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() );
|
||||
(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);
|
||||
bool hasObject = ((object.*_getter)()!=NULL);
|
||||
if ( os.isBinary() )
|
||||
{
|
||||
os << hasObject;
|
||||
os.writeImage( (object.*_getter)() );
|
||||
}
|
||||
else if ( ParentType::_defaultValue!=(object.*_getter)() )
|
||||
{
|
||||
os << ParentType::_name << hasObject;
|
||||
if ( hasObject )
|
||||
{
|
||||
os << BEGIN_BRACKET << std::endl;
|
||||
os.writeImage( (object.*_getter)() );
|
||||
os << END_BRACKET;
|
||||
}
|
||||
os << std::endl;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected:
|
||||
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), _getter(gf), _setter(sf)
|
||||
{ ParentType::_defaultValue = def; }
|
||||
|
||||
void add( const char* str, P value )
|
||||
{ _lookup.add(str, static_cast<osgDB::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<osgDB::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);
|
||||
if ( os.isBinary() )
|
||||
{
|
||||
os << (osgDB::IntLookup::Value)(object.*_getter)();
|
||||
}
|
||||
else if ( ParentType::_defaultValue!=(object.*_getter)() )
|
||||
{
|
||||
os << ParentType::_name << getString((object.*_getter)()) << std::endl;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected:
|
||||
Getter _getter;
|
||||
Setter _setter;
|
||||
IntLookup _lookup;
|
||||
};
|
||||
|
||||
template<typename C, typename P>
|
||||
class ListSerializer : public TemplateSerializer<P>
|
||||
{
|
||||
public:
|
||||
typedef TemplateSerializer<P> ParentType;
|
||||
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 )
|
||||
: ParentType(name), _getter(gf), _setter(sf) {}
|
||||
|
||||
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(ParentType::_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 << ParentType::_name << size << BEGIN_BRACKET << std::endl;
|
||||
for ( ConstIterator itr=list.begin();
|
||||
itr!=list.end(); ++itr )
|
||||
{
|
||||
os << (*itr);
|
||||
}
|
||||
os << END_BRACKET << std::endl;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected:
|
||||
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) )
|
||||
|
||||
#define ADD_BOOL_SERIALIZER(PROP, DEF) \
|
||||
wrapper->addSerializer( new osgDB::PropByValSerializer<MyClass, bool>( \
|
||||
#PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP) )
|
||||
|
||||
#define ADD_SHORT_SERIALIZER(PROP, DEF) \
|
||||
wrapper->addSerializer( new osgDB::PropByValSerializer<MyClass, short>( \
|
||||
#PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP) )
|
||||
|
||||
#define ADD_USHORT_SERIALIZER(PROP, DEF) \
|
||||
wrapper->addSerializer( new osgDB::PropByValSerializer<MyClass, unsigned short>( \
|
||||
#PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP) )
|
||||
|
||||
#define ADD_HEXSHORT_SERIALIZER(PROP, DEF) \
|
||||
wrapper->addSerializer( new osgDB::PropByValSerializer<MyClass, unsigned short>( \
|
||||
#PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP, true) )
|
||||
|
||||
#define ADD_INT_SERIALIZER(PROP, DEF) \
|
||||
wrapper->addSerializer( new osgDB::PropByValSerializer<MyClass, int>( \
|
||||
#PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP) )
|
||||
|
||||
#define ADD_UINT_SERIALIZER(PROP, DEF) \
|
||||
wrapper->addSerializer( new osgDB::PropByValSerializer<MyClass, unsigned int>( \
|
||||
#PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP) )
|
||||
|
||||
#define ADD_HEXINT_SERIALIZER(PROP, DEF) \
|
||||
wrapper->addSerializer( new osgDB::PropByValSerializer<MyClass, unsigned int>( \
|
||||
#PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP, true) )
|
||||
|
||||
#define ADD_FLOAT_SERIALIZER(PROP, DEF) \
|
||||
wrapper->addSerializer( new osgDB::PropByValSerializer<MyClass, float>( \
|
||||
#PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP) )
|
||||
|
||||
#define ADD_DOUBLE_SERIALIZER(PROP, DEF) \
|
||||
wrapper->addSerializer( new osgDB::PropByValSerializer<MyClass, double>( \
|
||||
#PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP) )
|
||||
|
||||
#define ADD_VEC3F_SERIALIZER(PROP, DEF) \
|
||||
wrapper->addSerializer( new osgDB::PropByRefSerializer<MyClass, osg::Vec3f>( \
|
||||
#PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP) )
|
||||
|
||||
#define ADD_VEC3D_SERIALIZER(PROP, DEF) \
|
||||
wrapper->addSerializer( new osgDB::PropByRefSerializer<MyClass, osg::Vec3d>( \
|
||||
#PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP) )
|
||||
|
||||
#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) )
|
||||
|
||||
#define ADD_VEC4D_SERIALIZER(PROP, DEF) \
|
||||
wrapper->addSerializer( new osgDB::PropByRefSerializer<MyClass, osg::Vec4d>( \
|
||||
#PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP) )
|
||||
|
||||
#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) )
|
||||
|
||||
#define ADD_PLANE_SERIALIZER(PROP, DEF) \
|
||||
wrapper->addSerializer( new osgDB::PropByRefSerializer<MyClass, osg::Plane>( \
|
||||
#PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP) )
|
||||
|
||||
#define ADD_MATRIXF_SERIALIZER(PROP, DEF) \
|
||||
wrapper->addSerializer( new osgDB::PropByRefSerializer<MyClass, osg::Matrixf>( \
|
||||
#PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP) )
|
||||
|
||||
#define ADD_MATRIXD_SERIALIZER(PROP, DEF) \
|
||||
wrapper->addSerializer( new osgDB::PropByRefSerializer<MyClass, osg::Matrixd>( \
|
||||
#PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP) )
|
||||
|
||||
#define ADD_MATRIX_SERIALIZER(PROP, DEF) \
|
||||
wrapper->addSerializer( new osgDB::MatrixSerializer<MyClass>( \
|
||||
#PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP) )
|
||||
|
||||
#define ADD_GLENUM_SERIALIZER(PROP, TYPE, DEF) \
|
||||
wrapper->addSerializer( new osgDB::GLenumSerializer<MyClass, TYPE>( \
|
||||
#PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP) )
|
||||
|
||||
#define ADD_STRING_SERIALIZER(PROP, DEF) \
|
||||
wrapper->addSerializer( new osgDB::StringSerializer<MyClass>( \
|
||||
#PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP) )
|
||||
|
||||
#define ADD_OBJECT_SERIALIZER(PROP, TYPE, DEF) \
|
||||
wrapper->addSerializer( new osgDB::ObjectSerializer<MyClass, TYPE>( \
|
||||
#PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP) )
|
||||
|
||||
#define ADD_IMAGE_SERIALIZER(PROP, TYPE, DEF) \
|
||||
wrapper->addSerializer( new osgDB::ImageSerializer<MyClass, TYPE>( \
|
||||
#PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP) )
|
||||
|
||||
#define ADD_LIST_SERIALIZER(PROP, TYPE) \
|
||||
wrapper->addSerializer( new osgDB::ListSerializer<MyClass, TYPE>( \
|
||||
#PROP, &MyClass::get##PROP, &MyClass::set##PROP) )
|
||||
|
||||
#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 ADD_ENUM_VALUE(VALUE) \
|
||||
serializer->add(#VALUE, MyClass::VALUE)
|
||||
|
||||
#define END_ENUM_SERIALIZER() \
|
||||
wrapper->addSerializer(serializer); }
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user