dust3d/third_party/libigl/include/igl/xml/XMLSerializable.h

226 lines
6.1 KiB
C++

#ifndef IGL_XML_XMLSERIALIZABLE_H
#define IGL_XML_XMLSERIALIZABLE_H
#include "serialize_xml.h"
#include "../igl_inline.h"
#include "../serialize.h"
#include <tinyxml2.h>
// Interface for xml-serializable class see serialize_xml.h
// Pretty sure all of these IGL_INLINE should be inline
namespace igl
{
namespace xml
{
// interface for user defined types
struct XMLSerializableBase : public SerializableBase
{
virtual void Serialize(std::vector<char>& buffer) const = 0;
virtual void Deserialize(const std::vector<char>& buffer) = 0;
virtual void Serialize(tinyxml2::XMLDocument* doc,tinyxml2::XMLElement* element) const = 0;
virtual void Deserialize(const tinyxml2::XMLDocument* doc,const tinyxml2::XMLElement* element) = 0;
};
// Convenient interface for user defined types
class XMLSerializable: public XMLSerializableBase
{
private:
template <typename T>
struct XMLSerializationObject: public XMLSerializableBase
{
bool Binary;
std::string Name;
T* Object;
void Serialize(std::vector<char>& buffer) const {
serialize(*Object,Name,buffer);
}
void Deserialize(const std::vector<char>& buffer) {
deserialize(*Object,Name,buffer);
}
void Serialize(tinyxml2::XMLDocument* doc,tinyxml2::XMLElement* element) const {
serialize_xml(*Object,Name,doc,element,Binary);
}
void Deserialize(const tinyxml2::XMLDocument* doc,const tinyxml2::XMLElement* element) {
deserialize_xml(*Object,Name,doc,element);
}
};
mutable bool initialized;
mutable std::vector<XMLSerializableBase*> objects;
public:
// Override this function to add your member variables which should be serialized
IGL_INLINE virtual void InitSerialization() = 0;
// Following functions can be overridden to handle the specific events.
// Return false to prevent the de-/serialization of an object.
IGL_INLINE virtual bool PreSerialization() const;
IGL_INLINE virtual void PostSerialization() const;
IGL_INLINE virtual bool PreDeserialization();
IGL_INLINE virtual void PostDeserialization();
// Default implementation of XMLSerializableBase interface
IGL_INLINE void Serialize(std::vector<char>& buffer) const;
IGL_INLINE void Deserialize(const std::vector<char>& buffer);
IGL_INLINE void Serialize(tinyxml2::XMLDocument* doc,tinyxml2::XMLElement* element) const;
IGL_INLINE void Deserialize(const tinyxml2::XMLDocument* doc,const tinyxml2::XMLElement* element);
// Default constructor, destructor, assignment and copy constructor
IGL_INLINE XMLSerializable();
IGL_INLINE XMLSerializable(const XMLSerializable& obj);
IGL_INLINE ~XMLSerializable();
IGL_INLINE XMLSerializable& operator=(const XMLSerializable& obj);
// Use this function to add your variables which should be serialized
template <typename T>
IGL_INLINE void Add(T& obj,std::string name,bool binary = false);
};
// IMPLEMENTATION
IGL_INLINE bool XMLSerializable::PreSerialization() const
{
return true;
}
IGL_INLINE void XMLSerializable::PostSerialization() const
{
}
IGL_INLINE bool XMLSerializable::PreDeserialization()
{
return true;
}
IGL_INLINE void XMLSerializable::PostDeserialization()
{
}
IGL_INLINE void XMLSerializable::Serialize(std::vector<char>& buffer) const
{
if(this->PreSerialization())
{
if(initialized == false)
{
objects.clear();
(const_cast<XMLSerializable*>(this))->InitSerialization();
initialized = true;
}
for(unsigned int i=0;i<objects.size();i++)
objects[i]->Serialize(buffer);
this->PostSerialization();
}
}
IGL_INLINE void XMLSerializable::Deserialize(const std::vector<char>& buffer)
{
if(this->PreDeserialization())
{
if(initialized == false)
{
objects.clear();
(const_cast<XMLSerializable*>(this))->InitSerialization();
initialized = true;
}
for(unsigned int i=0;i<objects.size();i++)
objects[i]->Deserialize(buffer);
this->PostDeserialization();
}
}
IGL_INLINE void XMLSerializable::Serialize(tinyxml2::XMLDocument* doc,tinyxml2::XMLElement* element) const
{
if(this->PreSerialization())
{
if(initialized == false)
{
objects.clear();
(const_cast<XMLSerializable*>(this))->InitSerialization();
initialized = true;
}
for(unsigned int i=0;i<objects.size();i++)
objects[i]->Serialize(doc,element);
this->PostSerialization();
}
}
IGL_INLINE void XMLSerializable::Deserialize(const tinyxml2::XMLDocument* doc,const tinyxml2::XMLElement* element)
{
if(this->PreDeserialization())
{
if(initialized == false)
{
objects.clear();
(const_cast<XMLSerializable*>(this))->InitSerialization();
initialized = true;
}
for(unsigned int i=0;i<objects.size();i++)
objects[i]->Deserialize(doc,element);
this->PostDeserialization();
}
}
IGL_INLINE XMLSerializable::XMLSerializable()
{
initialized = false;
}
IGL_INLINE XMLSerializable::XMLSerializable(const XMLSerializable& obj)
{
initialized = false;
objects.clear();
}
IGL_INLINE XMLSerializable::~XMLSerializable()
{
initialized = false;
objects.clear();
}
IGL_INLINE XMLSerializable& XMLSerializable::operator=(const XMLSerializable& obj)
{
if(this != &obj)
{
if(initialized)
{
initialized = false;
objects.clear();
}
}
return *this;
}
template <typename T>
IGL_INLINE void XMLSerializable::Add(T& obj,std::string name,bool binary)
{
XMLSerializationObject<T>* object = new XMLSerializationObject<T>();
object->Binary = binary;
object->Name = name;
object->Object = &obj;
objects.push_back(object);
}
}
}
#endif