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

Revision 11902, 29.5 kB (checked in by robert, 3 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__SERIALIZER
16#define OSGDB__SERIALIZER
17
18#include <osg/ref_ptr>
19#include <osg/Notify>
20#include <osg/Object>
21#include <osgDB/InputStream>
22#include <osgDB/OutputStream>
23#include <string>
24#include <sstream>
25
26
27namespace osgDB
28{
29
30#ifndef OBJECT_CAST
31    #define OBJECT_CAST static_cast
32#endif
33
34class IntLookup
35{
36public:
37    typedef int Value;
38    typedef std::map<std::string, Value> StringToValue;
39    typedef std::map<Value, std::string> ValueToString;
40   
41    IntLookup() {}
42    unsigned int size() const { return _stringToValue.size(); }
43   
44    void add( const char* str, Value value )
45    {
46        if ( _valueToString.find(value)!=_valueToString.end() )
47        {
48            osg::notify(osg::WARN) << "Duplicate enum value " << value
49                                   << " with old string: " << _valueToString[value]
50                                   << " and new string: " << str << std::endl;
51        }
52        _valueToString[value] = str;
53        _stringToValue[str] = value;
54    }
55   
56    Value getValue( const char* str )
57    {
58        StringToValue::iterator itr = _stringToValue.find(str);
59        if ( itr==_stringToValue.end() )
60        {
61            Value value;
62            std::stringstream stream;
63            stream << str; stream >> value;
64            _stringToValue[str] = value;
65            return value;
66        }
67        return itr->second;
68    }
69   
70    const std::string& getString( Value value )
71    {
72        ValueToString::iterator itr = _valueToString.find(value);
73        if ( itr==_valueToString.end() )
74        {
75            std::string str;
76            std::stringstream stream;
77            stream << value; stream >> str;
78            _valueToString[value] = str;
79            return _valueToString[value];
80        }
81        return itr->second;
82    }
83   
84protected:
85    StringToValue _stringToValue;
86    ValueToString _valueToString;
87};
88
89class UserLookupTableProxy
90{
91public:
92    typedef void (*AddValueFunc)( IntLookup* lookup );
93    UserLookupTableProxy( AddValueFunc func ) { if ( func ) (*func)(&_lookup); }
94   
95    IntLookup _lookup;
96};
97
98#define BEGIN_USER_TABLE(NAME, CLASS) \
99    static void add_user_value_func_##NAME(osgDB::IntLookup*); \
100    static osgDB::UserLookupTableProxy s_user_lookup_table_##NAME(&add_user_value_func_##NAME); \
101    static void add_user_value_func_##NAME(osgDB::IntLookup* lookup) { typedef CLASS MyClass
102#define ADD_USER_VALUE(VALUE) lookup->add(#VALUE, MyClass::VALUE)
103#define END_USER_TABLE() }
104
105#define USER_READ_FUNC(NAME, FUNCNAME) \
106    static int FUNCNAME(osgDB::InputStream& is) { \
107        int value; if (is.isBinary()) is >> value; \
108        else { std::string str; is >> str; \
109        value = (s_user_lookup_table_##NAME)._lookup.getValue(str.c_str()); } \
110        return value; }
111
112#define USER_WRITE_FUNC(NAME, FUNCNAME) \
113    static void FUNCNAME(osgDB::OutputStream& os, int value) { \
114        if (os.isBinary()) os << value; \
115        else os << (s_user_lookup_table_##NAME)._lookup.getString(value); } \
116
117class BaseSerializer : public osg::Referenced
118{
119    friend class ObjectWrapper;
120public:
121    enum Type
122    {
123        RW_UNDEFINED = 0, RW_USER, RW_OBJECT, RW_IMAGE, RW_LIST,
124        RW_BOOL, RW_SHORT, RW_USHORT, RW_INT, RW_UINT, RW_FLOAT, RW_DOUBLE,
125        RW_VEC2F, RW_VEC2D, RW_VEC3F, RW_VEC3D, RW_VEC4F, RW_VEC4D, RW_QUAT, RW_PLANE,
126        RW_MATRIXF, RW_MATRIXD, RW_MATRIX, RW_GLENUM, RW_STRING, RW_ENUM
127    };
128
129    BaseSerializer() : _version(0) {}
130    virtual bool read( InputStream&, osg::Object& ) = 0;
131    virtual bool write( OutputStream&, const osg::Object& ) = 0;
132    virtual const std::string& getName() const = 0;
133
134protected:
135    int _version;  // Library version when the serializer is added, or removed (neg value)
136};
137
138template<typename C>
139class UserSerializer : public BaseSerializer
140{
141public:
142    typedef bool (*Checker)( const C& );
143    typedef bool (*Reader)( InputStream&, C& );
144    typedef bool (*Writer)( OutputStream&, const C& );
145   
146    UserSerializer( const char* name, Checker cf, Reader rf, Writer wf )
147    : _name(name), _checker(cf), _reader(rf), _writer(wf) {}
148   
149    virtual bool read( InputStream& is, osg::Object& obj )
150    {
151        C& object = OBJECT_CAST<C&>(obj);
152        if ( is.isBinary() )
153        {
154            bool ok = false; is >> ok;
155            if ( !ok ) return true;
156        }
157        else
158        {
159            if ( !is.matchString(_name) )
160                return true;
161        }
162        return (*_reader)(is, object);
163    }
164   
165    virtual bool write( OutputStream& os, const osg::Object& obj )
166    {
167        const C& object = OBJECT_CAST<const C&>(obj);
168        bool ok = (*_checker)(object);
169        if ( os.isBinary() )
170        {
171            os << ok;
172            if ( !ok ) return true;
173        }
174        else
175        {
176            if ( !ok ) return true;
177            os << PROPERTY(_name.c_str());
178        }
179        return (*_writer)(os, object);
180    }
181   
182    virtual const std::string& getName() const { return _name; }
183   
184protected:
185    std::string _name;
186    Checker _checker;
187   
188public:
189    Reader _reader;
190    Writer _writer;
191};
192
193template<typename P>
194class TemplateSerializer : public BaseSerializer
195{
196public:
197    TemplateSerializer( const char* name )
198    : _name(name) {}
199   
200    virtual bool read( InputStream& is, osg::Object& obj ) = 0;
201    virtual bool write( OutputStream& os, const osg::Object& obj ) = 0;
202    virtual const std::string& getName() const { return _name; }
203   
204protected:
205    std::string _name;
206    P _defaultValue;
207};
208
209template<typename C, typename P>
210class PropByValSerializer : public TemplateSerializer<P>
211{
212public:
213    typedef TemplateSerializer<P> ParentType;
214    typedef P (C::*Getter)() const;
215    typedef void (C::*Setter)( P );
216   
217    PropByValSerializer( const char* name, P def, Getter gf, Setter sf, bool useHex=false )
218    : ParentType(name), _getter(gf), _setter(sf), _useHex(useHex)
219     { ParentType::_defaultValue = def; }
220   
221    virtual bool read( InputStream& is, osg::Object& obj )
222    {
223        C& object = OBJECT_CAST<C&>(obj);
224        P value;
225        if ( is.isBinary() )
226        {
227            is >> value;
228            if ( ParentType::_defaultValue!=value )
229                (object.*_setter)( value );
230        }
231        else if ( is.matchString(ParentType::_name) )
232        {
233            if ( _useHex ) is >> std::hex;
234            is >> value;
235            if ( _useHex ) is >> std::dec;
236            (object.*_setter)( value );
237        }
238        return true;
239    }
240   
241    virtual bool write( OutputStream& os, const osg::Object& obj )
242    {
243        const C& object = OBJECT_CAST<const C&>(obj);
244        P value = (object.*_getter)();
245        if ( os.isBinary() )
246        {
247            os << value;
248        }
249        else if ( ParentType::_defaultValue!=value )
250        {
251            os << PROPERTY((ParentType::_name).c_str());
252            if ( _useHex ) os << std::hex;
253            os << value;
254            if ( _useHex ) os << std::dec;
255            os << std::endl;
256        }
257        return true;
258    }
259   
260public:
261    Getter _getter;
262    Setter _setter;
263   
264protected:
265    bool _useHex;
266};
267
268template<typename C, typename P>
269class PropByRefSerializer : public TemplateSerializer<P>
270{
271public:
272    typedef TemplateSerializer<P> ParentType;
273    typedef const P& CP;
274    typedef CP (C::*Getter)() const;
275    typedef void (C::*Setter)( CP );
276   
277    PropByRefSerializer( const char* name, CP def, Getter gf, Setter sf )
278    : ParentType(name), _getter(gf), _setter(sf)
279     { ParentType::_defaultValue = def; }
280   
281    virtual bool read( InputStream& is, osg::Object& obj )
282    {
283        C& object = OBJECT_CAST<C&>(obj);
284        P value;
285        if ( is.isBinary() )
286        {
287            is >> value;
288            if ( ParentType::_defaultValue!=value )
289                (object.*_setter)( value );
290        }
291        else if ( is.matchString(ParentType::_name) )
292        {
293            is >> value;
294            (object.*_setter)( value );
295        }
296        return true;
297    }
298   
299    virtual bool write( OutputStream& os, const osg::Object& obj )
300    {
301        const C& object = OBJECT_CAST<const C&>(obj);
302        CP value = (object.*_getter)();
303        if ( os.isBinary() )
304        {
305            os << value;
306        }
307        else if ( ParentType::_defaultValue!=value )
308        {
309            os << PROPERTY((ParentType::_name).c_str()) << value << std::endl;
310        }
311        return true;
312    }
313   
314public:
315    Getter _getter;
316    Setter _setter;
317};
318
319template<typename C>
320class MatrixSerializer : public TemplateSerializer<osg::Matrix>
321{
322public:
323    typedef TemplateSerializer<osg::Matrix> ParentType;
324    typedef const osg::Matrix& (C::*Getter)() const;
325    typedef void (C::*Setter)( const osg::Matrix& );
326   
327    MatrixSerializer( const char* name, const osg::Matrix& def, Getter gf, Setter sf )
328    : ParentType(name), _getter(gf), _setter(sf)
329     { ParentType::_defaultValue = def; }
330   
331    virtual bool read( InputStream& is, osg::Object& obj )
332    {
333        C& object = OBJECT_CAST<C&>(obj);
334        osg::Matrix value;
335        if ( is.isBinary() )
336        {
337            readMatrixImplementation( is, value );
338            if ( ParentType::_defaultValue!=value )
339                (object.*_setter)( value );
340        }
341        else if ( is.matchString(ParentType::_name) )
342        {
343            readMatrixImplementation( is, value );
344            (object.*_setter)( value );
345        }
346        return true;
347    }
348   
349    virtual bool write( OutputStream& os, const osg::Object& obj )
350    {
351
352        const C& object = OBJECT_CAST<const C&>(obj);
353        const osg::Matrix& value = (object.*_getter)();
354        if ( os.isBinary() )
355        {
356            OSG_NOTICE<<"MatrixSerializer::write() binary"<<std::endl;
357            os << value;
358        }
359        else if ( ParentType::_defaultValue!=value )
360        {
361            OSG_NOTICE<<"MatrixSerializer::write() ascii, ParentType::_name="<<ParentType::_name<<std::endl;
362            os << PROPERTY((ParentType::_name).c_str()) << value << std::endl;
363        }
364        return true;
365    }
366   
367protected:
368    void readMatrixImplementation( InputStream& is, osg::Matrix& matrix )
369    {
370#if 1
371        is >> matrix;
372#else
373        if ( is.getUseFloatMatrix() )
374        {
375            osg::Matrixf realValue; is >> realValue;
376            matrix = realValue;
377        }
378        else
379        {
380            osg::Matrixd realValue; is >> realValue;
381            matrix = realValue;
382        }
383#endif
384    }
385   
386public:
387    Getter _getter;
388    Setter _setter;
389};
390
391template<typename C, typename P>
392class GLenumSerializer : public TemplateSerializer<P>
393{
394public:
395    typedef TemplateSerializer<P> ParentType;
396    typedef P (C::*Getter)() const;
397    typedef void (C::*Setter)( P );
398   
399    GLenumSerializer( const char* name, P def, Getter gf, Setter sf )
400    : ParentType(name), _getter(gf), _setter(sf)
401     { ParentType::_defaultValue = def; }
402   
403    virtual bool read( InputStream& is, osg::Object& obj )
404    {
405        C& object = OBJECT_CAST<C&>(obj);
406        if ( is.isBinary() )
407        {
408            GLenum value; is >> value;
409            if ( ParentType::_defaultValue!=static_cast<P>(value) )
410                (object.*_setter)( static_cast<P>(value) );
411        }
412        else if ( is.matchString(ParentType::_name) )
413        {
414            DEF_GLENUM(value); is >> value;
415            (object.*_setter)( static_cast<P>(value.get()) );
416        }
417        return true;
418    }
419   
420    virtual bool write( OutputStream& os, const osg::Object& obj )
421    {
422        const C& object = OBJECT_CAST<const C&>(obj);
423        const P value = (object.*_getter)();
424        if ( os.isBinary() )
425        {
426            os << static_cast<GLenum>(value);
427        }
428        else if ( ParentType::_defaultValue!=value )
429        {
430            os << PROPERTY((ParentType::_name).c_str()) << GLENUM(value) << std::endl;
431        }
432        return true;
433    }
434   
435public:
436    Getter _getter;
437    Setter _setter;
438};
439
440template<typename C>
441class StringSerializer : public TemplateSerializer<std::string>
442{
443public:
444    typedef TemplateSerializer<std::string> ParentType;
445    typedef const std::string& (C::*Getter)() const;
446    typedef void (C::*Setter)( const std::string& );
447   
448    StringSerializer( const char* name, const std::string& def, Getter gf, Setter sf )
449    : ParentType(name), _getter(gf), _setter(sf)
450     { ParentType::_defaultValue = def; }
451   
452    virtual bool read( InputStream& is, osg::Object& obj )
453    {
454        C& object = OBJECT_CAST<C&>(obj);
455        std::string value;
456        if ( is.isBinary() )
457        {
458            is >> value;
459            if ( ParentType::_defaultValue!=value )
460                (object.*_setter)( value );
461        }
462        else if ( is.matchString(ParentType::_name) )
463        {
464            is.readWrappedString( value );
465            if ( !value.empty() )
466                (object.*_setter)( value );
467        }
468        return true;
469    }
470   
471    virtual bool write( OutputStream& os, const osg::Object& obj )
472    {
473        const C& object = OBJECT_CAST<const C&>(obj);
474        const std::string& value = (object.*_getter)();
475        if ( os.isBinary() )
476        {
477            os << value;
478        }
479        else if ( ParentType::_defaultValue!=value )
480        {
481            os << PROPERTY((ParentType::_name).c_str());
482            os.writeWrappedString( value );
483            os << std::endl;
484        }
485        return true;
486    }
487   
488public:
489    Getter _getter;
490    Setter _setter;
491};
492
493template<typename C, typename P>
494class ObjectSerializer : public TemplateSerializer<P*>
495{
496public:
497    typedef TemplateSerializer<P*> ParentType;
498    typedef const P* (C::*Getter)() const;
499    typedef void (C::*Setter)( P* );
500   
501    ObjectSerializer( const char* name, P* def, Getter gf, Setter sf )
502    : ParentType(name), _getter(gf), _setter(sf)
503     { ParentType::_defaultValue = def; }
504   
505    virtual bool read( InputStream& is, osg::Object& obj )
506    {
507        C& object = OBJECT_CAST<C&>(obj);
508        bool hasObject = false;
509        if ( is.isBinary() )
510        {
511            is >> hasObject;
512            if ( hasObject )
513            {
514                P* value = dynamic_cast<P*>( is.readObject() );
515                if ( ParentType::_defaultValue!=value )
516                    (object.*_setter)( value );
517            }
518        }
519        else if ( is.matchString(ParentType::_name) )
520        {
521            is >> hasObject;
522            if ( hasObject )
523            {
524                is >> BEGIN_BRACKET;
525                P* value = dynamic_cast<P*>( is.readObject() );
526                if ( ParentType::_defaultValue!=value )
527                    (object.*_setter)( value );
528                is >> END_BRACKET;
529            }
530        }
531        return true;
532    }
533   
534    virtual bool write( OutputStream& os, const osg::Object& obj )
535    {
536        const C& object = OBJECT_CAST<const C&>(obj);
537        const P* value = (object.*_getter)();
538        bool hasObject = (value!=NULL);
539        if ( os.isBinary() )
540        {
541            os << hasObject;
542            os.writeObject( value );
543        }
544        else if ( ParentType::_defaultValue!=value )
545        {
546            os << PROPERTY((ParentType::_name).c_str()) << hasObject;
547            if ( hasObject )
548            {
549                os << BEGIN_BRACKET << std::endl;
550                os.writeObject( value );
551                os << END_BRACKET;
552            }
553            os << std::endl;
554        }
555        return true;
556    }
557   
558public:
559    Getter _getter;
560    Setter _setter;
561};
562
563template<typename C, typename P>
564class ImageSerializer : public TemplateSerializer<P*>
565{
566public:
567    typedef TemplateSerializer<P*> ParentType;
568    typedef const P* (C::*Getter)() const;
569    typedef void (C::*Setter)( P* );
570   
571    ImageSerializer( const char* name, P* def, Getter gf, Setter sf )
572    : ParentType(name), _getter(gf), _setter(sf)
573     { ParentType::_defaultValue = def; }
574   
575    virtual bool read( InputStream& is, osg::Object& obj )
576    {
577        C& object = OBJECT_CAST<C&>(obj);
578        bool hasObject = false;
579        if ( is.isBinary() )
580        {
581            is >> hasObject;
582            if ( hasObject )
583            {
584                P* value = dynamic_cast<P*>( is.readImage() );
585                if ( ParentType::_defaultValue!=value )
586                    (object.*_setter)( value );
587            }
588        }
589        else if ( is.matchString(ParentType::_name) )
590        {
591            is >> hasObject;
592            if ( hasObject )
593            {
594                is >> BEGIN_BRACKET;
595                P* value = dynamic_cast<P*>( is.readImage() );
596                if ( ParentType::_defaultValue!=value )
597                    (object.*_setter)( value );
598                is >> END_BRACKET;
599            }
600        }
601        return true;
602    }
603   
604    virtual bool write( OutputStream& os, const osg::Object& obj )
605    {
606        const C& object = OBJECT_CAST<const C&>(obj);
607        const P* value = (object.*_getter)();
608        bool hasObject = (value!=NULL);
609        if ( os.isBinary() )
610        {
611            os << hasObject;
612            os.writeImage( value );
613        }
614        else if ( ParentType::_defaultValue!=value )
615        {
616            os << PROPERTY((ParentType::_name).c_str()) << hasObject;
617            if ( hasObject )
618            {
619                os << BEGIN_BRACKET << std::endl;
620                os.writeImage( value );
621                os << END_BRACKET;
622            }
623            os << std::endl;
624        }
625        return true;
626    }
627   
628public:
629    Getter _getter;
630    Setter _setter;
631};
632
633template<typename C, typename P, typename B>
634class EnumSerializer : public TemplateSerializer<P>
635{
636public:
637    typedef TemplateSerializer<P> ParentType;
638    typedef P (C::*Getter)() const;
639    typedef B (C::*Setter)( P );
640   
641    EnumSerializer( const char* name, P def, Getter gf, Setter sf )
642    : ParentType(name), _getter(gf), _setter(sf)
643     { ParentType::_defaultValue = def; }
644   
645    void add( const char* str, P value )
646    { _lookup.add(str, static_cast<IntLookup::Value>(value)); }
647   
648    P getValue( const char* str )
649    { return static_cast<P>(_lookup.getValue(str)); }
650   
651    const std::string& getString( P value )
652    { return _lookup.getString(static_cast<IntLookup::Value>(value)); }
653   
654    virtual bool read( InputStream& is, osg::Object& obj )
655    {
656        C& object = OBJECT_CAST<C&>(obj);
657        IntLookup::Value value;
658        if ( is.isBinary() )
659        {
660            is >> value;
661            if ( ParentType::_defaultValue!=static_cast<P>(value) )
662                (object.*_setter)( static_cast<P>(value) );
663        }
664        else if ( is.matchString(ParentType::_name) )
665        {
666            std::string str; is >> str;
667            (object.*_setter)( getValue(str.c_str()) );
668        }
669        return true;
670    }
671   
672    virtual bool write( osgDB::OutputStream& os, const osg::Object& obj )
673    {
674        const C& object = OBJECT_CAST<const C&>(obj);
675        const P value = (object.*_getter)();
676        if ( os.isBinary() )
677        {
678            os << (IntLookup::Value)value;
679        }
680        else if ( ParentType::_defaultValue!=value )
681        {
682            os << PROPERTY((ParentType::_name).c_str()) << getString(value) << std::endl;
683        }
684        return true;
685    }
686   
687public:
688    Getter _getter;
689    Setter _setter;
690   
691protected:
692    IntLookup _lookup;
693};
694
695template<typename C, typename P>
696class ListSerializer : public TemplateSerializer<P>
697{
698public:
699    typedef TemplateSerializer<P> ParentType;
700    typedef typename P::value_type ValueType;
701    typedef typename P::const_iterator ConstIterator;
702    typedef const P& (C::*Getter)() const;
703    typedef void (C::*Setter)( const P& );
704   
705    ListSerializer( const char* name, Getter gf, Setter sf )
706    : ParentType(name), _getter(gf), _setter(sf) {}
707   
708    virtual bool read( InputStream& is, osg::Object& obj )
709    {
710        C& object = OBJECT_CAST<C&>(obj);
711        unsigned int size = 0;
712        P list;
713        if ( is.isBinary() )
714        {
715            is >> size;
716            for ( unsigned int i=0; i<size; ++i )
717            {
718                ValueType value;
719                is >> value;
720                list.push_back( value );
721            }
722            if ( size>0 ) (object.*_setter)( list );
723        }
724        else if ( is.matchString(ParentType::_name) )
725        {
726            is >> size;
727            if ( size>0 ) is >> BEGIN_BRACKET;
728            for ( unsigned int i=0; i<size; ++i )
729            {
730                ValueType value;
731                is >> value;
732                list.push_back( value );
733            }
734            if ( size>0 )
735            {
736                is >> END_BRACKET;
737                (object.*_setter)( list );
738            }
739        }
740        return true;
741    }
742   
743    virtual bool write( OutputStream& os, const osg::Object& obj )
744    {
745        const C& object = OBJECT_CAST<const C&>(obj);
746        const P& list = (object.*_getter)();
747        unsigned int size = (unsigned int)list.size();
748        if ( os.isBinary() )
749        {
750            os << size;
751            for ( ConstIterator itr=list.begin();
752                  itr!=list.end(); ++itr )
753            {
754                os << (*itr);
755            }
756        }
757        else if ( size>0 )
758        {
759            os << PROPERTY((ParentType::_name).c_str()) << size << BEGIN_BRACKET << std::endl;
760            for ( ConstIterator itr=list.begin();
761                  itr!=list.end(); ++itr )
762            {
763                os << (*itr);
764            }
765            os << std::endl;
766            os << END_BRACKET << std::endl;
767        }
768        return true;
769    }
770   
771public:
772    Getter _getter;
773    Setter _setter;
774};
775
776// ADDING MANIPULATORS
777#define ADD_SERIALIZER(S) \
778    wrapper->addSerializer( (S) )
779
780#define ADD_USER_SERIALIZER(PROP) \
781    wrapper->addSerializer( new osgDB::UserSerializer<MyClass>( \
782        #PROP, &check##PROP, &read##PROP, &write##PROP), osgDB::BaseSerializer::RW_USER )
783
784#define ADD_BOOL_SERIALIZER(PROP, DEF) \
785    wrapper->addSerializer( new osgDB::PropByValSerializer< MyClass, bool >( \
786        #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_BOOL )
787
788#define ADD_SHORT_SERIALIZER(PROP, DEF) \
789    wrapper->addSerializer( new osgDB::PropByValSerializer< MyClass, short >( \
790        #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_SHORT )
791
792#define ADD_USHORT_SERIALIZER(PROP, DEF) \
793    wrapper->addSerializer( new osgDB::PropByValSerializer< MyClass, unsigned short >( \
794        #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_USHORT )
795
796#define ADD_HEXSHORT_SERIALIZER(PROP, DEF) \
797    wrapper->addSerializer( new osgDB::PropByValSerializer< MyClass, unsigned short >( \
798        #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP, true), osgDB::BaseSerializer::RW_USHORT )
799
800#define ADD_INT_SERIALIZER(PROP, DEF) \
801    wrapper->addSerializer( new osgDB::PropByValSerializer< MyClass, int >( \
802        #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_INT )
803
804#define ADD_UINT_SERIALIZER(PROP, DEF) \
805    wrapper->addSerializer( new osgDB::PropByValSerializer< MyClass, unsigned int >( \
806        #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_UINT )
807       
808#define ADD_GLINT_SERIALIZER(PROP, DEF) \
809    wrapper->addSerializer( new osgDB::PropByValSerializer< MyClass, GLint >( \
810        #PROP, ((int)(DEF)), &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_INT )
811
812#define ADD_HEXINT_SERIALIZER(PROP, DEF) \
813    wrapper->addSerializer( new osgDB::PropByValSerializer< MyClass, unsigned int >( \
814        #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP, true), osgDB::BaseSerializer::RW_UINT )
815
816#define ADD_FLOAT_SERIALIZER(PROP, DEF) \
817    wrapper->addSerializer( new osgDB::PropByValSerializer< MyClass, float >( \
818        #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_FLOAT )
819
820#define ADD_DOUBLE_SERIALIZER(PROP, DEF) \
821    wrapper->addSerializer( new osgDB::PropByValSerializer< MyClass, double >( \
822        #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_DOUBLE )
823
824#define ADD_VEC2F_SERIALIZER(PROP, DEF) \
825    wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::Vec2f >( \
826        #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_VEC2F )
827
828#define ADD_VEC2D_SERIALIZER(PROP, DEF) \
829    wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::Vec2d >( \
830        #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_VEC2D )
831
832#define ADD_VEC2_SERIALIZER(PROP, DEF) ADD_VEC2F_SERIALIZER(PROP, DEF)
833
834#define ADD_VEC3F_SERIALIZER(PROP, DEF) \
835    wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::Vec3f >( \
836        #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_VEC3F )
837
838#define ADD_VEC3D_SERIALIZER(PROP, DEF) \
839    wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::Vec3d >( \
840        #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_VEC3D )
841
842#define ADD_VEC3_SERIALIZER(PROP, DEF) ADD_VEC3F_SERIALIZER(PROP, DEF)
843
844#define ADD_VEC4F_SERIALIZER(PROP, DEF) \
845    wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::Vec4f >( \
846        #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_VEC4F )
847
848#define ADD_VEC4D_SERIALIZER(PROP, DEF) \
849    wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::Vec4d >( \
850        #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_VEC4D )
851
852#define ADD_VEC4_SERIALIZER(PROP, DEF) ADD_VEC4F_SERIALIZER(PROP, DEF)
853
854#define ADD_QUAT_SERIALIZER(PROP, DEF) \
855    wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::Quat >( \
856        #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_QUAT )
857
858#define ADD_PLANE_SERIALIZER(PROP, DEF) \
859    wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::Plane >( \
860        #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_PLANE )
861
862#define ADD_MATRIXF_SERIALIZER(PROP, DEF) \
863    wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::Matrixf >( \
864        #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_MATRIXF )
865
866#define ADD_MATRIXD_SERIALIZER(PROP, DEF) \
867    wrapper->addSerializer( new osgDB::PropByRefSerializer< MyClass, osg::Matrixd >( \
868        #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_MATRIXD )
869
870#define ADD_MATRIX_SERIALIZER(PROP, DEF) \
871    wrapper->addSerializer( new osgDB::MatrixSerializer< MyClass >( \
872        #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_MATRIX )
873
874#define ADD_GLENUM_SERIALIZER(PROP, TYPE, DEF) \
875    wrapper->addSerializer( new osgDB::GLenumSerializer< MyClass, TYPE >( \
876        #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_GLENUM )
877
878#define ADD_STRING_SERIALIZER(PROP, DEF) \
879    wrapper->addSerializer( new osgDB::StringSerializer< MyClass >( \
880        #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_STRING )
881
882#define ADD_OBJECT_SERIALIZER(PROP, TYPE, DEF) \
883    wrapper->addSerializer( new osgDB::ObjectSerializer< MyClass, TYPE >( \
884        #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_OBJECT )
885
886#define ADD_IMAGE_SERIALIZER(PROP, TYPE, DEF) \
887    wrapper->addSerializer( new osgDB::ImageSerializer< MyClass, TYPE >( \
888        #PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_IMAGE )
889
890#define ADD_LIST_SERIALIZER(PROP, TYPE) \
891    wrapper->addSerializer( new osgDB::ListSerializer< MyClass, TYPE >( \
892        #PROP, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_LIST )
893
894#define BEGIN_ENUM_SERIALIZER(PROP, DEF) \
895    { typedef osgDB::EnumSerializer<MyClass, MyClass::PROP, void> MySerializer; \
896    osg::ref_ptr<MySerializer> serializer = new MySerializer( \
897        #PROP, MyClass::DEF, &MyClass::get##PROP, &MyClass::set##PROP)
898
899#define BEGIN_ENUM_SERIALIZER2(PROP, TYPE, DEF) \
900    { typedef osgDB::EnumSerializer<MyClass, TYPE, void> MySerializer; \
901    osg::ref_ptr<MySerializer> serializer = new MySerializer( \
902        #PROP, MyClass::DEF, &MyClass::get##PROP, &MyClass::set##PROP)
903
904#define BEGIN_ENUM_SERIALIZER3(PROP, DEF) \
905    { typedef osgDB::EnumSerializer<MyClass, MyClass::PROP, bool> MySerializer; \
906    osg::ref_ptr<MySerializer> serializer = new MySerializer( \
907        #PROP, MyClass::DEF, &MyClass::get##PROP, &MyClass::set##PROP)
908
909#define BEGIN_ENUM_SERIALIZER4(PROPERTIES_CLASS, PROP, DEF) \
910    { typedef osgDB::EnumSerializer<MyClass, PROPERTIES_CLASS::PROP, void> MySerializer; \
911    osg::ref_ptr<MySerializer> serializer = new MySerializer( \
912        #PROP, PROPERTIES_CLASS::DEF, &MyClass::get##PROP, &MyClass::set##PROP)
913
914#define ADD_ENUM_VALUE(VALUE) \
915    serializer->add(#VALUE, MyClass::VALUE)
916
917#define ADD_ENUM_CLASS_VALUE(CLASS, VALUE) \
918    serializer->add(#VALUE, CLASS::VALUE)
919
920#define END_ENUM_SERIALIZER() \
921    wrapper->addSerializer(serializer.get(), osgDB::BaseSerializer::RW_ENUM); }
922
923// VERSION CONTROL OPERATORS
924#define UPDATE_TO_VERSION(VER) \
925    wrapper->setUpdatedVersion( (VER) );
926
927#define REMOVE_SERIALIZER(PROP) \
928    wrapper->markSerializerAsRemoved( #PROP );
929
930}
931
932#endif
Note: See TracBrowser for help on using the browser.