OpenSceneGraph/include/osgDB/Serializer
2008-09-18 15:50:22 +00:00

378 lines
10 KiB
C++

/* -*-c++-*- VirtualPlanetBuilder - Copyright (C) 1998-2007 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.
*/
#ifndef SERIALIZER_H
#define SERIALIZER_H 1
#include <osgDB/Input>
#include <osgDB/Output>
#include <osgDB/ParameterOutput>
namespace osgDB
{
class IntLookup
{
public:
typedef int Value;
IntLookup(Value defaultValue):
_default(defaultValue) {}
typedef std::map<std::string, Value> StringToValue;
typedef std::map<Value, std::string> ValueToString;
StringToValue _stringToValue;
ValueToString _valueToString;
void add(Value value, const char* str)
{
_stringToValue[str] = value;
_valueToString[value] = str;
}
Value getValue(const char* str)
{
StringToValue::iterator itr = _stringToValue.find(str);
if (itr==_stringToValue.end()) return _default;
return itr->second;
}
const std::string& getString(Value value)
{
ValueToString::iterator itr = _valueToString.find(value);
if (itr==_valueToString.end()) return _valueToString[_default];
return itr->second;
}
Value _default;
};
class Serializer : public osg::Referenced
{
public:
Serializer() {}
virtual bool write(osgDB::Output&, const osg::Object&) = 0;
virtual bool read(osgDB::Input&, osg::Object&, bool&) = 0;
};
template<typename C, typename P>
class EnumSerializer : public Serializer
{
public:
typedef P (C::*GetterFunctionType)() const;
typedef void (C::*SetterFunctionType)(P);
EnumSerializer(const char* fieldName, P defaultValue, GetterFunctionType getter, SetterFunctionType setter):
_fieldName(fieldName),
_default(defaultValue),
_getter(getter),
_setter(setter),
_lookup(defaultValue) {}
void add(P value, const char* str)
{
_lookup.add(static_cast<IntLookup::Value>(value), str);
}
P getValue(const char* str)
{
return static_cast<P>(_lookup.getValue(str));
}
const std::string& getString(P value)
{
return _lookup.getString(static_cast<IntLookup::Value>(value));
}
bool write(osgDB::Output& fw, const osg::Object& obj)
{
const C& object = static_cast<const C&>(obj);
if (fw.getWriteOutDefaultValues() ||
_default != (object.*_getter)())
{
fw.indent()<<_fieldName<<" "<<getString((object.*_getter)())<<std::endl;
}
return true;
}
bool read(osgDB::Input& fr, osg::Object& obj, bool& itrAdvanced)
{
C& object = static_cast<C&>(obj);
if (fr[0].matchWord(_fieldName.c_str()) && fr[1].isWord())
{
(object.*_setter)(getValue(fr[1].getStr()));
fr += 2;
itrAdvanced = true;
}
return true;
}
std::string _fieldName;
P _default;
GetterFunctionType _getter;
SetterFunctionType _setter;
IntLookup _lookup;
};
template<typename C>
class StringSerializer : public Serializer
{
public:
typedef const std::string& P;
typedef P (C::*GetterFunctionType)() const;
typedef void (C::*SetterFunctionType)(P);
StringSerializer(const char* fieldName, P defaultValue, GetterFunctionType getter, SetterFunctionType setter):
_fieldName(fieldName),
_default(defaultValue),
_getter(getter),
_setter(setter) {}
bool write(osgDB::Output& fw, const osg::Object& obj)
{
const C& object = static_cast<const C&>(obj);
if (fw.getWriteOutDefaultValues() ||
_default != (object.*_getter)())
{
fw.indent()<<_fieldName<<" "<<fw.wrapString((object.*_getter)())<<std::endl;
}
return true;
}
bool read(osgDB::Input& fr, osg::Object& obj, bool& itrAdvanced)
{
C& object = static_cast<C&>(obj);
if (fr[0].matchWord(_fieldName.c_str()) && (fr[1].isWord() || fr[1].isString()))
{
(object.*_setter)(fr[1].getStr());
fr += 2;
itrAdvanced = true;
}
return true;
}
std::string _fieldName;
std::string _default;
GetterFunctionType _getter;
SetterFunctionType _setter;
};
template<typename C, typename P>
class TemplateSerializer : public Serializer
{
public:
typedef P (C::*GetterFunctionType)() const;
typedef void (C::*SetterFunctionType)(P);
TemplateSerializer(const char* fieldName, P defaultValue, GetterFunctionType getter, SetterFunctionType setter):
_fieldName(fieldName),
_default(defaultValue),
_getter(getter),
_setter(setter) {}
bool write(osgDB::Output& fw, const osg::Object& obj)
{
const C& object = static_cast<const C&>(obj);
if (fw.getWriteOutDefaultValues() ||
_default != (object.*_getter)())
{
fw.indent()<<_fieldName<<" "<<(object.*_getter)()<<std::endl;
}
return true;
}
bool read(osgDB::Input& fr, osg::Object& obj, bool& itrAdvanced)
{
C& object = static_cast<C&>(obj);
P value;
if (fr.read(_fieldName.c_str(), value))
{
(object.*_setter)(value);
itrAdvanced = true;
}
return true;
}
std::string _fieldName;
P _default;
GetterFunctionType _getter;
SetterFunctionType _setter;
};
template<typename C>
class Vec4Serializer : public Serializer
{
public:
typedef osg::Vec4 V;
typedef const V& P;
typedef P (C::*GetterFunctionType)() const;
typedef void (C::*SetterFunctionType)(P);
Vec4Serializer(const char* fieldName, P defaultValue, GetterFunctionType getter, SetterFunctionType setter):
_fieldName(fieldName),
_default(defaultValue),
_getter(getter),
_setter(setter) {}
bool write(osgDB::Output& fw, const osg::Object& obj)
{
const C& object = static_cast<const C&>(obj);
if (fw.getWriteOutDefaultValues() ||
_default != (object.*_getter)())
{
fw.indent()<<_fieldName<<" "<<(object.*_getter)()<<std::endl;
}
return true;
}
bool read(osgDB::Input& fr, osg::Object& obj, bool& itrAdvanced)
{
C& object = static_cast<C&>(obj);
V value;
if (fr.read(_fieldName.c_str(), value[0], value[1], value[2], value[3]))
{
(object.*_setter)(value);
fr += 2;
itrAdvanced = true;
}
return true;
}
std::string _fieldName;
V _default;
GetterFunctionType _getter;
SetterFunctionType _setter;
};
template<typename C>
class BoolSerializer : public Serializer
{
public:
typedef bool P;
typedef P (C::*GetterFunctionType)() const;
typedef void (C::*SetterFunctionType)(P);
BoolSerializer(const char* fieldName, P defaultValue, GetterFunctionType getter, SetterFunctionType setter):
_fieldName(fieldName),
_default(defaultValue),
_getter(getter),
_setter(setter) {}
bool write(osgDB::Output& fw, const osg::Object& obj)
{
const C& object = static_cast<const C&>(obj);
if (fw.getWriteOutDefaultValues() ||
_default != (object.*_getter)())
{
fw.indent()<<_fieldName<<" "<<((object.*_getter)() ? "TRUE" : "FALSE")<<std::endl;
}
return true;
}
bool read(osgDB::Input& fr, osg::Object& obj, bool& itrAdvanced)
{
C& object = static_cast<C&>(obj);
if (fr[0].matchWord(_fieldName.c_str()) && fr[1].isWord())
{
(object.*_setter)(fr[1].matchWord("TRUE") || fr[1].matchWord("True") || fr[1].matchWord("true"));
fr += 2;
itrAdvanced = true;
}
return true;
}
std::string _fieldName;
P _default;
GetterFunctionType _getter;
SetterFunctionType _setter;
};
#define CREATE_STRING_SERIALIZER(CLASS,PROPERTY,PROTOTYPE) \
new osgDB::StringSerializer<CLASS>( \
#PROPERTY, \
PROTOTYPE.get##PROPERTY(), \
&CLASS::get##PROPERTY, \
&CLASS::set##PROPERTY)
#define CREATE_UINT_SERIALIZER(CLASS,PROPERTY,PROTOTYPE) \
new osgDB::TemplateSerializer<CLASS,unsigned int>( \
#PROPERTY, \
PROTOTYPE.get##PROPERTY(), \
&CLASS::get##PROPERTY, \
&CLASS::set##PROPERTY)
#define CREATE_INT_SERIALIZER(CLASS,PROPERTY,PROTOTYPE) \
new osgDB::TemplateSerializer<CLASS, int>( \
#PROPERTY, \
PROTOTYPE.get##PROPERTY(), \
&CLASS::get##PROPERTY, \
&CLASS::set##PROPERTY)
#define CREATE_FLOAT_SERIALIZER(CLASS,PROPERTY,PROTOTYPE) \
new osgDB::TemplateSerializer<CLASS,float>( \
#PROPERTY, \
PROTOTYPE.get##PROPERTY(), \
&CLASS::get##PROPERTY, \
&CLASS::set##PROPERTY)
#define CREATE_DOUBLE_SERIALIZER(CLASS,PROPERTY,PROTOTYPE) \
new osgDB::TemplateSerializer<CLASS, double>( \
#PROPERTY, \
PROTOTYPE.get##PROPERTY(), \
&CLASS::get##PROPERTY, \
&CLASS::set##PROPERTY)
#define CREATE_VEC4_SERIALIZER(CLASS,PROPERTY,PROTOTYPE) \
new osgDB::Vec4Serializer<CLASS>( \
#PROPERTY, \
PROTOTYPE.get##PROPERTY(), \
&CLASS::get##PROPERTY, \
&CLASS::set##PROPERTY)
#define CREATE_BOOL_SERIALIZER(CLASS,PROPERTY,PROTOTYPE) \
new osgDB::BoolSerializer<CLASS>( \
#PROPERTY, \
PROTOTYPE.get##PROPERTY(), \
&CLASS::get##PROPERTY, \
&CLASS::set##PROPERTY)
}
#endif