diff --git a/include/app.hpp b/include/app.hpp index 1c9d2281..a31c158b 100644 --- a/include/app.hpp +++ b/include/app.hpp @@ -42,12 +42,12 @@ struct App { history::State *history = NULL; PatchManager *patch = NULL; - void init(bool headless); + void init(); ~App(); }; -void appInit(bool headless); +void appInit(); void appDestroy(); /** Returns the global App pointer */ App *appGet(); diff --git a/include/app/Scene.hpp b/include/app/Scene.hpp index 0cbd1f40..3e6ab2a0 100644 --- a/include/app/Scene.hpp +++ b/include/app/Scene.hpp @@ -18,7 +18,6 @@ struct Scene : widget::OpaqueWidget { widget::Widget *moduleBrowser; // Version checking - bool devMode = false; bool checkVersion = true; bool checkedVersion = false; std::string latestVersion; diff --git a/include/asset.hpp b/include/asset.hpp index e394ba0a..7d4ea6b1 100644 --- a/include/asset.hpp +++ b/include/asset.hpp @@ -13,7 +13,7 @@ namespace plugin { namespace asset { -void init(bool devMode); +void init(); /** Returns the path of a system resource. Should only read files from this location. */ std::string system(std::string filename); /** Returns the path of a user resource. Can read and write files to this location. */ diff --git a/include/logger.hpp b/include/logger.hpp index a35a2e23..f77ff97f 100644 --- a/include/logger.hpp +++ b/include/logger.hpp @@ -27,7 +27,7 @@ enum Level { FATAL_LEVEL }; -void init(bool devMode); +void init(); void destroy(); /** Do not use this function directly. Use the macros below. Thread-safe. diff --git a/include/settings.hpp b/include/settings.hpp index 3f4a8ba2..f69f82e9 100644 --- a/include/settings.hpp +++ b/include/settings.hpp @@ -9,6 +9,11 @@ namespace rack { struct Settings { + /** Runtime state, not serialized. */ + bool devMode = false; + bool headless = false; + + /** Persistent state, serialized to settings.json. */ std::string token; math::Vec windowSize; math::Vec windowPos; @@ -31,8 +36,8 @@ struct Settings { json_t *toJson(); void fromJson(json_t *rootJ); - void save(std::string filename); - void load(std::string filename); + void save(const std::string &path); + void load(const std::string &path); }; diff --git a/src/app.cpp b/src/app.cpp index 60639c19..ccb1ac60 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -5,14 +5,15 @@ #include "engine/Engine.hpp" #include "app/Scene.hpp" #include "history.hpp" +#include "settings.hpp" namespace rack { -void App::init(bool headless) { +void App::init() { engine = new engine::Engine; - if (!headless) { + if (!settings.headless) { event = new widget::EventState; history = new history::State; window = new Window; @@ -41,10 +42,10 @@ App::~App() { static App *appInstance = NULL; -void appInit(bool headless) { +void appInit() { assert(!appInstance); appInstance = new App; - appInstance->init(headless); + appInstance->init(); } void appDestroy() { diff --git a/src/app/Scene.cpp b/src/app/Scene.cpp index 7af96948..8e645c1b 100644 --- a/src/app/Scene.cpp +++ b/src/app/Scene.cpp @@ -47,7 +47,7 @@ void Scene::step() { } // Request latest version from server - if (!devMode && checkVersion && !checkedVersion) { + if (!settings.devMode && checkVersion && !checkedVersion) { std::thread t(&Scene::runCheckVersion, this); t.detach(); checkedVersion = true; diff --git a/src/asset.cpp b/src/asset.cpp index e9084a94..b4da6494 100644 --- a/src/asset.cpp +++ b/src/asset.cpp @@ -1,5 +1,6 @@ #include "asset.hpp" #include "system.hpp" +#include "settings.hpp" #include "plugin/Plugin.hpp" #if defined ARCH_MAC @@ -24,10 +25,10 @@ namespace rack { namespace asset { -void init(bool devMode) { +void init() { // Get system dir if (systemDir.empty()) { - if (devMode) { + if (settings.devMode) { systemDir = "."; } else { @@ -57,7 +58,7 @@ void init(bool devMode) { // Get user dir if (userDir.empty()) { - if (devMode) { + if (settings.devMode) { userDir = "."; } else { diff --git a/src/logger.cpp b/src/logger.cpp index bb14d055..e8921800 100644 --- a/src/logger.cpp +++ b/src/logger.cpp @@ -1,5 +1,6 @@ #include "common.hpp" #include "asset.hpp" +#include "settings.hpp" #include #include @@ -13,9 +14,9 @@ static std::chrono::high_resolution_clock::time_point startTime; static std::mutex logMutex; -void init(bool devMode) { +void init() { startTime = std::chrono::high_resolution_clock::now(); - if (devMode) { + if (settings.devMode) { outputFile = stderr; } else { diff --git a/src/main.cpp b/src/main.cpp index a31fd699..74549115 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -56,8 +56,6 @@ int main(int argc, char *argv[]) { (void) instanceMutex; #endif - bool devMode = false; - bool headless = false; std::string patchPath; // Parse command line arguments @@ -66,10 +64,10 @@ int main(int argc, char *argv[]) { while ((c = getopt(argc, argv, "ds:u:")) != -1) { switch (c) { case 'd': { - devMode = true; + settings.devMode = true; } break; case 'h': { - headless = true; + settings.headless = true; } break; case 's': { asset::systemDir = optarg; @@ -85,13 +83,13 @@ int main(int argc, char *argv[]) { } // Initialize environment - asset::init(devMode); - logger::init(devMode); + asset::init(); + logger::init(); // We can now install a signal handler and log the output // Mac has its own decent crash handler #if 0 - if (!devMode) { + if (!settings.devMode) { signal(SIGABRT, fatalSignalHandler); signal(SIGFPE, fatalSignalHandler); signal(SIGILL, fatalSignalHandler); @@ -102,7 +100,7 @@ int main(int argc, char *argv[]) { // Log environment INFO("%s v%s", app::APP_NAME, app::APP_VERSION); - if (devMode) + if (settings.devMode) INFO("Development mode"); INFO("System directory: %s", asset::systemDir.c_str()); INFO("User directory: %s", asset::userDir.c_str()); @@ -115,7 +113,7 @@ int main(int argc, char *argv[]) { keyboard::init(); gamepad::init(); plugin::init(); - if (!headless) { + if (!settings.headless) { ui::init(); windowInit(); } @@ -123,22 +121,21 @@ int main(int argc, char *argv[]) { // Initialize app INFO("Initializing app"); settings.load(asset::user("settings.json")); - appInit(headless); + appInit(); const char *openedFilename = glfwGetOpenedFilename(); if (openedFilename) { patchPath = openedFilename; } - if (!headless) { - APP->scene->devMode = devMode; + if (!settings.headless) { APP->patch->init(patchPath); } INFO("Starting engine"); APP->engine->start(); - if (!headless) { + if (!settings.headless) { INFO("Running window"); APP->window->run(); INFO("Stopped window"); @@ -151,7 +148,7 @@ int main(int argc, char *argv[]) { APP->engine->stop(); // Destroy app - if (!headless) { + if (!settings.headless) { APP->patch->save(asset::user("autosave.vcv")); } INFO("Destroying app"); @@ -160,7 +157,7 @@ int main(int argc, char *argv[]) { // Destroy environment INFO("Destroying environment"); - if (!headless) { + if (!settings.headless) { windowDestroy(); ui::destroy(); } diff --git a/src/plugin.cpp b/src/plugin.cpp index 57eec4fd..d8bc5b03 100644 --- a/src/plugin.cpp +++ b/src/plugin.cpp @@ -356,20 +356,20 @@ void init() { plugins.push_back(corePlugin); // Get user plugins directory - std::string userPlugins = asset::user("plugins"); - mkdir(userPlugins.c_str(), 0755); + std::string pluginsDir = asset::user("plugins"); + mkdir(pluginsDir.c_str(), 0755); - // Copy Fundamental package to plugins directory if folder does not exist + // Extract packages and load plugins + extractPackages(pluginsDir); + loadPlugins(pluginsDir); + + // Copy Fundamental package to plugins directory if Fundamental is not loaded std::string fundamentalSrc = asset::system("Fundamental.zip"); - std::string fundamentalDest = asset::user("plugins/Fundamental.zip"); std::string fundamentalDir = asset::user("plugins/Fundamental"); - if (system::isFile(fundamentalSrc) && !system::isFile(fundamentalDest) && !system::isDirectory(fundamentalDir)) { - system::copyFile(fundamentalSrc, fundamentalDest); + if (!settings.devMode && !getPlugin("Fundamental") && system::isFile(fundamentalSrc)) { + extractZip(fundamentalSrc.c_str(), pluginsDir.c_str()); + loadPlugin(fundamentalDir); } - - // Extract packages and load plugins - extractPackages(userPlugins); - loadPlugins(userPlugins); } void destroy() { diff --git a/src/settings.cpp b/src/settings.cpp index f4e437ae..3447a4ad 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -172,11 +172,11 @@ void Settings::fromJson(json_t *rootJ) { } } -void Settings::save(std::string filename) { - INFO("Saving settings %s", filename.c_str()); +void Settings::save(const std::string &path) { + INFO("Saving settings %s", path.c_str()); json_t *rootJ = toJson(); if (rootJ) { - FILE *file = std::fopen(filename.c_str(), "w"); + FILE *file = std::fopen(path.c_str(), "w"); if (!file) return; @@ -186,9 +186,9 @@ void Settings::save(std::string filename) { } } -void Settings::load(std::string filename) { - INFO("Loading settings %s", filename.c_str()); - FILE *file = std::fopen(filename.c_str(), "r"); +void Settings::load(const std::string &path) { + INFO("Loading settings %s", path.c_str()); + FILE *file = std::fopen(path.c_str(), "r"); if (!file) return;