fpmas 1.6
json_serializer.h
Go to the documentation of this file.
1#ifndef FPMAS_MODEL_JSON_SERIALIZER_H
2#define FPMAS_MODEL_JSON_SERIALIZER_H
3
8#include "serializer_set_up.h"
10#include "fpmas/io/json.h"
11#include "fpmas/model/model.h"
12
40#define FPMAS_BASE_JSON_SET_UP(...)\
41 namespace nlohmann {\
42 void adl_serializer<fpmas::api::model::AgentPtr>\
43 ::to_json(json& j, const fpmas::api::model::AgentPtr& data) {\
44 fpmas::io::json::AgentPtrSerializer<json, __VA_ARGS__ , void>::to_json(j, data);\
45 }\
46 fpmas::api::model::AgentPtr adl_serializer<fpmas::api::model::AgentPtr>\
47 ::from_json(const json& j) {\
48 return {fpmas::io::json::AgentPtrSerializer<json, __VA_ARGS__ , void>::from_json(j)};\
49 }\
50\
51 void adl_serializer<fpmas::api::model::WeakAgentPtr>\
52 ::to_json(json& j, const fpmas::api::model::WeakAgentPtr& data) {\
53 fpmas::io::json::AgentPtrSerializer<json, __VA_ARGS__ , void>::to_json(j, data);\
54 }\
55 fpmas::api::model::WeakAgentPtr adl_serializer<fpmas::api::model::WeakAgentPtr>\
56 ::from_json(const json& j) {\
57 return fpmas::io::json::AgentPtrSerializer<json, __VA_ARGS__ , void>::from_json(j);\
58 }\
59 }\
60 namespace fpmas { namespace io { namespace json {\
61 void light_serializer<fpmas::api::model::AgentPtr>::to_json(light_json& j, const fpmas::api::model::AgentPtr& data) {\
62 AgentPtrSerializer<light_json, __VA_ARGS__ , void>::to_json(j, data);\
63 }\
64 fpmas::api::model::AgentPtr light_serializer<fpmas::api::model::AgentPtr>::from_json(const light_json& j) {\
65 return {AgentPtrSerializer<light_json, __VA_ARGS__ , void>::from_json(j)};\
66 }\
67 \
68 void light_serializer<fpmas::api::model::WeakAgentPtr>\
69 ::to_json(light_json& j, const fpmas::api::model::WeakAgentPtr& data) {\
70 AgentPtrSerializer<light_json, __VA_ARGS__ , void>::to_json(j, data);\
71 }\
72 fpmas::api::model::WeakAgentPtr light_serializer<fpmas::api::model::WeakAgentPtr>\
73 ::from_json(const light_json& j) {\
74 return AgentPtrSerializer<light_json, __VA_ARGS__ , void>::from_json(j);\
75 }\
76 }}}\
77
82#define FPMAS_BASE_DEFAULT_JSON_SET_UP()\
83 namespace nlohmann {\
84 void adl_serializer<fpmas::api::model::AgentPtr>\
85 ::to_json(json& j, const fpmas::api::model::AgentPtr& data) {\
86 fpmas::io::json::AgentPtrSerializer<json, void>::to_json(j, data);\
87 }\
88 fpmas::api::model::AgentPtr adl_serializer<fpmas::api::model::AgentPtr>\
89 ::from_json(const json& j) {\
90 return {fpmas::io::json::AgentPtrSerializer<json, void>::from_json(j)};\
91 }\
92\
93 void adl_serializer<fpmas::api::model::WeakAgentPtr>\
94 ::to_json(json& j, const fpmas::api::model::WeakAgentPtr& data) {\
95 fpmas::io::json::AgentPtrSerializer<json, void>::to_json(j, data);\
96 }\
97 fpmas::api::model::WeakAgentPtr adl_serializer<fpmas::api::model::WeakAgentPtr>\
98 ::from_json(const json& j) {\
99 return fpmas::io::json::AgentPtrSerializer<json, void>::from_json(j);\
100 }\
101 }\
102 namespace fpmas { namespace io { namespace json {\
103 void light_serializer<fpmas::api::model::AgentPtr>::to_json(light_json& j, const fpmas::api::model::AgentPtr& data) {\
104 AgentPtrSerializer<light_json, void>::to_json(j, data);\
105 }\
106 fpmas::api::model::AgentPtr light_serializer<fpmas::api::model::AgentPtr>::from_json(const light_json& j) {\
107 return {AgentPtrSerializer<light_json, void>::from_json(j)};\
108 }\
109 \
110 void light_serializer<fpmas::api::model::WeakAgentPtr>\
111 ::to_json(light_json& j, const fpmas::api::model::WeakAgentPtr& data) {\
112 AgentPtrSerializer<light_json, void>::to_json(j, data);\
113 }\
114 fpmas::api::model::WeakAgentPtr light_serializer<fpmas::api::model::WeakAgentPtr>\
115 ::from_json(const light_json& j) {\
116 return AgentPtrSerializer<light_json, void>::from_json(j);\
117 }\
118 }}}\
119
127#define FPMAS_DEFAULT_JSON(AGENT) \
128 namespace nlohmann {\
129 template<>\
130\
133 struct adl_serializer<fpmas::api::utils::PtrWrapper<AGENT>> {\
134\
139 template<typename JsonType>\
140 static void to_json(JsonType& j, const fpmas::api::utils::PtrWrapper<AGENT>&) {\
141 j = json::object();\
142 }\
143\
144\
149 template<typename JsonType>\
150 static void from_json(const JsonType&, fpmas::api::utils::PtrWrapper<AGENT>& ptr) {\
151 ptr = fpmas::api::utils::PtrWrapper<AGENT>(new AGENT);\
152 }\
153 };\
154 }
155
156namespace nlohmann {
166 template<>
167 struct adl_serializer<std::type_index> {
168 private:
169 static FPMAS_TYPE_INDEX id;
170 static std::unordered_map<FPMAS_TYPE_INDEX, std::type_index> id_to_type;
171 static std::unordered_map<std::type_index, FPMAS_TYPE_INDEX> type_to_id;
172
173 public:
187 static FPMAS_TYPE_INDEX register_type(const std::type_index& type) {
188 FPMAS_TYPE_INDEX new_id = id++;
189 type_to_id.insert({type, new_id});
190 id_to_type.insert({new_id, type});
191 return new_id;
193
201 template<typename JsonType>
202 static std::type_index from_json(const JsonType& j) {
203 FPMAS_TYPE_INDEX id = j.template get<FPMAS_TYPE_INDEX>();
204 auto _type = id_to_type.find(id);
205 if(_type != id_to_type.end())
206 return _type->second;
208
209 }
219 template<typename JsonType>
220 static void to_json(JsonType& j, const std::type_index& type) {
221 auto _id = type_to_id.find(type);
222 if(_id != type_to_id.end())
223 j = _id->second;
224 else
226 }
227 };
228
322 template<typename AgentType>
323 struct adl_serializer<fpmas::api::utils::PtrWrapper<AgentType>> {
330 template<typename JsonType>
331 static fpmas::api::utils::PtrWrapper<AgentType> from_json(const JsonType& j) {
332 return AgentType::from_json(j);
333 }
334
341 template<typename JsonType>
342 static void to_json(JsonType& j, const fpmas::api::utils::PtrWrapper<AgentType>& agent_ptr) {
343 AgentType::to_json(j, agent_ptr.get());
344 }
345 };
346}
347
348namespace fpmas { namespace io { namespace json {
349
387 template<typename AgentType>
388 struct light_serializer<
389 fpmas::api::utils::PtrWrapper<AgentType>,
390 typename std::enable_if<
391 std::is_base_of<fpmas::api::model::Agent, AgentType>::value
392 && !std::is_default_constructible<AgentType>::value
393 && std::is_same<AgentType, typename AgentType::FinalAgentType>::value>::type
394 >{
395 public:
405 static void to_json(light_json& j, const fpmas::api::utils::PtrWrapper<AgentType>& agent) {
406 static bool warn_print = false;
407 if(!warn_print) {
408 warn_print = true;
409 FPMAS_LOGW(0, "light_serializer",
410 "Type %s does not define a default constructor or "
411 "a light_serializer specialization."
412 "This might be uneficient.", FPMAS_TYPE_STR(AgentType)
413 );
414 }
415
416 nlohmann::json _j = agent;
417 j = light_json::parse(_j.dump());
418 }
430 nlohmann::json _j = nlohmann::json::parse(j.dump());
432 }
433 };
434
435
454 template<typename AgentType>
455 struct light_serializer<
456 fpmas::api::utils::PtrWrapper<AgentType>,
457 typename std::enable_if<
458 std::is_base_of<fpmas::api::model::Agent, AgentType>::value
459 && std::is_default_constructible<AgentType>::value
460 && std::is_same<AgentType, typename AgentType::FinalAgentType>::value>::type
461 > {
462
470 }
482 return new AgentType;
483 }
484 };
485
486}}}
487
488namespace fpmas { namespace io { namespace json {
489 using api::utils::PtrWrapper;
492
493 template<typename JsonType, typename Type, typename... AgentTypes>
494 struct AgentPtrSerializer;
495
499 template<typename JsonType>
500 struct AgentPtrSerializer<JsonType, void> {
508 static void to_json(JsonType&, const WeakAgentPtr& ptr);
509
517 static WeakAgentPtr from_json(const JsonType& j);
518 };
519
520 template<typename JsonType>
522 JsonType &, const WeakAgentPtr& ptr) {
523 FPMAS_LOGE(-1, "AGENT_SERIALIZER",
524 "Invalid agent type : %s. Make sure to properly register "
525 "the Agent type with FPMAS_JSON_SET_UP and FPMAS_REGISTER_AGENT_TYPES.",
526 ptr->typeId().name());
527 throw exceptions::BadTypeException(ptr->typeId());
528 }
529
530 template<typename JsonType>
532 std::size_t id = j.at("type").template get<std::size_t>();
533 FPMAS_LOGE(-1, "AGENT_SERIALIZER",
534 "Invalid agent type id : %lu. Make sure to properly register "
535 "the Agent type with FPMAS_JSON_SET_UP and FPMAS_REGISTER_AGENT_TYPES.",
536 id);
538 }
539
549 template<typename JsonType, typename Type, typename... AgentTypes>
550 struct AgentPtrSerializer {
571 static void to_json(
572 JsonType& j, const WeakAgentPtr& ptr) {
573 if(ptr->typeId() == Type::TYPE_ID) {
574 j["type"] = Type::TYPE_ID;
575 j["gids"] = ptr->groupIds();
576 j["agent"] = TypedAgentPtr<Type>(
577 const_cast<Type*>(static_cast<const Type*>(ptr.get()))
578 );
579 } else {
581 }
582 }
583
604 static WeakAgentPtr from_json(const JsonType& j) {
605 fpmas::api::model::TypeId id = j.at("type")
606 .template get<fpmas::api::model::TypeId>();
607 if(id == Type::TYPE_ID) {
608 auto agent = j.at("agent").template get<TypedAgentPtr<Type>>();
609 for(auto gid : j.at("gids")
610 .template get<std::vector<fpmas::api::model::GroupId>>())
611 agent->addGroupId(gid);
612 return {agent};
613 } else {
615 }
616 }
617
618 };
619}}}
620#endif
Definition: model.h:92
Definition: ptr_wrapper.h:21
T * get()
Definition: ptr_wrapper.h:58
Definition: serializer_set_up.h:67
Definition: serializer_set_up.h:97
api::utils::PtrWrapper< api::model::Agent > WeakAgentPtr
Definition: model.h:160
std::type_index TypeId
Definition: model.h:82
nlohmann::basic_json< std::map, std::vector, std::string, bool, std::int64_t, std::uint64_t, double, std::allocator, light_serializer > light_json
Definition: json.h:14
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
Definition: json_serializer.h:540
static WeakAgentPtr from_json(const JsonType &j)
Definition: json_serializer.h:594
static void to_json(JsonType &j, const WeakAgentPtr &ptr)
Definition: json_serializer.h:561
static void from_json(const light_json &j, T &data)
Definition: json.h:123
static void to_json(light_json &j, const T &data)
Definition: json.h:107