1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
|
#ifndef ODFAEG_SERIALIZATION_HPP
#define ODFAEG_SERIALIZATION_HPP
#include <iostream>
#include <sstream>
#include <typeinfo>
#include "tuple.h"
#include <tuple>
#include <map>
#include "fastDelegate.h"
#include "erreur.h"
#include "archive.h"
#define REGISTER_TYPE(ID, BASE, DERIVED) \
{ \
DERIVED *derived##ID = nullptr; \
odfaeg::Allocator<BASE> allocator##ID; \
BASE*(odfaeg::Allocator<BASE>::*f##ID)(DERIVED*) = &odfaeg::Allocator<BASE>::allocate<DERIVED>; \
odfaeg::FastDelegate<BASE*> allocatorDelegate##ID(f##ID, &allocator##ID, derived##ID); \
odfaeg::BaseFact<BASE>::register_type(typeid(DERIVED).name(), allocatorDelegate##ID); \
}
#define REGISTER_FUNC(ID, funcName, SID, BASE, DERIVED, SIGNATURE, args...) \
{ \
REGISTER_TYPE(ID, BASE, DERIVED) \
void(DERIVED::*f##ID##funcName##SID)SIGNATURE = &DERIVED::vt##funcName; \
odfaeg::FastDelegate<void> delegate##ID##funcName##SID (f##ID##funcName##SID, args); \
odfaeg::BaseFact<BASE>::register_function(typeid(DERIVED).name(), #funcName, #SID, delegate##ID##funcName##SID); \
}
#define CALL_FUNC(BASE, funcName, SID, object, args...) \
{ \
odfaeg::BaseFact<BASE>::callFunction(typeid(*object).name(), #funcName, #SID, object, args); \
}
#define EXPORT_CLASS_GUID(ID, BASE, DERIVED) \
{ \
REGISTER_TYPE(ID, BASE, DERIVED) \
std::ostringstream oss##ID; \
std::istringstream iss##ID; \
odfaeg::OTextArchive outa##ID(oss##ID); \
odfaeg::ITextArchive ina##ID(iss##ID); \
DERIVED* derived##ID = nullptr; \
REGISTER_FUNC(ID, serialize, OTextArchive, BASE, DERIVED, (odfaeg::OTextArchive&), derived##ID, std::ref(outa##ID)) \
REGISTER_FUNC(ID, serialize, ITextArchive, BASE, DERIVED, (odfaeg::ITextArchive&), derived##ID, std::ref(ina##ID)) \
}
namespace odfaeg {
template <typename B>
struct Allocator {
template <typename D>
B* allocate(D*) {
return new D();
}
};
template <typename B>
class BaseFact {
public :
static void register_type(std::string typeName, FastDelegate<B*> allocatorDelegate) {
typename std::map<std::string, FastDelegate<B*>>::iterator it = types.find(typeName);
if (it == types.end()) {
types[typeName] = allocatorDelegate;
}
}
static void register_function(std::string typeName, std::string funcName, std::string funcArgs, FastDelegate<void> delegate) {
typename std::map<std::string, FastDelegate<void>>::iterator it = functions.find(typeName+funcName+funcArgs);
if (it == functions.end())
functions[typeName+funcName+funcArgs] = delegate;
}
template <typename... A>
static void callFunction(std::string typeName, std::string funcName, std::string funcArgs, A&&... args) {
typename std::map<std::string, FastDelegate<void>>::iterator it = functions.find(typeName+funcName+funcArgs);
if (it != functions.end()) {
it->second.setParams(std::forward<A>(args)...);
(it->second)();
} else {
throw Erreur(0, "Unregistred function exception!", 1);
}
}
static B* create (std::string typeName) {
typename std::map<std::string, FastDelegate<B*>>::iterator it = types.find(typeName);
if (it != types.end()) {
return (it->second)();
}
throw Erreur(0, "Unregistred type exception!", 1);
}
static std::string getTypeName (B* type) {
typename std::map<std::string, FastDelegate<B*>>::iterator it = types.find(typeid(*type).name());
if (it != types.end())
return it->first;
}
private :
static std::map<std::string, FastDelegate<B*>> types;
static std::map<std::string, FastDelegate<void>> functions;
};
template <typename B>
std::map<std::string, FastDelegate<B*>> BaseFact<B>::types = std::map<std::string, FastDelegate<B*>>();
template <typename B>
std::map<std::string, FastDelegate<void>> BaseFact<B>::functions = std::map<std::string, FastDelegate<void>>();
template <class B>
class Serializer : public BaseFact<B> {
public :
Serializer() : BaseFact<B>() {
baseObject = nullptr;
}
void setObject(B* baseObject) {
this->baseObject = baseObject;
}
template <typename Archive>
void serialize(std::string funcName, std::string funcArgs, Archive & ar) {
BaseFact<B>::callFunction(typeid(*baseObject).name(), funcName, funcArgs, baseObject, std::ref(ar));
}
B* sallocate(std::string typeName) {
return BaseFact<B>::create(typeName);
}
std::string getTypeName() {
return BaseFact<B>::getTypeName(baseObject);
}
private :
B* baseObject;
};
}
#endif // SERIALIZATION |
Partager