diff --git a/.gitignore b/.gitignore index bb6cf582..c7086e9b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,7 @@ -Rack -Rack.exe -autosave.json -build \ No newline at end of file +/Rack +/Rack.exe +/autosave.json +/settings.json +/plugins +/build +/dep \ No newline at end of file diff --git a/include/plugin.hpp b/include/plugin.hpp index f55dedd5..b7ac227b 100644 --- a/include/plugin.hpp +++ b/include/plugin.hpp @@ -33,6 +33,7 @@ struct Model { }; extern std::list gPlugins; +extern std::string gToken; void pluginInit(); void pluginDestroy(); diff --git a/include/settings.hpp b/include/settings.hpp new file mode 100644 index 00000000..8714c63a --- /dev/null +++ b/include/settings.hpp @@ -0,0 +1,13 @@ +#pragma once + +#include + + +namespace rack { + + +void settingsSave(std::string filename); +void settingsLoad(std::string filename); + + +} // namespace rack diff --git a/include/util/request.hpp b/include/util/request.hpp index 3df0f167..e5d42563 100644 --- a/include/util/request.hpp +++ b/include/util/request.hpp @@ -4,6 +4,9 @@ #include +namespace rack { + + enum RequestMethod { GET_METHOD, POST_METHOD, @@ -15,3 +18,5 @@ enum RequestMethod { json_t *requestJson(RequestMethod method, std::string url, json_t *dataJ); /** Returns the filename, blank if unsuccessful */ bool requestDownload(std::string url, std::string filename, float *progress); + +} // namespace rack diff --git a/src/app/RackWidget.cpp b/src/app/RackWidget.cpp index 174b10d9..18f50ab1 100644 --- a/src/app/RackWidget.cpp +++ b/src/app/RackWidget.cpp @@ -299,11 +299,6 @@ void RackWidget::step() { } } - // Autosave every 15 seconds - if (gGuiFrame % (60*15) == 0) { - savePatch("autosave.json"); - } - Widget::step(); } diff --git a/src/gui.cpp b/src/gui.cpp index ae9f0f01..3d824562 100644 --- a/src/gui.cpp +++ b/src/gui.cpp @@ -2,6 +2,7 @@ #include "gui.hpp" #include "app.hpp" +#include "settings.hpp" #define NANOVG_GL2_IMPLEMENTATION // #define NANOVG_GL3_IMPLEMENTATION @@ -155,7 +156,7 @@ void charCallback(GLFWwindow *window, unsigned int codepoint) { } } -static int lastWindowX, lastWindowY, lastWindowWidth, lastWindowHeight; +// static int lastWindowX, lastWindowY, lastWindowWidth, lastWindowHeight; void keyCallback(GLFWwindow* window, int key, int scancode, int action, int mods) { if (action == GLFW_PRESS || action == GLFW_REPEAT) { @@ -299,8 +300,15 @@ void guiRun() { } gScene->step(); + // Render renderGui(); + // Autosave every 15 seconds + if (gGuiFrame % (60*15) == 0) { + gRackWidget->savePatch("autosave.json"); + settingsSave("settings.json"); + } + double currTime = glfwGetTime(); // printf("%lf fps\n", 1.0/(currTime - lastTime)); lastTime = currTime; diff --git a/src/main.cpp b/src/main.cpp index 3966333f..39846603 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2,6 +2,7 @@ #include "gui.hpp" #include "app.hpp" #include "plugin.hpp" +#include "settings.hpp" #if ARCH_MAC @@ -96,6 +97,7 @@ int main() { engineInit(); guiInit(); sceneInit(); + settingsLoad("settings.json"); gRackWidget->loadPatch("autosave.json"); engineStart(); @@ -103,6 +105,7 @@ int main() { engineStop(); gRackWidget->savePatch("autosave.json"); + settingsSave("settings.json"); sceneDestroy(); guiDestroy(); engineDestroy(); diff --git a/src/plugin.cpp b/src/plugin.cpp index c054faf5..3b4fe487 100644 --- a/src/plugin.cpp +++ b/src/plugin.cpp @@ -27,8 +27,8 @@ namespace rack { std::list gPlugins; +std::string gToken; -static std::string token; static bool isDownloading = false; static float downloadProgress = 0.0; static std::string downloadName; @@ -204,7 +204,7 @@ void pluginLogIn(std::string email, std::string password) { json_t *tokenJ = json_object_get(resJ, "token"); if (tokenJ) { const char *tokenStr = json_string_value(tokenJ); - token = tokenStr; + gToken = tokenStr; loginStatus = ""; } } @@ -213,7 +213,7 @@ void pluginLogIn(std::string email, std::string password) { } void pluginLogOut() { - token = ""; + gToken = ""; } static void pluginRefreshPlugin(json_t *pluginJ) { @@ -260,7 +260,7 @@ static void pluginRefreshPlugin(json_t *pluginJ) { } void pluginRefresh() { - if (token.empty()) + if (gToken.empty()) return; isDownloading = true; @@ -268,7 +268,7 @@ void pluginRefresh() { downloadName = ""; json_t *reqJ = json_object(); - json_object_set(reqJ, "token", json_string(token.c_str())); + json_object_set(reqJ, "token", json_string(gToken.c_str())); json_t *resJ = requestJson(GET_METHOD, apiHost + "/purchases", reqJ); json_decref(reqJ); @@ -297,7 +297,7 @@ void pluginCancelDownload() { } bool pluginIsLoggedIn() { - return token != ""; + return gToken != ""; } bool pluginIsDownloading() { diff --git a/src/settings.cpp b/src/settings.cpp new file mode 100644 index 00000000..c895bb9d --- /dev/null +++ b/src/settings.cpp @@ -0,0 +1,84 @@ +#include "settings.hpp" +#include "app.hpp" +#include "plugin.hpp" +#include + + +namespace rack { + + +static json_t *settingsToJson() { + // root + json_t *rootJ = json_object(); + + // token + json_t *tokenJ = json_string(gToken.c_str()); + json_object_set_new(rootJ, "token", tokenJ); + + // opacity + float opacity = dynamic_cast(gScene)->toolbar->wireOpacitySlider->value; + json_t *opacityJ = json_real(opacity); + json_object_set_new(rootJ, "opacity", opacityJ); + + // tension + float tension = dynamic_cast(gScene)->toolbar->wireTensionSlider->value; + json_t *tensionJ = json_real(tension); + json_object_set_new(rootJ, "tension", tensionJ); + + return rootJ; +} + +static void settingsFromJson(json_t *rootJ) { + // token + json_t *tokenJ = json_object_get(rootJ, "token"); + if (tokenJ) + gToken = json_string_value(tokenJ); + + // opacity + json_t *opacityJ = json_object_get(rootJ, "opacity"); + if (opacityJ) + dynamic_cast(gScene)->toolbar->wireOpacitySlider->value = json_number_value(opacityJ); + + // tension + json_t *tensionJ = json_object_get(rootJ, "tension"); + if (tensionJ) + dynamic_cast(gScene)->toolbar->wireTensionSlider->value = json_number_value(tensionJ); +} + + +void settingsSave(std::string filename) { + printf("Saving settings %s\n", filename.c_str()); + FILE *file = fopen(filename.c_str(), "w"); + if (!file) + return; + + json_t *rootJ = settingsToJson(); + if (rootJ) { + json_dumpf(rootJ, file, JSON_INDENT(2)); + json_decref(rootJ); + } + + fclose(file); +} + +void settingsLoad(std::string filename) { + printf("Loading settings %s\n", filename.c_str()); + FILE *file = fopen(filename.c_str(), "r"); + if (!file) + return; + + json_error_t error; + json_t *rootJ = json_loadf(file, 0, &error); + if (rootJ) { + settingsFromJson(rootJ); + json_decref(rootJ); + } + else { + printf("JSON parsing error at %s %d:%d %s\n", error.source, error.line, error.column, error.text); + } + + fclose(file); +} + + +} // namespace rack diff --git a/src/util/request.cpp b/src/util/request.cpp index e25b3df3..5693f368 100644 --- a/src/util/request.cpp +++ b/src/util/request.cpp @@ -5,6 +5,8 @@ #include +namespace rack { + static size_t writeStringCallback(char *ptr, size_t size, size_t nmemb, void *userdata) { std::string *str = (std::string*) userdata; size_t len = size * nmemb; @@ -145,3 +147,6 @@ bool requestDownload(std::string url, std::string filename, float *progress) { return res == CURLE_OK; } + + +} // namespace rack