json_export.h
Go to the documentation of this file.
1 #pragma once
2 
6 
7 // Use the version nlohmann::json embedded in BT.CPP
9 
10 namespace BT
11 {
12 
43 //-----------------------------------------------------------------------------------
44 
50 {
51 public:
52  static JsonExporter& get();
53 
60  bool toJson(const BT::Any& any, nlohmann::json& destination) const;
61 
63  using Entry = std::pair<BT::Any, BT::TypeInfo>;
64 
65  using ExpectedEntry = nonstd::expected<Entry, std::string>;
66 
74  ExpectedEntry fromJson(const nlohmann::json& source) const;
75 
78  ExpectedEntry fromJson(const nlohmann::json& source, std::type_index type) const;
79 
80  template <typename T>
81  Expected<T> fromJson(const nlohmann::json& source) const;
82 
85  template <typename T>
86  void addConverter();
87 
94  template <typename T>
95  void addConverter(std::function<void(const T&, nlohmann::json&)> to_json,
96  bool add_type = true);
97 
99  template <typename T>
100  void addConverter(std::function<void(const nlohmann::json&, T&)> from_json);
101 
102 private:
103  using ToJonConverter = std::function<void(const BT::Any&, nlohmann::json&)>;
104  using FromJonConverter = std::function<Entry(const nlohmann::json&)>;
105 
106  std::unordered_map<std::type_index, ToJonConverter> to_json_converters_;
107  std::unordered_map<std::type_index, FromJonConverter> from_json_converters_;
108  std::unordered_map<std::string, BT::TypeInfo> type_names_;
109 };
110 
111 template <typename T>
113 {
114  auto res = fromJson(source);
115  if(!res)
116  {
117  return nonstd::expected_lite::make_unexpected(res.error());
118  }
119  auto casted = res->first.tryCast<T>();
120  if(!casted)
121  {
122  return nonstd::expected_lite::make_unexpected(casted.error());
123  }
124  return *casted;
125 }
126 
127 //-------------------------------------------------------------------
128 
129 template <typename T>
131 {
132  ToJonConverter to_converter = [](const BT::Any& entry, nlohmann::json& dst) {
133  dst = *const_cast<BT::Any&>(entry).castPtr<T>();
134  };
135  to_json_converters_.insert({ typeid(T), to_converter });
136 
137  FromJonConverter from_converter = [](const nlohmann::json& src) -> Entry {
138  T value = src.get<T>();
139  return { BT::Any(value), BT::TypeInfo::Create<T>() };
140  };
141 
142  // we need to get the name of the type
143  nlohmann::json const js = T{};
144  // we insert both the name obtained from JSON and demangle
145  if(js.contains("__type"))
146  {
147  type_names_.insert({ std::string(js["__type"]), BT::TypeInfo::Create<T>() });
148  }
149  type_names_.insert({ BT::demangle(typeid(T)), BT::TypeInfo::Create<T>() });
150 
151  from_json_converters_.insert({ typeid(T), from_converter });
152 }
153 
154 template <typename T>
156  std::function<void(const T&, nlohmann::json&)> func, bool add_type)
157 {
158  auto converter = [func, add_type](const BT::Any& entry, nlohmann::json& json) {
159  func(entry.cast<T>(), json);
160  if(add_type)
161  {
162  json["__type"] = BT::demangle(typeid(T));
163  }
164  };
165  to_json_converters_.insert({ typeid(T), std::move(converter) });
166 }
167 
168 template <typename T>
169 inline void
170 JsonExporter::addConverter(std::function<void(const nlohmann::json&, T&)> func)
171 {
172  auto converter = [func](const nlohmann::json& json) -> Entry {
173  T tmp;
174  func(json, tmp);
175  return { BT::Any(tmp), BT::TypeInfo::Create<T>() };
176  };
177  type_names_.insert({ BT::demangle(typeid(T)), BT::TypeInfo::Create<T>() });
178  from_json_converters_.insert({ typeid(T), std::move(converter) });
179 }
180 
181 template <typename T>
183 {
185 }
186 
187 } // namespace BT
188 
189 //------------------------------------------------
190 //------------------------------------------------
191 //------------------------------------------------
192 
193 // Macro to implement to_json() and from_json()
194 
195 #define BT_JSON_CONVERTER(Type, value) \
196  template <class AddField> \
197  void _JsonTypeDefinition(Type&, AddField&); \
198  \
199  inline void to_json(nlohmann::json& js, const Type& p) \
200  { \
201  auto op = [&js](const char* name, auto* val) { js[name] = *val; }; \
202  _JsonTypeDefinition(const_cast<Type&>(p), op); \
203  js["__type"] = #Type; \
204  } \
205  \
206  inline void from_json(const nlohmann::json& js, Type& p) \
207  { \
208  auto op = [&js](const char* name, auto* v) { js.at(name).get_to(*v); }; \
209  _JsonTypeDefinition(p, op); \
210  } \
211  \
212  template <class AddField> \
213  inline void _JsonTypeDefinition(Type& value, AddField& add_field)
214 
215 //end of file
BT
Definition: ex01_wrap_legacy.cpp:29
BT::demangle
std::string demangle(char const *name)
Definition: demangle_util.h:74
BT::JsonExporter::toJson
bool toJson(const BT::Any &any, nlohmann::json &destination) const
toJson adds the content of "any" to the JSON "destination".
Definition: json_export.cpp:12
BT::Any
Definition: safe_any.hpp:36
BT::JsonExporter::Entry
std::pair< BT::Any, BT::TypeInfo > Entry
This information is needed to create a BT::Blackboard::entry.
Definition: json_export.h:63
basic_types.h
BT::Expected
nonstd::expected< T, std::string > Expected
Definition: basic_types.h:85
basic_json
namespace for Niels Lohmann
Definition: json.hpp:3411
BT::JsonExporter::type_names_
std::unordered_map< std::string, BT::TypeInfo > type_names_
Definition: json_export.h:108
detail::void
j template void())
Definition: json.hpp:4893
BT::JsonExporter::FromJonConverter
std::function< Entry(const nlohmann::json &)> FromJonConverter
Definition: json_export.h:104
BT::JsonExporter::from_json_converters_
std::unordered_map< std::type_index, FromJonConverter > from_json_converters_
Definition: json_export.h:107
BT::JsonExporter
Definition: json_export.h:49
BT::JsonExporter::get
static JsonExporter & get()
Definition: json_export.cpp:6
detail::from_json
void from_json(const BasicJsonType &j, typename std::nullptr_t &n)
Definition: json.hpp:4664
BT::JsonExporter::ExpectedEntry
nonstd::expected< Entry, std::string > ExpectedEntry
Definition: json_export.h:65
safe_any.hpp
json.hpp
BT::JsonExporter::to_json_converters_
std::unordered_map< std::type_index, ToJonConverter > to_json_converters_
Definition: json_export.h:106
json
basic_json<> json
default specialization
Definition: json.hpp:3422
detail::to_json
void to_json(BasicJsonType &j, T b) noexcept
Definition: json.hpp:5642
BT::JsonExporter::addConverter
void addConverter()
Definition: json_export.h:130
BT::JsonExporter::fromJson
ExpectedEntry fromJson(const nlohmann::json &source) const
fromJson will return an Entry (value wrappedn in Any + TypeInfo) from a json source....
Definition: json_export.cpp:48
BT::JsonExporter::ToJonConverter
std::function< void(const BT::Any &, nlohmann::json &)> ToJonConverter
Definition: json_export.h:103
lexyd::any
constexpr auto any
Matches anything and consumes all remaining characters.
Definition: 3rdparty/lexy/include/lexy/dsl/any.hpp:42
BT::RegisterJsonDefinition
void RegisterJsonDefinition()
Definition: json_export.h:182


behaviortree_cpp_v4
Author(s): Davide Faconti
autogenerated on Fri Jun 28 2024 02:20:07