378 lines
10 KiB
Plaintext
378 lines
10 KiB
Plaintext
|
/* -*-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
|
||
|
|