/* -*-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 #include #include namespace osgDB { class IntLookup { public: typedef int Value; IntLookup(Value defaultValue): _default(defaultValue) {} typedef std::map StringToValue; typedef std::map 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 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(value), str); } P getValue(const char* str) { return static_cast

(_lookup.getValue(str)); } const std::string& getString(P value) { return _lookup.getString(static_cast(value)); } bool write(osgDB::Output& fw, const osg::Object& obj) { const C& object = static_cast(obj); if (fw.getWriteOutDefaultValues() || _default != (object.*_getter)()) { fw.indent()<<_fieldName<<" "<(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 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(obj); if (fw.getWriteOutDefaultValues() || _default != (object.*_getter)()) { fw.indent()<<_fieldName<<" "<(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 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(obj); if (fw.getWriteOutDefaultValues() || _default != (object.*_getter)()) { fw.indent()<<_fieldName<<" "<<(object.*_getter)()<(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 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(obj); if (fw.getWriteOutDefaultValues() || _default != (object.*_getter)()) { fw.indent()<<_fieldName<<" "<<(object.*_getter)()<(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 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(obj); if (fw.getWriteOutDefaultValues() || _default != (object.*_getter)()) { fw.indent()<<_fieldName<<" "<<((object.*_getter)() ? "TRUE" : "FALSE")<(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( \ #PROPERTY, \ PROTOTYPE.get##PROPERTY(), \ &CLASS::get##PROPERTY, \ &CLASS::set##PROPERTY) #define CREATE_UINT_SERIALIZER(CLASS,PROPERTY,PROTOTYPE) \ new osgDB::TemplateSerializer( \ #PROPERTY, \ PROTOTYPE.get##PROPERTY(), \ &CLASS::get##PROPERTY, \ &CLASS::set##PROPERTY) #define CREATE_INT_SERIALIZER(CLASS,PROPERTY,PROTOTYPE) \ new osgDB::TemplateSerializer( \ #PROPERTY, \ PROTOTYPE.get##PROPERTY(), \ &CLASS::get##PROPERTY, \ &CLASS::set##PROPERTY) #define CREATE_FLOAT_SERIALIZER(CLASS,PROPERTY,PROTOTYPE) \ new osgDB::TemplateSerializer( \ #PROPERTY, \ PROTOTYPE.get##PROPERTY(), \ &CLASS::get##PROPERTY, \ &CLASS::set##PROPERTY) #define CREATE_DOUBLE_SERIALIZER(CLASS,PROPERTY,PROTOTYPE) \ new osgDB::TemplateSerializer( \ #PROPERTY, \ PROTOTYPE.get##PROPERTY(), \ &CLASS::get##PROPERTY, \ &CLASS::set##PROPERTY) #define CREATE_VEC4_SERIALIZER(CLASS,PROPERTY,PROTOTYPE) \ new osgDB::Vec4Serializer( \ #PROPERTY, \ PROTOTYPE.get##PROPERTY(), \ &CLASS::get##PROPERTY, \ &CLASS::set##PROPERTY) #define CREATE_BOOL_SERIALIZER(CLASS,PROPERTY,PROTOTYPE) \ new osgDB::BoolSerializer( \ #PROPERTY, \ PROTOTYPE.get##PROPERTY(), \ &CLASS::get##PROPERTY, \ &CLASS::set##PROPERTY) } #endif