root/OpenSceneGraph/trunk/include/osgDB/ObjectWrapper @ 11902

Revision 11902, 6.4 kB (checked in by robert, 4 years ago)

From Wang Rui, "I'd like to submit my latest modification of the serialization IO
functionalities. It includes two main parts: a version checking macro
for handling backward-compatiblity since 3.0, and enhencement of
current schema mechanism. I also change the option handling process to
use getPluginStringData(), and add new USE_SERIALIZER_WRAPPER macro in
the Registry header to allow for static-link usage as well.

The enhencement of schema machanism just tells the type of each
serializer while outputting them, such as:
osg::Group = Children:1

The meaning of the number can be found in the osgDB/Serializer header,
BaseSerializer::Type enum. It may help 3rdparty utilities understand
the structure of the wrapper and do some reflection work in the
future.

The new macro UPDATE_TO_VERSION can help indicate the InputStream? (no
affect on the writer) that a serializer is added/removed since certain
OSG version. An example wrapper file is also attached. The
Geode_modified.cpp is based on the serializers/osg/Geode.cpp file
(hey, don't merge it :-), but assumes that a new user serializer
'Test' is added since version 65 (that is, the OSG_SOVERSION):

REGISTER_OBJECT_WRAPPER( Geode, ... )
{

ADD_USER_SERIALIZER( Drawables ); // origin ones

UPDATE_TO_VERSION( 65 )
{

ADD_USER_SERIALIZER( Test ); // a serializer added from version 65

}

}

All kinds of ADD_... macros following UPDATE_TO_VERSION will
automatically apply the updated version. The braces here are only for
typesetting!
While reading an osgt/osgb/osgx file, OSG will now check if the file
version (recorded as the writer's soversion, instead of previous
meaningless "#Version 2") is equal or greater than Test's version, and
try reading it, or just ignore it if file version is lesser.

And we also have the REMOVE_SERIALIZER macro will mark a named
serializer as removed in some version, with which all files generated
by further versions will just ignore it:

UPDATE_TO_VERSION( 70 )
{

REMOVE_SERIALIZER( Test );

}

This means that from version 70, the serializer Test is removed (but
not actually erased from the list) and should not be read anymore. If
the read file version is less than 70 (and equal or greater than 65),
Test will still be handled when reading; otherwise it will be ignored
to keep compatiblity on different OSG versions.
"

Line 
1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2010 Robert Osfield
2 *
3 * This library is open source and may be redistributed and/or modified under
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version.  The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 * OpenSceneGraph Public License for more details.
12*/
13// Written by Wang Rui, (C) 2010
14
15#ifndef OSGDB_OBJECTWRAPPER
16#define OSGDB_OBJECTWRAPPER
17
18#include <osgDB/Serializer>
19
20namespace osgDB
21{
22
23typedef std::vector<std::string> StringList;
24extern OSGDB_EXPORT void split( const std::string& src, StringList& list, char separator=' ' );
25
26class OSGDB_EXPORT BaseCompressor : public osg::Referenced
27{
28public:
29    BaseCompressor() {}
30    void setName( const std::string& name ) { _name = name; }
31    const std::string& getName() const { return _name; }
32
33    virtual bool compress( std::ostream&, const std::string& ) = 0;
34    virtual bool decompress( std::istream&, std::string& ) = 0;
35
36protected:
37    std::string _name;
38};
39
40struct FinishedObjectReadCallback : public osg::Referenced
41{
42    virtual void objectRead(osgDB::InputStream& is, osg::Object& obj) = 0;
43};
44
45class OSGDB_EXPORT ObjectWrapper : public osg::Referenced
46{
47public:
48    typedef std::vector< osg::ref_ptr<BaseSerializer> > SerializerList;
49    typedef std::vector< osg::ref_ptr<FinishedObjectReadCallback> > FinishedObjectReadCallbackList;
50   
51    ObjectWrapper( osg::Object* proto, const std::string& name,
52                   const std::string& associates );
53    void setUpdatedVersion( int ver ) { _version = ver; }
54   
55    const osg::Object* getProto() const { return _proto.get(); }
56    const std::string& getName() const { return _name; }
57    const StringList& getAssociates() const { return _associates; }
58
59    void addSerializer( BaseSerializer* s, BaseSerializer::Type t=BaseSerializer::RW_UNDEFINED )
60    { s->_version = _version; _serializers.push_back(s); _typeList.push_back(static_cast<int>(t)); }
61
62    void markSerializerAsRemoved( const std::string& name );
63    BaseSerializer* getSerializer( const std::string& name );
64    void addFinishedObjectReadCallback ( FinishedObjectReadCallback* forc) { _finishedObjectReadCallbacks.push_back(forc); }
65
66    bool read( InputStream&, osg::Object& );
67    bool write( OutputStream&, const osg::Object& );
68
69    bool readSchema( const StringList& properties, const std::vector<int>& types );
70    void writeSchema( StringList& properties, std::vector<int>& types );
71    void resetSchema()
72    { if ( _backupSerializers.size()>0 ) _serializers = _backupSerializers; }
73   
74protected:
75    ObjectWrapper() : _version(0) {}
76    virtual ~ObjectWrapper() {}
77
78    osg::ref_ptr<osg::Object> _proto;
79    std::string _name;
80    StringList _associates;
81    SerializerList _serializers;
82    SerializerList _backupSerializers;
83    std::vector<int> _typeList;
84    FinishedObjectReadCallbackList _finishedObjectReadCallbacks;
85    int _version;  // Last updated version of the wrapper
86};
87
88class Registry;
89
90class OSGDB_EXPORT ObjectWrapperManager : public osg::Referenced
91{
92public:
93
94    // Wrapper handlers
95    void addWrapper( ObjectWrapper* wrapper );
96    void removeWrapper( ObjectWrapper* wrapper );
97    ObjectWrapper* findWrapper( const std::string& name );
98
99    typedef std::map< std::string, osg::ref_ptr<ObjectWrapper> > WrapperMap;
100    WrapperMap& getWrapperMap() { return _wrappers; }
101    const WrapperMap& getWrapperMap() const { return _wrappers; }
102
103    // Compressor handlers
104    void addCompressor( BaseCompressor* compressor );
105    void removeCompressor( BaseCompressor* compressor );
106    BaseCompressor* findCompressor( const std::string& name );
107
108    typedef std::map< std::string, osg::ref_ptr<BaseCompressor> > CompressorMap;
109    CompressorMap& getCompressorMap() { return _compressors; }
110    const CompressorMap& getCompressorMap() const { return _compressors; }
111
112    typedef std::map<std::string, IntLookup> IntLookupMap;
113    IntLookup::Value getValue( const std::string& group, const std::string& str ) { return findLookup(group).getValue(str.c_str()); }
114    const std::string& getString( const std::string& group, IntLookup::Value value ) { return findLookup(group).getString(value); }
115
116protected:
117
118    friend class osgDB::Registry;
119
120    ObjectWrapperManager();
121    virtual ~ObjectWrapperManager();
122
123    WrapperMap _wrappers;
124    CompressorMap _compressors;
125
126    IntLookup& findLookup( const std::string& group )
127    {
128        IntLookupMap::iterator itr = _globalMap.find(group);
129        if ( itr!=_globalMap.end() ) return itr->second;
130        else return _globalMap["GL"];
131    }
132
133    IntLookupMap _globalMap;
134};
135
136
137class OSGDB_EXPORT RegisterWrapperProxy
138{
139public:
140    typedef void (*AddPropFunc)( ObjectWrapper* );
141
142    RegisterWrapperProxy( osg::Object* proto, const std::string& name,
143                          const std::string& associates, AddPropFunc func );
144
145    virtual ~RegisterWrapperProxy();
146
147protected:
148    osg::ref_ptr<ObjectWrapper> _wrapper;
149};
150
151#define REGISTER_OBJECT_WRAPPER(NAME, PROTO, CLASS, ASSOCIATES) \
152    extern "C" void wrapper_serializer_##NAME(void) {} \
153    extern void wrapper_propfunc_##NAME(osgDB::ObjectWrapper*); \
154    static osgDB::RegisterWrapperProxy wrapper_proxy_##NAME( \
155        PROTO, #CLASS, ASSOCIATES, &wrapper_propfunc_##NAME); \
156    typedef CLASS MyClass; \
157    void wrapper_propfunc_##NAME(osgDB::ObjectWrapper* wrapper)
158
159#define REGISTER_OBJECT_WRAPPER2(NAME, PROTO, CLASS, CLASSNAME, ASSOCIATES) \
160    extern "C" void wrapper_serializer_##NAME(void) {} \
161    extern void wrapper_propfunc_##NAME(osgDB::ObjectWrapper*); \
162    static osgDB::RegisterWrapperProxy wrapper_proxy_##NAME( \
163        PROTO, CLASSNAME, ASSOCIATES, &wrapper_propfunc_##NAME); \
164    typedef CLASS MyClass; \
165    void wrapper_propfunc_##NAME(osgDB::ObjectWrapper* wrapper)
166
167class OSGDB_EXPORT RegisterCompressorProxy
168{
169public:
170    RegisterCompressorProxy( const std::string& name, BaseCompressor* compressor );
171    ~RegisterCompressorProxy();
172
173protected:
174    osg::ref_ptr<BaseCompressor> _compressor;
175};
176
177#define REGISTER_COMPRESSOR(NAME, CLASS) \
178    extern "C" void wrapper_compressor_##CLASS(void) {} \
179    static osgDB::RegisterCompressorProxy compressor_proxy_##CLASS(NAME, new CLASS);
180
181}
182
183#endif
Note: See TracBrowser for help on using the browser.