9fab99ddd9
macro, which could set version within brackets and reset it after that. All related serializers are also modified so that the backward-compatibility bug reported by Farshid can be fixed. " From Robert Osfield, removed the use of osg::Referenced and creating the proxy object on the heap.
201 lines
6.7 KiB
C++
201 lines
6.7 KiB
C++
/* -*-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_OBJECTWRAPPER
|
|
#define OSGDB_OBJECTWRAPPER
|
|
|
|
#include <osgDB/Serializer>
|
|
|
|
namespace osgDB
|
|
{
|
|
|
|
typedef std::vector<std::string> StringList;
|
|
extern OSGDB_EXPORT void split( const std::string& src, StringList& list, char separator=' ' );
|
|
|
|
class OSGDB_EXPORT 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;
|
|
};
|
|
|
|
struct FinishedObjectReadCallback : public osg::Referenced
|
|
{
|
|
virtual void objectRead(osgDB::InputStream& is, osg::Object& obj) = 0;
|
|
};
|
|
|
|
class OSGDB_EXPORT ObjectWrapper : public osg::Referenced
|
|
{
|
|
public:
|
|
typedef std::vector< osg::ref_ptr<BaseSerializer> > SerializerList;
|
|
typedef std::vector< osg::ref_ptr<FinishedObjectReadCallback> > FinishedObjectReadCallbackList;
|
|
|
|
ObjectWrapper( osg::Object* proto, const std::string& name,
|
|
const std::string& associates );
|
|
|
|
void setUpdatedVersion( int ver ) { _version = ver; }
|
|
int getUpdatedVersion() const { return _version; }
|
|
|
|
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, BaseSerializer::Type t=BaseSerializer::RW_UNDEFINED );
|
|
void markSerializerAsRemoved( const std::string& name );
|
|
BaseSerializer* getSerializer( const std::string& name );
|
|
void addFinishedObjectReadCallback ( FinishedObjectReadCallback* forc) { _finishedObjectReadCallbacks.push_back(forc); }
|
|
|
|
bool read( InputStream&, osg::Object& );
|
|
bool write( OutputStream&, const osg::Object& );
|
|
|
|
bool readSchema( const StringList& properties, const std::vector<int>& types );
|
|
void writeSchema( StringList& properties, std::vector<int>& types );
|
|
void resetSchema()
|
|
{ if ( _backupSerializers.size()>0 ) _serializers = _backupSerializers; }
|
|
|
|
protected:
|
|
ObjectWrapper() : _version(0) {}
|
|
virtual ~ObjectWrapper() {}
|
|
|
|
osg::ref_ptr<osg::Object> _proto;
|
|
std::string _name;
|
|
StringList _associates;
|
|
SerializerList _serializers;
|
|
SerializerList _backupSerializers;
|
|
std::vector<int> _typeList;
|
|
FinishedObjectReadCallbackList _finishedObjectReadCallbacks;
|
|
int _version; // Last updated version of the wrapper
|
|
};
|
|
|
|
struct UpdateWrapperVersionProxy
|
|
{
|
|
UpdateWrapperVersionProxy( ObjectWrapper* w, int v ): _wrapper(w)
|
|
{
|
|
_lastVersion = w->getUpdatedVersion();
|
|
w->setUpdatedVersion(v);
|
|
}
|
|
|
|
~UpdateWrapperVersionProxy()
|
|
{
|
|
_wrapper->setUpdatedVersion(_lastVersion);
|
|
}
|
|
|
|
ObjectWrapper* _wrapper;
|
|
int _lastVersion;
|
|
};
|
|
|
|
class Registry;
|
|
|
|
class OSGDB_EXPORT ObjectWrapperManager : public osg::Referenced
|
|
{
|
|
public:
|
|
|
|
// 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; }
|
|
|
|
typedef std::map<std::string, IntLookup> IntLookupMap;
|
|
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:
|
|
|
|
friend class osgDB::Registry;
|
|
|
|
ObjectWrapperManager();
|
|
virtual ~ObjectWrapperManager();
|
|
|
|
WrapperMap _wrappers;
|
|
CompressorMap _compressors;
|
|
|
|
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;
|
|
};
|
|
|
|
|
|
class OSGDB_EXPORT 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 "C" void wrapper_serializer_##NAME(void) {} \
|
|
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)
|
|
|
|
#define REGISTER_OBJECT_WRAPPER2(NAME, PROTO, CLASS, CLASSNAME, ASSOCIATES) \
|
|
extern "C" void wrapper_serializer_##NAME(void) {} \
|
|
extern void wrapper_propfunc_##NAME(osgDB::ObjectWrapper*); \
|
|
static osgDB::RegisterWrapperProxy wrapper_proxy_##NAME( \
|
|
PROTO, CLASSNAME, ASSOCIATES, &wrapper_propfunc_##NAME); \
|
|
typedef CLASS MyClass; \
|
|
void wrapper_propfunc_##NAME(osgDB::ObjectWrapper* wrapper)
|
|
|
|
class OSGDB_EXPORT RegisterCompressorProxy
|
|
{
|
|
public:
|
|
RegisterCompressorProxy( const std::string& name, BaseCompressor* compressor );
|
|
~RegisterCompressorProxy();
|
|
|
|
protected:
|
|
osg::ref_ptr<BaseCompressor> _compressor;
|
|
};
|
|
|
|
#define REGISTER_COMPRESSOR(NAME, CLASS) \
|
|
extern "C" void wrapper_compressor_##CLASS(void) {} \
|
|
static osgDB::RegisterCompressorProxy compressor_proxy_##CLASS(NAME, new CLASS);
|
|
|
|
}
|
|
|
|
#endif
|