Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #ifndef PROJECT_DEFINES
- #define PROJECT_DEFINES
- #define EXTEND_NVI(class_name) \
- virtual void class_name ## _save( StreamWrapper &out, const quint32 p_version = 0 ) = 0;\
- virtual void class_name ## _load( StreamWrapper &in, const quint32 p_version = 0 ) = 0;
- #endif // PROJECT_DEFINES
- #ifndef SERIALIZABLE_H
- #define SERIALIZABLE_H
- #include <QObject>
- #include <QDataStream>
- #include <boost/serialization/access.hpp>
- #include <boost/serialization/version.hpp>
- #include <boost/serialization/split_member.hpp>
- #include "Utilities/project_defines.hpp"
- #include "streamwrapper.h"
- class Serializable : public QObject
- {
- Q_OBJECT
- friend class boost::serialization::access;
- EXTEND_NVI( Serializable )
- quint32 m_ID;
- quint16 m_version;
- protected:
- quint32 ID() const;
- void setID( const quint32 &ID );
- quint16 version() const;
- void setVersion( const quint16 &version );
- public:
- explicit Serializable( quint32 p_ID, QObject *parent = 0 ) : QObject( parent ),
- m_ID( p_ID ) {}
- virtual ~Serializable() {}
- BOOST_SERIALIZATION_SPLIT_MEMBER()
- template <typename Stream>
- void save( Stream &out, const quint32 p_version = 0 )
- {
- StreamWrapper stream( out );
- stream << m_ID << m_version;
- Serializable_save( stream, p_version );
- }
- template <typename Stream>
- void load( Stream &in, const quint32 p_version = 0 )
- {
- StreamWrapper stream( in );
- stream >> m_ID >> m_version;
- Serializable_load( stream, p_version );
- }
- };
- template <class Archive>
- Archive &operator << ( Archive &out, const Serializable &module )
- {
- module.save( out );
- return out;
- }
- template <class Archive>
- Archive &operator >> ( Archive &in, Serializable &module )
- {
- module.load( in );
- return in;
- }
- #endif // SERIALIZABLE_H
- #ifndef STREAMWRAPPER_H
- #define STREAMWRAPPER_H
- #include "streamholder.h"
- class StreamWrapper
- {
- Stream_I *m_stream_holder; // Smart pointers...?
- Stream_I &m_stream; // Convenience of use.
- public:
- template < typename Stream >
- explicit StreamWrapper( Stream &p_stream ) : // Implicit creation gave me problems so for now I made the ctor explicit.
- m_stream_holder( new StreamHolder<Stream>( p_stream ) ),
- m_stream( *m_stream_holder )
- {}
- inline StreamWrapper &operator <<( ModuleWrapper p_module ) { m_stream << p_module; return *this; }
- inline StreamWrapper &operator >>( ModuleWrapper p_module ) { m_stream >> p_module; return *this; }
- ~StreamWrapper() { delete m_stream_holder; }
- };
- #endif // STREAMWRAPPER_H
- #ifndef STREAM_I_H
- #define STREAM_I_H
- #include "modulewrapper.h"
- class Stream_I
- {
- public:
- Stream_I();
- virtual ~Stream_I() {}
- virtual void operator << ( ModuleWrapper &p_module ) = 0;
- virtual void operator >> ( ModuleWrapper &p_module ) = 0;
- };
- #endif // STREAM_I_H
- #ifndef STREAMHOLDER_H
- #define STREAMHOLDER_H
- #include "stream_i.h"
- template <typename Stream>
- class StreamHolder : public Stream_I
- {
- Stream &m_stream;
- public:
- StreamHolder( Stream &p_stream ) : m_stream( p_stream ) {}
- // Note '<<' & '>>' reversal.
- // The now-concrete stream type is sent to the module for it to send itself into the stream.
- // Visitor pattern stuff.
- inline virtual void operator << ( ModuleWrapper &p_module ) { p_module >> m_stream; }
- inline virtual void operator >> ( ModuleWrapper &p_module ) { p_module << m_stream; }
- };
- #endif // STREAMHOLDER_H
- #ifndef MODULEWRAPPER_H
- #define MODULEWRAPPER_H
- #include "moduleholder.h"
- class ModuleWrapper
- {
- Module_I *m_module_holder;
- Module_I &m_module; // Convenience of use.
- public:
- template <typename Module>
- ModuleWrapper( Module &p_module ) :
- m_module_holder( new ModuleHolder<Module>( p_module ) ),
- m_module( *m_module_holder )
- {}
- // Fun fact: 'typename' and 'class' are synonymous in this context.
- // http://stackoverflow.com/questions/213121/use-class-or-typename-for-template-parameters
- // http://stackoverflow.com/questions/2023977/c-difference-of-keywords-typename-and-class-in-templates
- template <typename Stream>
- inline void operator << ( Stream &p_stream ) { m_module << p_stream; }
- template <class Stream>
- inline void operator >> ( Stream &p_stream ) { m_module >> p_stream; }
- ~ModuleWrapper() { delete m_module_holder; }
- };
- #endif // MODULEWRAPPER_H
- #ifndef MODULE_I_H
- #define MODULE_I_H
- #include <QDataStream>
- #include <boost/archive/text_iarchive.hpp>
- #include <boost/archive/text_oarchive.hpp>
- class Module_I
- {
- public:
- Module_I();
- virtual ~Module_I() {}
- // Here you have to give concrete types in order to get out of the generalization loop.
- // The module is the one activating '<<' or '>>'
- // so the directions regarding text_iarchive/oarchive are correct.
- inline virtual void operator <<( QDataStream p_stream ) = 0;
- inline virtual void operator >>( QDataStream p_stream ) = 0;
- inline virtual void operator <<( boost::archive::text_iarchive p_stream ) = 0;
- inline virtual void operator >>( boost::archive::text_oarchive p_stream ) = 0;
- };
- #endif // MODULE_I_H
- #ifndef MODULEHOLDER_H
- #define MODULEHOLDER_H
- #include "module_i.h"
- #include "qclassesserialization.h" // Define your ways of serializing QThings like this:
- //namespace boost
- //{
- //namespace serialization
- //{
- //// QString
- //template<class Archive>
- //void serialize( Archive &archive, QString &p_QString, const unsigned int file_version )
- //{
- // split_free( archive, p_QString, file_version );
- //}
- //template<class Archive>
- //void save( Archive &archive, const QString &p_QString, const unsigned int )
- //{
- // std::string std_string = p_QString.toStdString();
- // archive << BOOST_SERIALIZATION_NVP( std_string );
- //}
- //template<class Archive>
- //void load( Archive &archive, QString &p_QString, const unsigned int )
- //{
- // std::string std_string;
- // archive >> BOOST_SERIALIZATION_NVP( std_string );
- // p_QString = p_QString.fromStdString( std_string );
- //}
- template <typename Module>
- class ModuleHolder : public Module_I
- {
- Module &m_module;
- public:
- ModuleHolder( Module p_module ) : m_module( p_module ) {}
- // Finally, both types are concrete and the magic can happen.
- inline virtual void operator <<( QDataStream p_stream ) { p_stream >> m_module; }
- inline virtual void operator >>( QDataStream p_stream ) { p_stream << m_module; }
- inline virtual void operator <<( boost::archive::text_iarchive p_stream ) { p_stream >> m_module; }
- inline virtual void operator >>( boost::archive::text_oarchive p_stream ) { p_stream << m_module; }
- };
- #endif // MODULEHOLDER_H
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement