C++ API Reference RNBO: src/RNBO_Presets.h Source File

RNBO: src/RNBO_Presets.h Source File

Go to the documentation of this file.
1 //
2 // RNBO_Presets.h
3 //
4 
5 #ifndef _RNBO_Presets_H_
6 #define _RNBO_Presets_H_
7 
8 #include "RNBO_Std.h"
9 #include "RNBO_PatcherState.h"
10 
11 #ifdef RNBO_NOSTDLIB
12 #define RNBO_NOPRESETS
13 #endif
14 
15 #ifdef RNBO_NOPRESETS
16 
17 namespace RNBO {
18  using Preset = PatcherState;
19  using PresetCallback = void(*);
20  using UniquePresetPtr = void*;
21  using PresetPtr = std::shared_ptr<Preset>;
22  using ConstPresetPtr = std::shared_ptr<const Preset>;
23 }
24 
25 #else
26 
27 RNBO_PUSH_DISABLE_WARNINGS
28 #include "3rdparty/json/json.hpp"
29 RNBO_POP_DISABLE_WARNINGS
30 
31 #include "RNBO_Utils.h"
32 #include "RNBO_Debug.h"
33 
40 namespace RNBO {
41 
42  using PresetMap = StateMap;
43 
49 
56  using PresetPtr = std::shared_ptr<Preset>;
57 
62  using PresetCallback = std::function<void(std::shared_ptr<const Preset>)>;
63 
70  using ConstPresetPtr = std::shared_ptr<const Preset>;
71 
76  std::string name;
77  PresetPtr preset;
78  };
79 
80  class DummyPreset : public PatcherState
81  {
82  public:
83  bool isDummy() const override { return true; }
84  };
85 
86 #ifdef RNBO_NOSTDLIB
88 #else
89 
95  using UniquePresetPtr = std::unique_ptr<Preset>;
96 #endif // RNBO_NOSTDLIB
97 
98 #ifndef RNBO_NOJSONPRESETS
99 
100  using Json = nlohmann::json;
101 
102  static Json convertPresetToJSONObj(const Preset& preset) {
103  Json json;
104  for (auto const& entry : preset) {
105  const char *key = entry.first.c_str();
106  auto type = entry.second.getType();
107  switch (type) {
108  case ValueHolder::FLOAT: {
109  float value = (float)entry.second;
110  json[key] = value;
111  break;
112  }
113  case ValueHolder::DOUBLE: {
114  double value = (double)entry.second;
115  json[key] = value;
116  break;
117  }
118  case ValueHolder::LIST: {
119  Json j;
120  const list& value = entry.second;
121  for (size_t i = 0; i < value.length; i++) {
122  j.push_back(value[i]);
123  }
124  json[key] = j;
125  break;
126  }
127  case ValueHolder::STRING: {
128  const char * str = entry.second;
129  json[key] = str;
130  break;
131  }
132  case ValueHolder::SUBSTATE: {
133  const Preset& subPreset = entry.second;
134  json[key] = convertPresetToJSONObj(subPreset);
135  break;
136  }
138  Index size = entry.second.getSubStateMapSize();
139  if (size) {
140  Json j;
141  for (Index i = 0; i < size; i++) {
142  const Preset& subPreset = entry.second[i];
143  j.push_back(convertPresetToJSONObj(subPreset));
144  }
145  json[key] = j;
146  }
147  break;
148  }
149  case ValueHolder::UINT32: {
150  UInt32 value = (UInt32)entry.second;
151  json[key] = value;
152  break;
153  }
154  case ValueHolder::UINT64: {
155  UInt64 value = (UInt64)entry.second;
156  json[key] = value;
157  break;
158  }
159  case ValueHolder::NONE:
160  case ValueHolder::EXTERNAL:
161  case ValueHolder::EVENTTARGET:
162  case ValueHolder::DATAREF:
163  case ValueHolder::MULTIREF:
164  case ValueHolder::SIGNAL:
165  case ValueHolder::BOOLEAN:
166  case ValueHolder::INTVALUE:
167  default:
168  // we do only support numbers, lists and substates
169  RNBO_ASSERT(false);
170  }
171  }
172 
173  return json;
174  }
175 
176  ATTRIBUTE_UNUSED
177  static std::string convertPresetToJSON(const Preset& preset) {
178  return convertPresetToJSONObj(preset).dump();
179  }
180 
181  static void convertJSONObjToPreset(Json& json, Preset& preset) {
182  for (Json::iterator it = json.begin(); it != json.end(); it++) {
183  const char* key = it.key().c_str();
184  if (it->is_number()) {
185  number value = it.value();
186  preset[key] = value;
187  }
188  else if (it->is_string()) {
189  std::string value = it.value();
190  preset[key] = value.c_str();
191  }
192  else if (it->is_array()) {
193  Json& j = *it;
194  if (j.size() > 0) {
195  if (j[0].is_number()) {
196  list value;
197  for (Index i = 0; i < j.size(); i++) {
198  value.push(j[i]);
199  }
200  preset[key] = value;
201  }
202  else if (j[0].is_object()) {
203  for (Index i = 0; i < j.size(); i++) {
204  Preset& subPreset = preset[key][i];
205  convertJSONObjToPreset(j[i], subPreset);
206  }
207  }
208  }
209  }
210  else if (it->is_object()) {
211  Json& j = *it;
212  Preset& subPreset = preset.getSubState(key);
213  convertJSONObjToPreset(j, subPreset);
214  }
215  }
216  }
217 
218  ATTRIBUTE_UNUSED
219  static void convertJSONArrayToPresetList(std::string jsonString, std::vector<std::shared_ptr<NamedPresetEntry>>& presetList) {
220  Json json = Json::parse(jsonString);
221  for (Json::iterator it = json.begin(); it != json.end(); it++) {
222  if (it->is_object()) {
223  Json& j = *it;
224  std::shared_ptr<NamedPresetEntry> entry(new NamedPresetEntry);
225  std::string name = j["name"];
226  Json presetPayload = j["preset"];
227  entry->name = name;
228  PresetPtr preset = std::make_shared<Preset>();
229  convertJSONObjToPreset(presetPayload, *preset);
230  entry->preset = preset;
231  presetList.push_back(entry);
232  }
233  }
234  }
235 
236  ATTRIBUTE_UNUSED
237  static UniquePresetPtr convertJSONToPreset(std::string jsonString) {
238  UniquePresetPtr preset = make_unique<Preset>();
239  Json json = Json::parse(jsonString);
240  convertJSONObjToPreset(json, *preset);
241  return preset;
242  }
243 
244  ATTRIBUTE_UNUSED
245  static void copyPreset(const Preset& src, Preset &dst)
246  {
247  for (auto const& entry : src) {
248  const char *key = entry.first.c_str();
249  auto type = entry.second.getType();
250  switch (type) {
251  case ValueHolder::FLOAT: {
252  float value = (float)entry.second;
253  dst[key] = value;
254  break;
255  }
256  case ValueHolder::DOUBLE: {
257  double value = (double)entry.second;
258  dst[key] = value;
259  break;
260  }
261  case ValueHolder::UINT32: {
262  UInt32 value = (UInt32)entry.second;
263  dst[key] = value;
264  break;
265  }
266  case ValueHolder::UINT64: {
267  UInt64 value = (UInt64)entry.second;
268  dst[key] = value;
269  break;
270  }
271  case ValueHolder::LIST: {
272  Json j;
273  const list& srclist = entry.second;
274  list dstlist;
275  for (Index i = 0; i < srclist.length; i++) {
276  dstlist.push(srclist[i]);
277  }
278  dst[key] = dstlist;
279  break;
280  }
281  case ValueHolder::SUBSTATE: {
282  const Preset& preset = entry.second;
283  copyPreset(preset, dst[key]);
284  break;
285  }
287  Index size = entry.second.getSubStateMapSize();
288  if (size) {
289  for (Index i = 0; i < size; i++) {
290  const Preset& preset = entry.second[i];
291  Preset& dstSubPreset = dst[key][i];
292  copyPreset(preset, dstSubPreset);
293  }
294  }
295  break;
296  }
297  case ValueHolder::STRING:
298  //presetid
299  RNBO_ASSERT(strcmp(key, "__presetid") == 0);
300  break;
301  case ValueHolder::NONE:
302  case ValueHolder::EXTERNAL:
303  case ValueHolder::EVENTTARGET:
304  case ValueHolder::DATAREF:
305  case ValueHolder::MULTIREF:
306  case ValueHolder::SIGNAL:
307  case ValueHolder::BOOLEAN:
308  case ValueHolder::INTVALUE:
309  default:
310  // we do only support numbers, lists and substates
311  RNBO_ASSERT(false);
312  break;
313  }
314  }
315  }
316 
317 #endif // RNBO_NOJSONPRESETS
318 
319 } // namespace RNBO
320 
321 #endif // RNBO_NOPRESETS
322 
323 #endif // _RNBO_Presets_H_