3#include "behaviortree_cpp/basic_types.h"
4#include "behaviortree_cpp/utils/safe_any.hpp"
7#include "behaviortree_cpp/contrib/json.hpp"
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
45
46
53 ~JsonExporter() =
default;
61 JsonExporter() =
default;
65
66
67
68
69
70 bool toJson(
const BT::
Any& any, nlohmann::json& destination)
const;
75 using ExpectedEntry = nonstd::expected<Entry, std::string>;
78
79
80
81
82
83
84 ExpectedEntry
fromJson(
const nlohmann::json& source)
const;
88 ExpectedEntry
fromJson(
const nlohmann::json& source, std::type_index type)
const;
91 Expected<T> fromJson(
const nlohmann::json& source)
const;
94
95
96
97
102
103
104
105
106
107
108 template <
typename T>
109 void addConverter(std::function<
void(
const T&, nlohmann::json&)> to_json,
110 bool add_type =
true);
113
114
115
116
117
118 template <
typename T>
119 void addConverter(std::function<
void(
const nlohmann::json&, T&)> from_json);
122 using ToJonConverter = std::function<
void(
const BT::
Any&, nlohmann::json&)>;
123 using FromJonConverter = std::function<Entry(
const nlohmann::json&)>;
125 std::unordered_map<std::type_index, ToJonConverter> to_json_converters_;
126 std::unordered_map<std::type_index, FromJonConverter> from_json_converters_;
127 std::unordered_map<std::type_index, FromJonConverter> from_json_array_converters_;
128 std::unordered_map<std::string, BT::TypeInfo> type_names_;
132inline Expected<T>
JsonExporter::fromJson(
const nlohmann::json& source)
const
134 auto res = fromJson(source);
137 return nonstd::make_unexpected(res.error());
139 auto casted = res->first.tryCast<T>();
142 return nonstd::make_unexpected(casted.error());
153 nlohmann::json
const js = T{};
155 if(js.contains(
"__type"))
157 type_names_.insert({ std::string(js[
"__type"]), BT::TypeInfo::Create<T>() });
159 type_names_.insert({ BT::demangle(
typeid(T)), BT::TypeInfo::Create<T>() });
161 ToJonConverter to_converter = [](
const BT::Any& entry, nlohmann::json& dst) {
162 dst = *
const_cast<BT::Any&>(entry).castPtr<T>();
164 to_json_converters_.insert({
typeid(T), to_converter });
166 FromJonConverter from_converter = [](
const nlohmann::json& src) -> Entry {
167 T value = src.get<T>();
168 return { BT::Any(value), BT::TypeInfo::Create<T>() };
171 from_json_converters_.insert({
typeid(T), from_converter });
174 ToJonConverter to_array_converter = [](
const BT::Any& entry, nlohmann::json& dst) {
175 dst = *
const_cast<BT::Any&>(entry).castPtr<std::vector<T>>();
177 to_json_converters_.insert({
typeid(std::vector<T>), to_array_converter });
179 FromJonConverter from_array_converter = [](
const nlohmann::json& src) -> Entry {
180 std::vector<T> value;
181 for(
const auto& item : src)
183 value.push_back(item.get<T>());
185 return { BT::Any(value), BT::TypeInfo::Create<std::vector<T>>() };
187 from_json_array_converters_.insert({
typeid(T), from_array_converter });
192 std::function<
void(
const T&, nlohmann::json&)> func,
bool add_type)
194 auto converter = [func, add_type](
const BT::
Any& entry, nlohmann::json& json) {
195 func(entry.cast<T>(), json);
198 json[
"__type"] = BT::demangle(
typeid(T));
203 auto vector_converter = [converter](
const BT::
Any& entry, nlohmann::json& json) {
204 auto& vec = *
const_cast<BT::Any&>(entry).castPtr<std::vector<T>>();
205 for(
const auto& item : vec)
207 nlohmann::json item_json;
208 converter(BT::Any(item), item_json);
209 json.push_back(item_json);
212 to_json_converters_.insert({
typeid(T), std::move(converter) });
213 to_json_converters_.insert({
typeid(std::vector<T>), std::move(vector_converter) });
220 auto converter = [func](
const nlohmann::json& json) -> Entry {
225 type_names_.insert({ BT::demangle(
typeid(T)), BT::TypeInfo::Create<T>() });
226 from_json_converters_.insert({
typeid(T), std::move(converter) });
229 auto vector_converter = [func](
const nlohmann::json& json) -> Entry {
231 for(
const auto& item : json)
234 func(item, item_tmp);
235 tmp.push_back(item_tmp);
237 return { BT::Any(tmp), BT::TypeInfo::Create<std::vector<T>>() };
239 from_json_array_converters_.insert({
typeid(T), std::move(vector_converter) });
243inline void RegisterJsonDefinition()
256#define BT_JSON_CONVERTER(Type, value)
257 template <class AddField>
258 void _JsonTypeDefinition(Type&, AddField&);
260 inline void to_json(nlohmann::json& js, const Type& p)
262 auto op = [&js](const char* name, auto* val) { js[name] = *val; };
263 _JsonTypeDefinition(const_cast<Type&>(p), op);
264 js["__type"] = #Type;
267 inline void from_json(const nlohmann::json& js, Type& p)
269 auto op = [&js](const char* name, auto* v) { js.at(name).get_to(*v); };
270 _JsonTypeDefinition(p, op);
273 template <class AddField>
274 inline void _JsonTypeDefinition(Type& value, AddField& add_field)
Definition: safe_any.hpp:50
Definition: json_export.h:49
ExpectedEntry fromJson(const nlohmann::json &source, std::type_index type) const
void addConverter(std::function< void(const T &, nlohmann::json &)> to_json, bool add_type=true)
addConverter register a to_json function that converts a json to a type T. The conversion to std:vect...
Definition: json_export.h:191
void addConverter(std::function< void(const nlohmann::json &, T &)> from_json)
addConverter register a from_json function that converts a json to a type T. The conversions from std...
Definition: json_export.h:218
bool toJson(const BT::Any &any, nlohmann::json &destination) const
toJson adds the content of "any" to the JSON "destination".
void addConverter()
Register new JSON converters with addConverter<Foo>(). You should used first the macro BT_JSON_CONVER...
Definition: json_export.h:150
ExpectedEntry fromJson(const nlohmann::json &source) const
fromJson will return an Entry (value wrappedn in Any + TypeInfo) from a json source....
Definition: basic_types.h:357
Definition: action_node.h:24