28 rapidjson::Document json{};
34 if (not json.HasMember(osc_path_v<T, Components>))
return;
35 auto& m = json[osc_path_v<T, Components>];
38 if constexpr (std::integral<value_t<T>>)
40 if constexpr (std::is_signed_v<value_t<T>>)
42 if (m.IsInt()) f(m.GetInt());
43 else if (m.IsInt64()) f(m.GetInt64());
46 if (m.IsUint()) f(m.GetUint());
47 else if (m.IsUint64()) f(m.GetUint64());
49 }
else if constexpr (std::floating_point<value_t<T>>)
51 if (m.IsDouble()) f(
static_cast<value_t<T>
>(m.GetDouble()));
54 if (m.IsString()) f(m.GetString());
57 if (!m.IsArray() || m.Empty() || m.Size() != size<value_t<T>>())
return;
58 if constexpr (std::integral<element_t<T>>)
61 f(m, [](
auto& arr,
auto idx) {
return arr[idx].GetInt(); });
62 else if (m[0].IsInt64())
63 f(m, [](
auto& arr,
auto idx) {
return arr[idx].GetInt64(); });
64 }
else if constexpr (std::floating_point<element_t<T>>)
67 f(m, [](
auto& arr,
auto idx) {
return arr[idx].GetDouble(); });
71 f(m, [](
auto& arr,
auto idx) {
return arr[idx].GetString(); });
77 void init(IStream& istream, Components& components)
79 json.ParseStream(istream);
80 if (not json.IsObject())
85 for_each_session_datum(components, [&]<
typename T>(T& endpoint)
88 apply_with_json_member_value<T>(json, [&](
auto& arr,
auto&& get)
90 for (std::size_t i = 0; i < size<value_t<T>>(); ++i)
91 value_of(endpoint)[i] = get(arr, i);
93 else apply_with_json_member_value<T>(json, [&](
auto value)
95 set_value(endpoint, value);
101 void external_destinations(Components& components)
103 bool updated =
false;
104 for_each_session_datum(components, [&]<
typename T>(T& endpoint)
106 if constexpr (has_value<T>)
108 if (not json.HasMember(osc_path_v<T, Components>))
110 if constexpr (string_like<value_t<T>>)
112 rapidjson::Value v{value_of(endpoint).c_str(), json.GetAllocator()};
113 json.AddMember(rapidjson::GenericStringRef{osc_path_v<T, Components>}, v, json.GetAllocator());
115 else if constexpr (array_like<value_t<T>>)
117 rapidjson::Value v{rapidjson::kArrayType};
118 v.Reserve(3, json.GetAllocator());
119 for (
auto& element : value_of(endpoint)) v.PushBack(rapidjson::Value{element}, json.GetAllocator());
120 json.AddMember(rapidjson::GenericStringRef{osc_path_v<T, Components>}, v, json.GetAllocator());
124 json.AddMember(rapidjson::GenericStringRef{osc_path_v<T, Components>}, value_of(endpoint), json.GetAllocator());
130 bool endpoint_updated =
false;
131 if constexpr (OccasionalValue<T>)
132 endpoint_updated = flag_state_of(endpoint);
133 else if constexpr (array_like<value_t<T>>)
134 apply_with_json_member_value<T>(json, [&](
auto& arr,
auto&& get)
136 for (std::size_t i = 0; i < size<value_t<T>>(); ++i)
137 endpoint_updated = endpoint_updated || (value_of(endpoint)[i] != get(arr, i));
139 else apply_with_json_member_value<T>(json, [&](
auto value)
141 endpoint_updated = value != value_of(endpoint);
143 if (endpoint_updated)
145 if constexpr (string_like<value_t<T>>)
146 json[osc_path_v<T, Components>].SetString(value_of(endpoint).c_str(), json.GetAllocator());
147 else if constexpr (array_like<value_t<T>>)
149 auto& arr = json[osc_path_v<T, Components>];
150 for (std::size_t i = 0; i < size<value_t<T>>(); ++i)
152 arr[i] = value_of(endpoint)[i];
155 else json[osc_path_v<T, Components>] = value_of(endpoint);
164 json.Accept(ostream.writer);