| @@ -1,4 +1,7 @@ | |||||
| Rack | |||||
| Rack.exe | |||||
| autosave.json | |||||
| build | |||||
| /Rack | |||||
| /Rack.exe | |||||
| /autosave.json | |||||
| /settings.json | |||||
| /plugins | |||||
| /build | |||||
| /dep | |||||
| @@ -33,6 +33,7 @@ struct Model { | |||||
| }; | }; | ||||
| extern std::list<Plugin*> gPlugins; | extern std::list<Plugin*> gPlugins; | ||||
| extern std::string gToken; | |||||
| void pluginInit(); | void pluginInit(); | ||||
| void pluginDestroy(); | void pluginDestroy(); | ||||
| @@ -0,0 +1,13 @@ | |||||
| #pragma once | |||||
| #include <string> | |||||
| namespace rack { | |||||
| void settingsSave(std::string filename); | |||||
| void settingsLoad(std::string filename); | |||||
| } // namespace rack | |||||
| @@ -4,6 +4,9 @@ | |||||
| #include <jansson.h> | #include <jansson.h> | ||||
| namespace rack { | |||||
| enum RequestMethod { | enum RequestMethod { | ||||
| GET_METHOD, | GET_METHOD, | ||||
| POST_METHOD, | POST_METHOD, | ||||
| @@ -15,3 +18,5 @@ enum RequestMethod { | |||||
| json_t *requestJson(RequestMethod method, std::string url, json_t *dataJ); | json_t *requestJson(RequestMethod method, std::string url, json_t *dataJ); | ||||
| /** Returns the filename, blank if unsuccessful */ | /** Returns the filename, blank if unsuccessful */ | ||||
| bool requestDownload(std::string url, std::string filename, float *progress); | bool requestDownload(std::string url, std::string filename, float *progress); | ||||
| } // namespace rack | |||||
| @@ -299,11 +299,6 @@ void RackWidget::step() { | |||||
| } | } | ||||
| } | } | ||||
| // Autosave every 15 seconds | |||||
| if (gGuiFrame % (60*15) == 0) { | |||||
| savePatch("autosave.json"); | |||||
| } | |||||
| Widget::step(); | Widget::step(); | ||||
| } | } | ||||
| @@ -2,6 +2,7 @@ | |||||
| #include "gui.hpp" | #include "gui.hpp" | ||||
| #include "app.hpp" | #include "app.hpp" | ||||
| #include "settings.hpp" | |||||
| #define NANOVG_GL2_IMPLEMENTATION | #define NANOVG_GL2_IMPLEMENTATION | ||||
| // #define NANOVG_GL3_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) { | void keyCallback(GLFWwindow* window, int key, int scancode, int action, int mods) { | ||||
| if (action == GLFW_PRESS || action == GLFW_REPEAT) { | if (action == GLFW_PRESS || action == GLFW_REPEAT) { | ||||
| @@ -299,8 +300,15 @@ void guiRun() { | |||||
| } | } | ||||
| gScene->step(); | gScene->step(); | ||||
| // Render | |||||
| renderGui(); | renderGui(); | ||||
| // Autosave every 15 seconds | |||||
| if (gGuiFrame % (60*15) == 0) { | |||||
| gRackWidget->savePatch("autosave.json"); | |||||
| settingsSave("settings.json"); | |||||
| } | |||||
| double currTime = glfwGetTime(); | double currTime = glfwGetTime(); | ||||
| // printf("%lf fps\n", 1.0/(currTime - lastTime)); | // printf("%lf fps\n", 1.0/(currTime - lastTime)); | ||||
| lastTime = currTime; | lastTime = currTime; | ||||
| @@ -2,6 +2,7 @@ | |||||
| #include "gui.hpp" | #include "gui.hpp" | ||||
| #include "app.hpp" | #include "app.hpp" | ||||
| #include "plugin.hpp" | #include "plugin.hpp" | ||||
| #include "settings.hpp" | |||||
| #if ARCH_MAC | #if ARCH_MAC | ||||
| @@ -96,6 +97,7 @@ int main() { | |||||
| engineInit(); | engineInit(); | ||||
| guiInit(); | guiInit(); | ||||
| sceneInit(); | sceneInit(); | ||||
| settingsLoad("settings.json"); | |||||
| gRackWidget->loadPatch("autosave.json"); | gRackWidget->loadPatch("autosave.json"); | ||||
| engineStart(); | engineStart(); | ||||
| @@ -103,6 +105,7 @@ int main() { | |||||
| engineStop(); | engineStop(); | ||||
| gRackWidget->savePatch("autosave.json"); | gRackWidget->savePatch("autosave.json"); | ||||
| settingsSave("settings.json"); | |||||
| sceneDestroy(); | sceneDestroy(); | ||||
| guiDestroy(); | guiDestroy(); | ||||
| engineDestroy(); | engineDestroy(); | ||||
| @@ -27,8 +27,8 @@ | |||||
| namespace rack { | namespace rack { | ||||
| std::list<Plugin*> gPlugins; | std::list<Plugin*> gPlugins; | ||||
| std::string gToken; | |||||
| static std::string token; | |||||
| static bool isDownloading = false; | static bool isDownloading = false; | ||||
| static float downloadProgress = 0.0; | static float downloadProgress = 0.0; | ||||
| static std::string downloadName; | static std::string downloadName; | ||||
| @@ -204,7 +204,7 @@ void pluginLogIn(std::string email, std::string password) { | |||||
| json_t *tokenJ = json_object_get(resJ, "token"); | json_t *tokenJ = json_object_get(resJ, "token"); | ||||
| if (tokenJ) { | if (tokenJ) { | ||||
| const char *tokenStr = json_string_value(tokenJ); | const char *tokenStr = json_string_value(tokenJ); | ||||
| token = tokenStr; | |||||
| gToken = tokenStr; | |||||
| loginStatus = ""; | loginStatus = ""; | ||||
| } | } | ||||
| } | } | ||||
| @@ -213,7 +213,7 @@ void pluginLogIn(std::string email, std::string password) { | |||||
| } | } | ||||
| void pluginLogOut() { | void pluginLogOut() { | ||||
| token = ""; | |||||
| gToken = ""; | |||||
| } | } | ||||
| static void pluginRefreshPlugin(json_t *pluginJ) { | static void pluginRefreshPlugin(json_t *pluginJ) { | ||||
| @@ -260,7 +260,7 @@ static void pluginRefreshPlugin(json_t *pluginJ) { | |||||
| } | } | ||||
| void pluginRefresh() { | void pluginRefresh() { | ||||
| if (token.empty()) | |||||
| if (gToken.empty()) | |||||
| return; | return; | ||||
| isDownloading = true; | isDownloading = true; | ||||
| @@ -268,7 +268,7 @@ void pluginRefresh() { | |||||
| downloadName = ""; | downloadName = ""; | ||||
| json_t *reqJ = json_object(); | 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_t *resJ = requestJson(GET_METHOD, apiHost + "/purchases", reqJ); | ||||
| json_decref(reqJ); | json_decref(reqJ); | ||||
| @@ -297,7 +297,7 @@ void pluginCancelDownload() { | |||||
| } | } | ||||
| bool pluginIsLoggedIn() { | bool pluginIsLoggedIn() { | ||||
| return token != ""; | |||||
| return gToken != ""; | |||||
| } | } | ||||
| bool pluginIsDownloading() { | bool pluginIsDownloading() { | ||||
| @@ -0,0 +1,84 @@ | |||||
| #include "settings.hpp" | |||||
| #include "app.hpp" | |||||
| #include "plugin.hpp" | |||||
| #include <jansson.h> | |||||
| 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<RackScene*>(gScene)->toolbar->wireOpacitySlider->value; | |||||
| json_t *opacityJ = json_real(opacity); | |||||
| json_object_set_new(rootJ, "opacity", opacityJ); | |||||
| // tension | |||||
| float tension = dynamic_cast<RackScene*>(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<RackScene*>(gScene)->toolbar->wireOpacitySlider->value = json_number_value(opacityJ); | |||||
| // tension | |||||
| json_t *tensionJ = json_object_get(rootJ, "tension"); | |||||
| if (tensionJ) | |||||
| dynamic_cast<RackScene*>(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 | |||||
| @@ -5,6 +5,8 @@ | |||||
| #include <curl/curl.h> | #include <curl/curl.h> | ||||
| namespace rack { | |||||
| static size_t writeStringCallback(char *ptr, size_t size, size_t nmemb, void *userdata) { | static size_t writeStringCallback(char *ptr, size_t size, size_t nmemb, void *userdata) { | ||||
| std::string *str = (std::string*) userdata; | std::string *str = (std::string*) userdata; | ||||
| size_t len = size * nmemb; | size_t len = size * nmemb; | ||||
| @@ -145,3 +147,6 @@ bool requestDownload(std::string url, std::string filename, float *progress) { | |||||
| return res == CURLE_OK; | return res == CURLE_OK; | ||||
| } | } | ||||
| } // namespace rack | |||||