3#include "behaviortree_cpp/basic_types.h"
4#include "behaviortree_cpp/utils/safe_any.hpp"
8#ifdef BTCPP_SYSTEM_JSON
9#include <nlohmann/json.hpp>
11#include "behaviortree_cpp/contrib/json.hpp"
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
50
51
58 ~JsonExporter() =
default;
66 JsonExporter() =
default;
70
71
72
73
74
75 bool toJson(
const BT::
Any& any, nlohmann::json& destination)
const;
80 using ExpectedEntry = nonstd::expected<Entry, std::string>;
83
84
85
86
87
88
89 ExpectedEntry
fromJson(
const nlohmann::json& source)
const;
93 ExpectedEntry
fromJson(
const nlohmann::json& source, std::type_index type)
const;
96 Expected<T> fromJson(
const nlohmann::json& source)
const;
99
100
101
102
103 template <
typename T>
107
108
109
110
111
112
113 template <
typename T>
114 void addConverter(std::function<
void(
const T&, nlohmann::json&)> to_json,
115 bool add_type =
true);
118
119
120
121
122
123 template <
typename T>
124 void addConverter(std::function<
void(
const nlohmann::json&, T&)> from_json);
127 using ToJonConverter = std::function<
void(
const BT::
Any&, nlohmann::json&)>;
128 using FromJonConverter = std::function<Entry(
const nlohmann::json&)>;
130 std::unordered_map<std::type_index, ToJonConverter> to_json_converters_;
131 std::unordered_map<std::type_index, FromJonConverter> from_json_converters_;
132 std::unordered_map<std::type_index, FromJonConverter> from_json_array_converters_;
133 std::unordered_map<std::string, BT::TypeInfo> type_names_;
137inline Expected<T>
JsonExporter::fromJson(
const nlohmann::json& source)
const
139 auto res = fromJson(source);
142 return nonstd::make_unexpected(res.error());
144 auto casted = res->first.tryCast<T>();
147 return nonstd::make_unexpected(casted.error());
158 nlohmann::json
const js = T{};
160 if(js.contains(
"__type"))
162 type_names_.insert({ std::string(js[
"__type"]), BT::TypeInfo::Create<T>() });
164 type_names_.insert({ BT::demangle(
typeid(T)), BT::TypeInfo::Create<T>() });
166 ToJonConverter to_converter = [](
const BT::Any& entry, nlohmann::json& dst) {
167 dst = *
const_cast<BT::Any&>(entry).castPtr<T>();
169 to_json_converters_.insert({
typeid(T), to_converter });
171 FromJonConverter from_converter = [](
const nlohmann::json& src) -> Entry {
172 T value = src.get<T>();
173 return { BT::Any(value), BT::TypeInfo::Create<T>() };
176 from_json_converters_.insert({
typeid(T), from_converter });
179 ToJonConverter to_array_converter = [](
const BT::Any& entry, nlohmann::json& dst) {
180 dst = *
const_cast<BT::Any&>(entry).castPtr<std::vector<T>>();
182 to_json_converters_.insert({
typeid(std::vector<T>), to_array_converter });
184 FromJonConverter from_array_converter = [](
const nlohmann::json& src) -> Entry {
185 std::vector<T> value;
186 for(
const auto& item : src)
188 value.push_back(item.get<T>());
190 return { BT::Any(value), BT::TypeInfo::Create<std::vector<T>>() };
192 from_json_array_converters_.insert({
typeid(T), from_array_converter });
197 std::function<
void(
const T&, nlohmann::json&)> func,
bool add_type)
199 auto converter = [func, add_type](
const BT::
Any& entry, nlohmann::json& json) {
200 func(entry.cast<T>(), json);
203 json[
"__type"] = BT::demangle(
typeid(T));
208 auto vector_converter = [converter](
const BT::
Any& entry, nlohmann::json& json) {
209 auto& vec = *
const_cast<BT::Any&>(entry).castPtr<std::vector<T>>();
210 for(
const auto& item : vec)
212 nlohmann::json item_json;
213 converter(BT::Any(item), item_json);
214 json.push_back(item_json);
217 to_json_converters_.insert({
typeid(T), std::move(converter) });
218 to_json_converters_.insert({
typeid(std::vector<T>), std::move(vector_converter) });
225 auto converter = [func](
const nlohmann::json& json) -> Entry {
230 type_names_.insert({ BT::demangle(
typeid(T)), BT::TypeInfo::Create<T>() });
231 from_json_converters_.insert({
typeid(T), std::move(converter) });
234 auto vector_converter = [func](
const nlohmann::json& json) -> Entry {
236 for(
const auto& item : json)
239 func(item, item_tmp);
240 tmp.push_back(item_tmp);
242 return { BT::Any(tmp), BT::TypeInfo::Create<std::vector<T>>() };
244 from_json_array_converters_.insert({
typeid(T), std::move(vector_converter) });
248inline void RegisterJsonDefinition()
261#define BT_JSON_CONVERTER(Type, value)
262 template <class AddField>
263 void _JsonTypeDefinition(Type&, AddField&);
265 inline void to_json(nlohmann::json& js, const Type& p)
267 auto op = [&js](const char* name, auto* val) { js[name] = *val; };
268 _JsonTypeDefinition(const_cast<Type&>(p), op);
269 js["__type"] = #Type;
272 inline void from_json(const nlohmann::json& js, Type& p)
274 auto op = [&js](const char* name, auto* v) { js.at(name).get_to(*v); };
275 _JsonTypeDefinition(p, op);
278 template <class AddField>
279 inline void _JsonTypeDefinition(Type& value, AddField& add_field)
Definition: safe_any.hpp:57
Definition: json_export.h:54
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:196
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:223
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:155
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:377
Definition: action_node.h:24