2
2
3
3
#include " behaviortree_cpp/basic_types.h"
4
4
#include " behaviortree_cpp/utils/safe_any.hpp"
5
- #include " behaviortree_cpp/contrib/expected.hpp "
5
+ #include " behaviortree_cpp/basic_types.h "
6
6
7
7
// Use the version nlohmann::json embedded in BT.CPP
8
8
#include " behaviortree_cpp/contrib/json.hpp"
@@ -73,14 +73,32 @@ class JsonExporter
73
73
*/
74
74
ExpectedEntry fromJson (const nlohmann::json& source) const ;
75
75
76
- // / Same as the other, but providing the specific type
76
+ // / Same as the other, but providing the specific type,
77
+ // / To be preferred if the JSON doesn't contain the field [__type]
77
78
ExpectedEntry fromJson (const nlohmann::json& source, std::type_index type) const ;
78
79
80
+ template <typename T>
81
+ Expected<T> fromJson (const nlohmann::json& source) const ;
82
+
79
83
// / Register new JSON converters with addConverter<Foo>().
80
84
// / You should have used first the macro BT_JSON_CONVERTER
81
85
template <typename T>
82
86
void addConverter ();
83
87
88
+ /* *
89
+ * @brief addConverter register a to_json function that converts a json to a type T.
90
+ *
91
+ * @param to_json the function with signature void(const T&, nlohmann::json&)
92
+ * @param add_type if true, add a field called [__type] with the name ofthe type.
93
+ * */
94
+ template <typename T>
95
+ void addConverter (std::function<void (const T&, nlohmann::json&)> to_json,
96
+ bool add_type = true);
97
+
98
+ // / Register custom from_json converter directly.
99
+ template <typename T>
100
+ void addConverter (std::function<void (const nlohmann::json&, T&)> from_json);
101
+
84
102
private:
85
103
using ToJonConverter = std::function<void (const BT::Any&, nlohmann::json&)>;
86
104
using FromJonConverter = std::function<Entry(const nlohmann::json&)>;
@@ -90,6 +108,22 @@ class JsonExporter
90
108
std::unordered_map<std::string, BT::TypeInfo> type_names_;
91
109
};
92
110
111
+ template <typename T>
112
+ inline Expected<T> JsonExporter::fromJson (const nlohmann::json& source) const
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
+
93
127
// -------------------------------------------------------------------
94
128
95
129
template <typename T>
@@ -117,6 +151,33 @@ inline void JsonExporter::addConverter()
117
151
from_json_converters_.insert ({ typeid (T), from_converter });
118
152
}
119
153
154
+ template <typename T>
155
+ inline void JsonExporter::addConverter (
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
+
120
181
template <typename T>
121
182
inline void RegisterJsonDefinition ()
122
183
{
0 commit comments