/src/behaviortreecpp/src/json_export.cpp
Line | Count | Source |
1 | | #include "behaviortree_cpp/json_export.h" |
2 | | |
3 | | namespace BT |
4 | | { |
5 | | |
6 | | JsonExporter& JsonExporter::get() |
7 | 1.05M | { |
8 | 1.05M | static JsonExporter global_instance; |
9 | 1.05M | return global_instance; |
10 | 1.05M | } |
11 | | |
12 | | bool JsonExporter::toJson(const Any& any, nlohmann::json& dst) const |
13 | 544k | { |
14 | 544k | auto const& type = any.castedType(); |
15 | | |
16 | 544k | if(any.isString()) |
17 | 36.2k | { |
18 | 36.2k | dst = any.cast<std::string>(); |
19 | 36.2k | } |
20 | 508k | else if(type == typeid(int64_t)) |
21 | 379k | { |
22 | 379k | dst = any.cast<int64_t>(); |
23 | 379k | } |
24 | 128k | else if(type == typeid(uint64_t)) |
25 | 2.72k | { |
26 | 2.72k | dst = any.cast<uint64_t>(); |
27 | 2.72k | } |
28 | 126k | else if(type == typeid(double)) |
29 | 103k | { |
30 | 103k | dst = any.cast<double>(); |
31 | 103k | } |
32 | 22.5k | else if(type == typeid(std::vector<double>)) |
33 | 2.37k | { |
34 | 2.37k | dst = any.cast<std::vector<double>>(); |
35 | 2.37k | } |
36 | 20.1k | else if(type == typeid(std::vector<int>)) |
37 | 3.52k | { |
38 | 3.52k | dst = any.cast<std::vector<int>>(); |
39 | 3.52k | } |
40 | 16.6k | else if(type == typeid(std::vector<std::string>)) |
41 | 3.01k | { |
42 | 3.01k | dst = any.cast<std::vector<std::string>>(); |
43 | 3.01k | } |
44 | 13.6k | else if(type == typeid(std::vector<bool>)) |
45 | 12.0k | { |
46 | 12.0k | dst = any.cast<std::vector<bool>>(); |
47 | 12.0k | } |
48 | 1.58k | else |
49 | 1.58k | { |
50 | 1.58k | auto it = to_json_converters_.find(type); |
51 | 1.58k | if(it != to_json_converters_.end()) |
52 | 0 | { |
53 | 0 | it->second(any, dst); |
54 | 0 | } |
55 | 1.58k | else |
56 | 1.58k | { |
57 | 1.58k | return false; |
58 | 1.58k | } |
59 | 1.58k | } |
60 | 542k | return true; |
61 | 544k | } |
62 | | |
63 | | JsonExporter::ExpectedEntry JsonExporter::fromJson(const nlohmann::json& source) const |
64 | 508k | { |
65 | 508k | if(source.is_null()) |
66 | 1.54k | { |
67 | 1.54k | return Entry{ BT::Any(), BT::TypeInfo::Create<std::nullptr_t>() }; |
68 | 1.54k | } |
69 | | |
70 | 506k | if(source.is_string()) |
71 | 21.3k | { |
72 | 21.3k | return Entry{ BT::Any(source.get<std::string>()), |
73 | 21.3k | BT::TypeInfo::Create<std::string>() }; |
74 | 21.3k | } |
75 | 485k | if(source.is_number_integer()) |
76 | 365k | { |
77 | 365k | return Entry{ BT::Any(source.get<int>()), BT::TypeInfo::Create<int>() }; |
78 | 365k | } |
79 | 119k | if(source.is_number_float()) |
80 | 97.3k | { |
81 | 97.3k | return Entry{ BT::Any(source.get<double>()), BT::TypeInfo::Create<double>() }; |
82 | 97.3k | } |
83 | 22.5k | if(source.is_boolean()) |
84 | 82 | { |
85 | 82 | return Entry{ BT::Any(source.get<bool>()), BT::TypeInfo::Create<bool>() }; |
86 | 82 | } |
87 | | |
88 | | // basic vectors |
89 | 22.4k | if(source.is_array() && source.size() > 0 && !source.contains("__type")) |
90 | 19.4k | { |
91 | 19.4k | const auto first_element = source[0]; |
92 | 19.4k | if(first_element.is_string()) |
93 | 3.08k | { |
94 | 3.08k | return Entry{ BT::Any(source.get<std::vector<std::string>>()), |
95 | 3.08k | BT::TypeInfo::Create<std::vector<std::string>>() }; |
96 | 3.08k | } |
97 | 16.3k | if(first_element.is_number_integer()) |
98 | 3.35k | { |
99 | 3.35k | return Entry{ BT::Any(source.get<std::vector<int>>()), |
100 | 3.35k | BT::TypeInfo::Create<std::vector<int>>() }; |
101 | 3.35k | } |
102 | 12.9k | if(first_element.is_number_float()) |
103 | 1.88k | { |
104 | 1.88k | return Entry{ BT::Any(source.get<std::vector<double>>()), |
105 | 1.88k | BT::TypeInfo::Create<std::vector<double>>() }; |
106 | 1.88k | } |
107 | 11.0k | if(first_element.is_boolean()) |
108 | 10.1k | { |
109 | 10.1k | return Entry{ BT::Any(source.get<std::vector<bool>>()), |
110 | 10.1k | BT::TypeInfo::Create<std::vector<bool>>() }; |
111 | 10.1k | } |
112 | 11.0k | } |
113 | | |
114 | 4.06k | if(source.is_array()) |
115 | 2.82k | { |
116 | 2.82k | if(source.empty()) |
117 | 1.83k | return nonstd::make_unexpected("Missing field '__type'"); |
118 | 985 | const auto& first = source[0]; |
119 | 985 | if(!first.is_object() || !first.contains("__type")) |
120 | 871 | return nonstd::make_unexpected("Missing field '__type'"); |
121 | 114 | if(!first["__type"].is_string()) |
122 | 76 | return nonstd::make_unexpected("Invalid '__type' (must be string)"); |
123 | 114 | } |
124 | 1.24k | else |
125 | 1.24k | { |
126 | 1.24k | if(!source.is_object() || !source.contains("__type") || !source["__type"].is_string()) |
127 | 589 | return nonstd::make_unexpected("Missing field '__type'"); |
128 | 1.24k | } |
129 | | |
130 | 695 | auto& from_converters = |
131 | 695 | source.is_array() ? from_json_array_converters_ : from_json_converters_; |
132 | 695 | auto type_field = source.is_array() ? source[0]["__type"] : source["__type"]; |
133 | | |
134 | 695 | auto type_it = type_names_.find(type_field); |
135 | 695 | if(type_it == type_names_.end()) |
136 | 695 | { |
137 | 695 | return nonstd::make_unexpected("Type not found in registered list"); |
138 | 695 | } |
139 | 0 | auto func_it = from_converters.find(type_it->second.type()); |
140 | 0 | if(func_it == from_converters.end()) |
141 | 0 | { |
142 | 0 | return nonstd::make_unexpected("Type not found in registered list"); |
143 | 0 | } |
144 | 0 | return func_it->second(source); |
145 | 0 | } |
146 | | |
147 | | JsonExporter::ExpectedEntry JsonExporter::fromJson(const nlohmann::json& source, |
148 | | std::type_index type) const |
149 | 0 | { |
150 | 0 | auto func_it = from_json_converters_.find(type); |
151 | 0 | if(func_it == from_json_converters_.end()) |
152 | 0 | { |
153 | 0 | return nonstd::make_unexpected("Type not found in registered list"); |
154 | 0 | } |
155 | 0 | return func_it->second(source); |
156 | 0 | } |
157 | | |
158 | | } // namespace BT |