You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

226 lines
6.1KB

  1. #include <settings.hpp>
  2. #include <window.hpp>
  3. #include <plugin.hpp>
  4. #include <app/Scene.hpp>
  5. #include <app/ModuleBrowser.hpp>
  6. #include <engine/Engine.hpp>
  7. #include <app.hpp>
  8. #include <patch.hpp>
  9. #include <jansson.h>
  10. namespace rack {
  11. namespace settings {
  12. bool devMode = false;
  13. bool headless = false;
  14. std::string token;
  15. math::Vec windowSize;
  16. math::Vec windowPos;
  17. float zoom = 0.0;
  18. bool invertZoom = false;
  19. float cableOpacity = 0.5;
  20. float cableTension = 0.5;
  21. bool allowCursorLock = true;
  22. bool realTime = false;
  23. float sampleRate = 44100.0;
  24. int threadCount = 1;
  25. bool paramTooltip = false;
  26. bool cpuMeter = false;
  27. bool lockModules = false;
  28. int frameSwapInterval = 1;
  29. float autosavePeriod = 15.0;
  30. bool skipLoadOnLaunch = false;
  31. std::string patchPath;
  32. std::vector<NVGcolor> cableColors = {
  33. nvgRGB(0xc9, 0xb7, 0x0e), // yellow
  34. nvgRGB(0x0c, 0x8e, 0x15), // green
  35. nvgRGB(0xc9, 0x18, 0x47), // red
  36. nvgRGB(0x09, 0x86, 0xad), // blue
  37. };
  38. json_t* toJson() {
  39. json_t* rootJ = json_object();
  40. json_object_set_new(rootJ, "token", json_string(token.c_str()));
  41. json_t* windowSizeJ = json_pack("[f, f]", windowSize.x, windowSize.y);
  42. json_object_set_new(rootJ, "windowSize", windowSizeJ);
  43. json_t* windowPosJ = json_pack("[f, f]", windowPos.x, windowPos.y);
  44. json_object_set_new(rootJ, "windowPos", windowPosJ);
  45. json_object_set_new(rootJ, "zoom", json_real(zoom));
  46. json_object_set_new(rootJ, "invertZoom", json_boolean(invertZoom));
  47. json_object_set_new(rootJ, "cableOpacity", json_real(cableOpacity));
  48. json_object_set_new(rootJ, "cableTension", json_real(cableTension));
  49. json_object_set_new(rootJ, "allowCursorLock", json_boolean(allowCursorLock));
  50. json_object_set_new(rootJ, "realTime", json_boolean(realTime));
  51. json_object_set_new(rootJ, "sampleRate", json_real(sampleRate));
  52. json_object_set_new(rootJ, "threadCount", json_integer(threadCount));
  53. json_object_set_new(rootJ, "paramTooltip", json_boolean(paramTooltip));
  54. json_object_set_new(rootJ, "cpuMeter", json_boolean(cpuMeter));
  55. json_object_set_new(rootJ, "lockModules", json_boolean(lockModules));
  56. json_object_set_new(rootJ, "frameSwapInterval", json_integer(frameSwapInterval));
  57. json_object_set_new(rootJ, "autosavePeriod", json_real(autosavePeriod));
  58. if (skipLoadOnLaunch) {
  59. json_object_set_new(rootJ, "skipLoadOnLaunch", json_true());
  60. }
  61. json_object_set_new(rootJ, "patchPath", json_string(patchPath.c_str()));
  62. json_t* cableColorsJ = json_array();
  63. for (NVGcolor cableColor : cableColors) {
  64. std::string colorStr = color::toHexString(cableColor);
  65. json_array_append_new(cableColorsJ, json_string(colorStr.c_str()));
  66. }
  67. json_object_set_new(rootJ, "cableColors", cableColorsJ);
  68. return rootJ;
  69. }
  70. void fromJson(json_t* rootJ) {
  71. json_t* tokenJ = json_object_get(rootJ, "token");
  72. if (tokenJ)
  73. token = json_string_value(tokenJ);
  74. json_t* windowSizeJ = json_object_get(rootJ, "windowSize");
  75. if (windowSizeJ) {
  76. double x, y;
  77. json_unpack(windowSizeJ, "[F, F]", &x, &y);
  78. windowSize = math::Vec(x, y);
  79. }
  80. json_t* windowPosJ = json_object_get(rootJ, "windowPos");
  81. if (windowPosJ) {
  82. double x, y;
  83. json_unpack(windowPosJ, "[F, F]", &x, &y);
  84. windowPos = math::Vec(x, y);
  85. }
  86. json_t* zoomJ = json_object_get(rootJ, "zoom");
  87. if (zoomJ)
  88. zoom = json_number_value(zoomJ);
  89. json_t* invertZoomJ = json_object_get(rootJ, "invertZoom");
  90. if (invertZoomJ)
  91. invertZoom = json_boolean_value(invertZoomJ);
  92. json_t* cableOpacityJ = json_object_get(rootJ, "cableOpacity");
  93. if (cableOpacityJ)
  94. cableOpacity = json_number_value(cableOpacityJ);
  95. json_t* tensionJ = json_object_get(rootJ, "cableTension");
  96. if (tensionJ)
  97. cableTension = json_number_value(tensionJ);
  98. json_t* allowCursorLockJ = json_object_get(rootJ, "allowCursorLock");
  99. if (allowCursorLockJ)
  100. allowCursorLock = json_is_true(allowCursorLockJ);
  101. json_t* realTimeJ = json_object_get(rootJ, "realTime");
  102. if (realTimeJ)
  103. realTime = json_boolean_value(realTimeJ);
  104. json_t* sampleRateJ = json_object_get(rootJ, "sampleRate");
  105. if (sampleRateJ)
  106. sampleRate = json_number_value(sampleRateJ);
  107. json_t* threadCountJ = json_object_get(rootJ, "threadCount");
  108. if (threadCountJ)
  109. threadCount = json_integer_value(threadCountJ);
  110. json_t* paramTooltipJ = json_object_get(rootJ, "paramTooltip");
  111. if (paramTooltipJ)
  112. paramTooltip = json_boolean_value(paramTooltipJ);
  113. json_t* cpuMeterJ = json_object_get(rootJ, "cpuMeter");
  114. if (cpuMeterJ)
  115. cpuMeter = json_boolean_value(cpuMeterJ);
  116. json_t* lockModulesJ = json_object_get(rootJ, "lockModules");
  117. if (lockModulesJ)
  118. lockModules = json_boolean_value(lockModulesJ);
  119. json_t* frameSwapIntervalJ = json_object_get(rootJ, "frameSwapInterval");
  120. if (frameSwapIntervalJ)
  121. frameSwapInterval = json_integer_value(frameSwapIntervalJ);
  122. json_t* autosavePeriodJ = json_object_get(rootJ, "autosavePeriod");
  123. if (autosavePeriodJ)
  124. autosavePeriod = json_number_value(autosavePeriodJ);
  125. json_t* skipLoadOnLaunchJ = json_object_get(rootJ, "skipLoadOnLaunch");
  126. if (skipLoadOnLaunchJ)
  127. skipLoadOnLaunch = json_boolean_value(skipLoadOnLaunchJ);
  128. json_t* patchPathJ = json_object_get(rootJ, "patchPath");
  129. if (patchPathJ)
  130. patchPath = json_string_value(patchPathJ);
  131. json_t* cableColorsJ = json_object_get(rootJ, "cableColors");
  132. if (cableColorsJ) {
  133. cableColors.clear();
  134. size_t i;
  135. json_t* cableColorJ;
  136. json_array_foreach(cableColorsJ, i, cableColorJ) {
  137. std::string colorStr = json_string_value(cableColorJ);
  138. cableColors.push_back(color::fromHexString(colorStr));
  139. }
  140. }
  141. }
  142. void save(const std::string& path) {
  143. INFO("Saving settings %s", path.c_str());
  144. json_t* rootJ = toJson();
  145. if (!rootJ)
  146. return;
  147. FILE* file = fopen(path.c_str(), "w");
  148. if (!file)
  149. return;
  150. DEFER({
  151. fclose(file);
  152. });
  153. json_dumpf(rootJ, file, JSON_INDENT(2) | JSON_REAL_PRECISION(9));
  154. json_decref(rootJ);
  155. }
  156. void load(const std::string& path) {
  157. INFO("Loading settings %s", path.c_str());
  158. FILE* file = fopen(path.c_str(), "r");
  159. if (!file)
  160. return;
  161. DEFER({
  162. fclose(file);
  163. });
  164. json_error_t error;
  165. json_t* rootJ = json_loadf(file, 0, &error);
  166. if (!rootJ)
  167. throw UserException(string::f("Settings file has invalid JSON at %d:%d %s", error.line, error.column, error.text));
  168. fromJson(rootJ);
  169. json_decref(rootJ);
  170. }
  171. } // namespace settings
  172. } // namespace rack