fpmas 1.6
datapack_serializer.h
Go to the documentation of this file.
1#ifndef FPMAS_MODEL_DATAPACK_SERIALIZER_H
2#define FPMAS_MODEL_DATAPACK_SERIALIZER_H
3
8#include "serializer_set_up.h"
10#include "fpmas/io/datapack.h"
11#include "fpmas/model/model.h"
12
42#define FPMAS_BASE_DATAPACK_SET_UP(...)\
43 namespace fpmas { namespace io { namespace datapack {\
44 std::size_t Serializer<api::model::AgentPtr>\
45 ::size(const ObjectPack& p, const api::model::AgentPtr& data) {\
46 return AgentPtrSerializer<ObjectPack, __VA_ARGS__ , void>::size(p, data);\
47 }\
48 void Serializer<api::model::AgentPtr>\
49 ::to_datapack(ObjectPack& p, const api::model::AgentPtr& data) {\
50 AgentPtrSerializer<ObjectPack, __VA_ARGS__ , void>::to_datapack(p, data);\
51 }\
52 api::model::AgentPtr Serializer<api::model::AgentPtr>\
53 ::from_datapack(const ObjectPack& p) {\
54 return {AgentPtrSerializer<ObjectPack, __VA_ARGS__ , void>::from_datapack(p)};\
55 }\
56 \
57 std::size_t Serializer<api::model::WeakAgentPtr>\
58 ::size(const ObjectPack& p, const api::model::WeakAgentPtr& data) {\
59 return AgentPtrSerializer<ObjectPack, __VA_ARGS__ , void>::size(p, data);\
60 }\
61 void Serializer<api::model::WeakAgentPtr>\
62 ::to_datapack(ObjectPack& p, const api::model::WeakAgentPtr& data) {\
63 AgentPtrSerializer<ObjectPack, __VA_ARGS__ , void>::to_datapack(p, data);\
64 }\
65 api::model::WeakAgentPtr Serializer<api::model::WeakAgentPtr>\
66 ::from_datapack(const ObjectPack& p) {\
67 return AgentPtrSerializer<ObjectPack, __VA_ARGS__ , void>::from_datapack(p);\
68 }\
69 \
70 std::size_t LightSerializer<api::model::AgentPtr>\
71 ::size(const LightObjectPack& p, const api::model::AgentPtr& data) {\
72 return AgentPtrSerializer<LightObjectPack, __VA_ARGS__ , void>::size(p, data);\
73 }\
74 void LightSerializer<api::model::AgentPtr>\
75 ::to_datapack(LightObjectPack& p, const api::model::AgentPtr& data) {\
76 AgentPtrSerializer<LightObjectPack, __VA_ARGS__ , void>::to_datapack(p, data);\
77 }\
78 api::model::AgentPtr LightSerializer<api::model::AgentPtr>::from_datapack(const LightObjectPack& p) {\
79 return {AgentPtrSerializer<LightObjectPack, __VA_ARGS__ , void>::from_datapack(p)};\
80 }\
81 \
82 std::size_t LightSerializer<api::model::WeakAgentPtr>\
83 ::size(const LightObjectPack& p, const api::model::WeakAgentPtr& data) {\
84 return AgentPtrSerializer<LightObjectPack, __VA_ARGS__ , void>::size(p, data);\
85 }\
86 void LightSerializer<api::model::WeakAgentPtr>\
87 ::to_datapack(LightObjectPack& p, const api::model::WeakAgentPtr& data) {\
88 AgentPtrSerializer<LightObjectPack, __VA_ARGS__ , void>::to_datapack(p, data);\
89 }\
90 api::model::WeakAgentPtr LightSerializer<api::model::WeakAgentPtr>\
91 ::from_datapack(const LightObjectPack& p) {\
92 return AgentPtrSerializer<LightObjectPack, __VA_ARGS__ , void>::from_datapack(p);\
93 }\
94 }}}
95
100#define FPMAS_BASE_DEFAULT_DATAPACK_SET_UP() \
101 namespace fpmas { namespace io { namespace datapack {\
102 std::size_t Serializer<fpmas::api::model::AgentPtr>::size(const ObjectPack& o, const fpmas::api::model::AgentPtr& data) {\
103 return AgentPtrSerializer<ObjectPack, void>::size(o, data);\
104 }\
105 void Serializer<fpmas::api::model::AgentPtr>::to_datapack(ObjectPack& o, const fpmas::api::model::AgentPtr& data) {\
106 AgentPtrSerializer<ObjectPack, void>::to_datapack(o, data);\
107 }\
108 fpmas::api::model::AgentPtr Serializer<fpmas::api::model::AgentPtr>::from_datapack(const ObjectPack& o) {\
109 return {AgentPtrSerializer<ObjectPack, void>::from_datapack(o)};\
110 }\
111 \
112 std::size_t Serializer<fpmas::api::model::WeakAgentPtr>::size(const ObjectPack& o, const fpmas::api::model::WeakAgentPtr& data) {\
113 return AgentPtrSerializer<ObjectPack, void>::size(o, data);\
114 }\
115 void Serializer<fpmas::api::model::WeakAgentPtr>\
116 ::to_datapack(ObjectPack& o, const fpmas::api::model::WeakAgentPtr& data) {\
117 AgentPtrSerializer<ObjectPack, void>::to_datapack(o, data);\
118 }\
119 fpmas::api::model::WeakAgentPtr Serializer<fpmas::api::model::WeakAgentPtr>\
120 ::from_datapack(const ObjectPack& o) {\
121 return AgentPtrSerializer<ObjectPack, void>::from_datapack(o);\
122 }\
123 \
124 std::size_t LightSerializer<fpmas::api::model::AgentPtr>::size(const LightObjectPack& o, const fpmas::api::model::AgentPtr& data) {\
125 return AgentPtrSerializer<LightObjectPack, void>::size(o, data);\
126 }\
127 void LightSerializer<fpmas::api::model::AgentPtr>::to_datapack(LightObjectPack& o, const fpmas::api::model::AgentPtr& data) {\
128 AgentPtrSerializer<LightObjectPack, void>::to_datapack(o, data);\
129 }\
130 fpmas::api::model::AgentPtr LightSerializer<fpmas::api::model::AgentPtr>::from_datapack(const LightObjectPack& o) {\
131 return {AgentPtrSerializer<LightObjectPack, void>::from_datapack(o)};\
132 }\
133 \
134 std::size_t LightSerializer<fpmas::api::model::WeakAgentPtr>::size(const LightObjectPack& o, const fpmas::api::model::WeakAgentPtr& data) {\
135 return AgentPtrSerializer<LightObjectPack, void>::size(o, data);\
136 }\
137 void LightSerializer<fpmas::api::model::WeakAgentPtr>\
138 ::to_datapack(LightObjectPack& o, const fpmas::api::model::WeakAgentPtr& data) {\
139 AgentPtrSerializer<LightObjectPack, void>::to_datapack(o, data);\
140 }\
141 fpmas::api::model::WeakAgentPtr LightSerializer<fpmas::api::model::WeakAgentPtr>\
142 ::from_datapack(const LightObjectPack& o) {\
143 return AgentPtrSerializer<LightObjectPack, void>::from_datapack(o);\
144 }\
145 }}}\
146
154#define FPMAS_DEFAULT_DATAPACK(AGENT) \
155 namespace fpmas { namespace io { namespace datapack {\
156 template<>\
157\
160 struct Serializer<fpmas::api::utils::PtrWrapper<AGENT>> {\
161 template<typename PackType>\
162 static std::size_t size(const PackType&, const fpmas::api::utils::PtrWrapper<AGENT>&) {\
163 return 0;\
164 }\
165 \
166\
171 template<typename PackType>\
172 static void to_datapack(PackType&, const fpmas::api::utils::PtrWrapper<AGENT>&) {\
173 }\
174 \
175\
180 template<typename PackType>\
181 static fpmas::api::utils::PtrWrapper<AGENT> from_datapack(const PackType&) {\
182 return {new AGENT};\
183 }\
184 };\
185 }}}
186
187namespace fpmas { namespace io { namespace datapack {
188
189 using api::model::AgentPtr;
200 template<>
201 struct Serializer<std::type_index> {
202 private:
203 static FPMAS_TYPE_INDEX id;
204 static std::unordered_map<FPMAS_TYPE_INDEX, std::type_index> id_to_type;
205 static std::unordered_map<std::type_index, FPMAS_TYPE_INDEX> type_to_id;
206
207 public:
221 static FPMAS_TYPE_INDEX register_type(const std::type_index& type) {
222 FPMAS_TYPE_INDEX new_id = id++;
223 type_to_id.insert({type, new_id});
224 id_to_type.insert({new_id, type});
225 return new_id;
226 }
227
232 template<typename PackType>
233 static FPMAS_TYPE_INDEX size(const PackType& pack) {
234 return pack.template size<FPMAS_TYPE_INDEX>();
235 }
236
240 template<typename PackType>
241 static FPMAS_TYPE_INDEX size(const PackType& o, const std::type_index&) {
242 return o.template size<FPMAS_TYPE_INDEX>();
243 }
244
254 template<typename PackType>
255 static void to_datapack(PackType& pack, const std::type_index& index) {
256 auto _id = type_to_id.find(index);
257 if(_id != type_to_id.end())
258 pack.put(_id->second);
259 else
261 }
271 template<typename PackType>
272 static std::type_index from_datapack(const PackType& pack) {
273 FPMAS_TYPE_INDEX type_id = pack.template get<FPMAS_TYPE_INDEX>();
274 auto _type = id_to_type.find(type_id);
275 if(_type != id_to_type.end())
276 return _type->second;
278 }
279 };
280
378 template<typename AgentType>
379 struct Serializer<api::utils::PtrWrapper<AgentType>> {
385 template<typename PackType>
386 static std::size_t size(const PackType& p, const api::utils::PtrWrapper<AgentType>& agent_ptr) {
387 return AgentType::size(p, agent_ptr.get());
388 }
389
396 template<typename PackType>
397 static void to_datapack(PackType& pack, const api::utils::PtrWrapper<AgentType>& agent_ptr) {
398 AgentType::to_datapack(pack, agent_ptr.get());
400
408 template<typename PackType>
409 static api::utils::PtrWrapper<AgentType> from_datapack(const PackType& pack) {
410 return AgentType::from_datapack(pack);
411 }
412 };
413
452 template<typename AgentType>
453 struct LightSerializer<
454 fpmas::api::utils::PtrWrapper<AgentType>,
455 typename std::enable_if<
456 std::is_base_of<fpmas::api::model::Agent, AgentType>::value
457 && !std::is_default_constructible<AgentType>::value
458 && std::is_same<AgentType, typename AgentType::FinalAgentType>::value>::type
459 >{
460 public:
467 static std::size_t size(const LightObjectPack& p, const fpmas::api::utils::PtrWrapper<AgentType>& agent) {
468 // Size required to serialize a classic ObjectPack into
469 // a LightObjectPack (the ObjectPack size is required
470 // in addition to the ObjectPack buffer size)
471 // This should be equivalent to the more correct
472 // `p.size(ObjectPack(agent))`, but avoids useless
473 // ObjectPack serialization in this method.
474 return p.size<std::size_t>() + ObjectPack().size(agent);
475 }
487 static bool warn_print = false;
488 if(!warn_print) {
489 warn_print = true;
490 FPMAS_LOGW(0, "LightSerializer",
491 "Type %s does not define a default constructor or "
492 "a LightSerializer specialization."
493 "This might be uneficient.", FPMAS_TYPE_STR(AgentType)
494 );
495 }
496
497 pack.put(ObjectPack(agent));
498 }
499
511 return pack.get<ObjectPack>()
513 }
514 };
515
534 template<typename AgentType>
535 struct LightSerializer<
536 fpmas::api::utils::PtrWrapper<AgentType>,
537 typename std::enable_if<
538 std::is_base_of<api::model::Agent, AgentType>::value
539 && std::is_default_constructible<AgentType>::value
540 && std::is_same<AgentType, typename AgentType::FinalAgentType>::value>::type
541 > {
542
543
551 static std::size_t size(
553 return 0;
554 }
555
562 static void to_datapack(
564 }
576 const LightObjectPack&) {
577 return new AgentType;
579 };
580
581 template<typename PackType, typename Type, typename... AgentTypes>
582 struct AgentPtrSerializer;
583
587 template<typename PackType>
588 struct AgentPtrSerializer<PackType, void> {
597 static std::size_t size(const PackType&, const WeakAgentPtr&);
606 static void to_datapack(PackType&, const WeakAgentPtr& ptr);
607
616 static WeakAgentPtr from_datapack(const PackType& p);
617 };
618
619 template<typename PackType>
621 const PackType &, const WeakAgentPtr& ptr) {
622 FPMAS_LOGE(-1, "AGENT_SERIALIZER",
623 "Invalid agent type : %s. Make sure to properly register "
624 "the Agent type with FPMAS_DATAPACK_SET_UP and FPMAS_REGISTER_AGENT_TYPES.",
625 ptr->typeId().name());
626 throw exceptions::BadTypeException(ptr->typeId());
627 }
628
629 template<typename PackType>
631 PackType &, const WeakAgentPtr& ptr) {
632 FPMAS_LOGE(-1, "AGENT_SERIALIZER",
633 "Invalid agent type : %s. Make sure to properly register "
634 "the Agent type with FPMAS_DATAPACK_SET_UP and FPMAS_REGISTER_AGENT_TYPES.",
635 ptr->typeId().name());
636 throw exceptions::BadTypeException(ptr->typeId());
637 }
638
639 template<typename PackType>
641 std::size_t id = p.template get<std::size_t>();
642 FPMAS_LOGE(-1, "AGENT_SERIALIZER",
643 "Invalid agent type id : %lu. Make sure to properly register "
644 "the Agent type with FPMAS_DATAPACK_SET_UP and FPMAS_REGISTER_AGENT_TYPES.",
645 id);
647 }
648
658 template<typename PackType, typename Type, typename... AgentTypes>
659 struct AgentPtrSerializer {
664 static std::size_t size(const PackType& p, const WeakAgentPtr& ptr) {
665 if(ptr->typeId() == Type::TYPE_ID) {
666 return p.template size<api::model::TypeId>()
667 + p.template size(TypedAgentPtr<Type>(
668 const_cast<Type*>(static_cast<const Type*>(ptr.get()))
669 ))
670 + p.template size(ptr->groupIds());
671 }
673 }
674
692 static void to_datapack(
693 PackType& p, const WeakAgentPtr& ptr) {
694 if(ptr->typeId() == Type::TYPE_ID) {
695 p.put(Type::TYPE_ID);
696 p.put(TypedAgentPtr<Type>(
697 const_cast<Type*>(static_cast<const Type*>(ptr.get()))
698 ));
699 p.put(ptr->groupIds());
700 } else {
702 }
703 }
704
722 static WeakAgentPtr from_datapack(const PackType& p) {
723 std::size_t pos = p.readOffset();
725 .template get<fpmas::api::model::TypeId>();
726 if(id == Type::TYPE_ID) {
727 auto agent = p
728 .template get<TypedAgentPtr<Type>>();
729 for(auto gid :
730 p.template get<std::vector<api::model::GroupId>>())
731 agent->addGroupId(gid);
732 return {agent};
733 } else {
734 p.seekRead(pos);
736 }
737 }
738 };
739
740}}}
741
742#endif
Definition: ptr_wrapper.h:21
T * get()
Definition: ptr_wrapper.h:58
Definition: serializer_set_up.h:67
Definition: serializer_set_up.h:97
Definition: datapack.h:301
std::size_t size() const
Definition: datapack.h:367
void put(const T &item)
Definition: datapack.h:447
T get() const
Definition: datapack.h:459
api::utils::PtrWrapper< api::model::Agent > WeakAgentPtr
Definition: model.h:160
std::type_index TypeId
Definition: model.h:82
BasicObjectPack< Serializer > ObjectPack
Definition: datapack.h:1393
Definition: fpmas.cpp:3
#define FPMAS_TYPE_INDEX
Definition: serializer_set_up.h:38
#define FPMAS_TYPE_STR(T)
Definition: serializer_set_up.h:16
static WeakAgentPtr from_datapack(const PackType &p)
Definition: datapack_serializer.h:712
static void to_datapack(PackType &p, const WeakAgentPtr &ptr)
Definition: datapack_serializer.h:682
static std::size_t size(const PackType &p, const WeakAgentPtr &ptr)
Definition: datapack_serializer.h:654
static void to_datapack(LightObjectPack &pack, const T &item)
Definition: datapack.h:1438
static std::size_t size(const LightObjectPack &p)
Definition: datapack.h:1418
static T from_datapack(const LightObjectPack &pack)
Definition: datapack.h:1451
Definition: datapack.h:55