From c31b8f0ba2a41a4fc0bb2b871adcf9c0dc2771b8 Mon Sep 17 00:00:00 2001 From: Andrew Belt Date: Mon, 17 Dec 2018 03:27:42 -0500 Subject: [PATCH] Split plugin.hpp to folder of headers, wrap plugin state in new PluginManager class --- include/app/ModuleWidget.hpp | 2 +- include/asset.hpp | 2 +- include/helpers.hpp | 2 +- include/plugin.hpp | 102 ------------ include/plugin/Model.hpp | 41 +++++ include/plugin/Plugin.hpp | 41 +++++ include/plugin/PluginManager.hpp | 46 ++++++ include/plugin/callbacks.hpp | 9 + include/rack.hpp | 5 +- src/app/ModuleBrowser.cpp | 8 +- src/app/PluginManagerWidget.cpp | 24 +-- src/app/RackWidget.cpp | 3 +- src/main.cpp | 8 +- src/plugin/Plugin.cpp | 21 +++ src/{plugin.cpp => plugin/PluginManager.cpp} | 163 +++++++------------ src/settings.cpp | 6 +- 16 files changed, 256 insertions(+), 227 deletions(-) delete mode 100644 include/plugin.hpp create mode 100644 include/plugin/Model.hpp create mode 100644 include/plugin/Plugin.hpp create mode 100644 include/plugin/PluginManager.hpp create mode 100644 include/plugin/callbacks.hpp create mode 100644 src/plugin/Plugin.cpp rename src/{plugin.cpp => plugin/PluginManager.cpp} (84%) diff --git a/include/app/ModuleWidget.hpp b/include/app/ModuleWidget.hpp index da997c27..166ebd93 100644 --- a/include/app/ModuleWidget.hpp +++ b/include/app/ModuleWidget.hpp @@ -5,7 +5,7 @@ #include "app/SVGPanel.hpp" #include "app/Port.hpp" #include "app/ParamWidget.hpp" -#include "plugin.hpp" +#include "plugin/Model.hpp" #include "engine/Module.hpp" diff --git a/include/asset.hpp b/include/asset.hpp index 4e3be2aa..584dc5a3 100644 --- a/include/asset.hpp +++ b/include/asset.hpp @@ -1,6 +1,6 @@ #pragma once #include "common.hpp" -#include "plugin.hpp" +#include "plugin/Plugin.hpp" namespace rack { diff --git a/include/helpers.hpp b/include/helpers.hpp index 59e89cba..afe14e05 100644 --- a/include/helpers.hpp +++ b/include/helpers.hpp @@ -1,4 +1,4 @@ -#include "plugin.hpp" +#include "plugin/Model.hpp" #include "event.hpp" #include "ui/MenuLabel.hpp" #include "ui/MenuItem.hpp" diff --git a/include/plugin.hpp b/include/plugin.hpp deleted file mode 100644 index c359bac6..00000000 --- a/include/plugin.hpp +++ /dev/null @@ -1,102 +0,0 @@ -#pragma once -#include -#include -#include "common.hpp" -#include "tags.hpp" - - -namespace rack { - - -struct ModuleWidget; -struct Module; -struct Model; - - -// Subclass this and return a pointer to a new one when init() is called -struct Plugin { - /** A list of the models available by this plugin, add with addModel() */ - std::list models; - /** The file path of the plugin's directory */ - std::string path; - /** OS-dependent library handle */ - void *handle = NULL; - - /** Must be unique. Used for patch files and the VCV store API. - To guarantee uniqueness, it is a good idea to prefix the slug by your "company name" if available, e.g. "MyCompany-MyPlugin" - */ - std::string slug; - - /** The version of your plugin - Plugins should follow the versioning scheme described at https://github.com/VCVRack/Rack/issues/266 - Do not include the "v" in "v1.0" for example. - */ - std::string version; - - /** Deprecated, do not use. */ - std::string website; - std::string manual; - - virtual ~Plugin(); - void addModel(Model *model); -}; - - -struct Model { - Plugin *plugin = NULL; - /** An identifier for the model, e.g. "VCO". Used for saving patches. - The model slug must be unique in your plugin, but it doesn't need to be unique among different plugins. - */ - std::string slug; - /** Human readable name for your model, e.g. "Voltage Controlled Oscillator" */ - std::string name; - /** The author name of the module. - This might be different than the plugin slug. For example, if you create multiple plugins but want them to be branded similarly, you may use the same author in multiple plugins. - You may even have multiple authors in one plugin, although this property will be moved to Plugin for Rack 1.0. - */ - std::string author; - /** List of tags representing the function(s) of the module (optional) */ - std::list tags; - - virtual ~Model() {} - /** Creates a headless Module */ - virtual Module *createModule() { return NULL; } - /** Creates a ModuleWidget with a Module attached */ - virtual ModuleWidget *createModuleWidget() { return NULL; } - /** Creates a ModuleWidget with no Module, useful for previews */ - virtual ModuleWidget *createModuleWidgetNull() { return NULL; } -}; - - -void pluginInit(bool devMode); -void pluginDestroy(); -void pluginLogIn(std::string email, std::string password); -void pluginLogOut(); -/** Returns whether a new plugin is available, and downloads it unless doing a dry run */ -bool pluginSync(bool dryRun); -void pluginCancelDownload(); -bool pluginIsLoggedIn(); -bool pluginIsDownloading(); -float pluginGetDownloadProgress(); -std::string pluginGetDownloadName(); -std::string pluginGetLoginStatus(); -Plugin *pluginGetPlugin(std::string pluginSlug); -Model *pluginGetModel(std::string pluginSlug, std::string modelSlug); - - -extern std::list gPlugins; -extern std::string gToken; - - -} // namespace rack - - -//////////////////// -// Implemented by plugin -//////////////////// - -/** Called once to initialize and return the Plugin instance. -You must implement this in your plugin -*/ -extern "C" -void init(rack::Plugin *plugin); diff --git a/include/plugin/Model.hpp b/include/plugin/Model.hpp new file mode 100644 index 00000000..433571c2 --- /dev/null +++ b/include/plugin/Model.hpp @@ -0,0 +1,41 @@ +#pragma once +#include "common.hpp" +#include "plugin/Plugin.hpp" +#include "tags.hpp" +#include + + +namespace rack { + + +struct ModuleWidget; +struct Module; + + +struct Model { + Plugin *plugin = NULL; + /** An identifier for the model, e.g. "VCO". Used for saving patches. + The model slug must be unique in your plugin, but it doesn't need to be unique among different plugins. + */ + std::string slug; + /** Human readable name for your model, e.g. "Voltage Controlled Oscillator" */ + std::string name; + /** The author name of the module. + This might be different than the plugin slug. For example, if you create multiple plugins but want them to be branded similarly, you may use the same author in multiple plugins. + You may even have multiple authors in one plugin, although this property will be moved to Plugin for Rack 1.0. + */ + std::string author; + /** List of tags representing the function(s) of the module (optional) */ + std::list tags; + + virtual ~Model() {} + /** Creates a headless Module */ + virtual Module *createModule() { return NULL; } + /** Creates a ModuleWidget with a Module attached */ + virtual ModuleWidget *createModuleWidget() { return NULL; } + /** Creates a ModuleWidget with no Module, useful for previews */ + virtual ModuleWidget *createModuleWidgetNull() { return NULL; } +}; + + +} // namespace rack diff --git a/include/plugin/Plugin.hpp b/include/plugin/Plugin.hpp new file mode 100644 index 00000000..c14565c7 --- /dev/null +++ b/include/plugin/Plugin.hpp @@ -0,0 +1,41 @@ +#pragma once +#include "common.hpp" +#include + + +namespace rack { + + +struct Model; + + +// Subclass this and return a pointer to a new one when init() is called +struct Plugin { + /** A list of the models available by this plugin, add with addModel() */ + std::list models; + /** The file path of the plugin's directory */ + std::string path; + /** OS-dependent library handle */ + void *handle = NULL; + + /** Must be unique. Used for patch files and the VCV store API. + To guarantee uniqueness, it is a good idea to prefix the slug by your "company name" if available, e.g. "MyCompany-MyPlugin" + */ + std::string slug; + + /** The version of your plugin + Plugins should follow the versioning scheme described at https://github.com/VCVRack/Rack/issues/266 + Do not include the "v" in "v1.0" for example. + */ + std::string version; + + /** Deprecated, do not use. */ + std::string website; + std::string manual; + + virtual ~Plugin(); + void addModel(Model *model); +}; + + +} // namespace rack diff --git a/include/plugin/PluginManager.hpp b/include/plugin/PluginManager.hpp new file mode 100644 index 00000000..51fe50f8 --- /dev/null +++ b/include/plugin/PluginManager.hpp @@ -0,0 +1,46 @@ +#pragma once +#include "common.hpp" +#include "plugin/Plugin.hpp" +#include "plugin/Model.hpp" +#include + + +namespace rack { + + +struct PluginManager { + std::list plugins; + std::string token; + + bool isDownloading = false; + float downloadProgress = 0.f; + std::string downloadName; + std::string loginStatus; + + PluginManager(bool devMode); + ~PluginManager(); + void logIn(std::string email, std::string password); + void logOut(); + /** Returns whether a new plugin is available, and downloads it unless doing a dry run */ + bool sync(bool dryRun); + void cancelDownload(); + bool isLoggedIn(); + Plugin *getPlugin(std::string pluginSlug); + Model *getModel(std::string pluginSlug, std::string modelSlug); +}; + +extern PluginManager *gPluginManager; + + +} // namespace rack + + +//////////////////// +// Implemented by plugin +//////////////////// + +/** Called once to initialize and return the Plugin instance. +You must implement this in your plugin +*/ +extern "C" +void init(rack::Plugin *plugin); diff --git a/include/plugin/callbacks.hpp b/include/plugin/callbacks.hpp new file mode 100644 index 00000000..4f53d75a --- /dev/null +++ b/include/plugin/callbacks.hpp @@ -0,0 +1,9 @@ +#pragma once +#include "plugin/Plugin.hpp" + + +/** Called once to initialize and return the Plugin instance. +You must implement this in your plugin +*/ +extern "C" +void init(rack::Plugin *plugin); diff --git a/include/rack.hpp b/include/rack.hpp index 192a9ff0..ea647342 100644 --- a/include/rack.hpp +++ b/include/rack.hpp @@ -8,7 +8,6 @@ #include "random.hpp" #include "network.hpp" #include "asset.hpp" -#include "plugin.hpp" #include "window.hpp" #include "helpers.hpp" @@ -77,3 +76,7 @@ #include "engine/Output.hpp" #include "engine/Param.hpp" #include "engine/Wire.hpp" + +#include "plugin/Plugin.hpp" +#include "plugin/Model.hpp" +#include "plugin/callbacks.hpp" diff --git a/src/app/ModuleBrowser.cpp b/src/app/ModuleBrowser.cpp index 65b50e35..016be763 100644 --- a/src/app/ModuleBrowser.cpp +++ b/src/app/ModuleBrowser.cpp @@ -1,6 +1,5 @@ #include #include -#include "plugin.hpp" #include "window.hpp" #include "helpers.hpp" #include "event.hpp" @@ -11,6 +10,7 @@ #include "app/Scene.hpp" #include "ui/List.hpp" #include "ui/TextField.hpp" +#include "plugin/PluginManager.hpp" static const float itemMargin = 2.0; @@ -322,7 +322,7 @@ struct ModuleBrowser : OpaqueWidget { addChild(moduleScroll); // Collect authors - for (Plugin *plugin : gPlugins) { + for (Plugin *plugin : gPluginManager->plugins) { for (Model *model : plugin->models) { // Insert author if (!model->author.empty()) @@ -427,7 +427,7 @@ struct ModuleBrowser : OpaqueWidget { moduleList->addChild(item); } // Modules - for (Plugin *plugin : gPlugins) { + for (Plugin *plugin : gPluginManager->plugins) { for (Model *model : plugin->models) { if (isModelFiltered(model) && isModelMatch(model, search)) { ModelItem *item = new ModelItem; @@ -587,7 +587,7 @@ void moduleBrowserFromJson(json_t *rootJ) { continue; std::string pluginSlug = json_string_value(pluginJ); std::string modelSlug = json_string_value(modelJ); - Model *model = pluginGetModel(pluginSlug, modelSlug); + Model *model = gPluginManager->getModel(pluginSlug, modelSlug); if (!model) continue; sFavoriteModels.insert(model); diff --git a/src/app/PluginManagerWidget.cpp b/src/app/PluginManagerWidget.cpp index 6e97bf6a..6cf68139 100644 --- a/src/app/PluginManagerWidget.cpp +++ b/src/app/PluginManagerWidget.cpp @@ -7,7 +7,7 @@ #include "ui/TextField.hpp" #include "ui/PasswordField.hpp" #include "ui/Label.hpp" -#include "plugin.hpp" +#include "plugin/PluginManager.hpp" #include "window.hpp" #include "helpers.hpp" #include "osdialog.h" @@ -30,7 +30,9 @@ struct LogInButton : Button { TextField *emailField; TextField *passwordField; void onAction(event::Action &e) override { - std::thread t(pluginLogIn, emailField->text, passwordField->text); + std::thread t([&]() { + gPluginManager->logIn(emailField->text, passwordField->text); + }); t.detach(); passwordField->text = ""; } @@ -39,7 +41,7 @@ struct LogInButton : Button { struct StatusLabel : Label { void step() override { - text = pluginGetLoginStatus(); + text = gPluginManager->loginStatus; } }; @@ -65,7 +67,7 @@ struct SyncButton : Button { // Check for plugin update on first step() if (!checked) { std::thread t([this]() { - if (pluginSync(true)) + if (gPluginManager->sync(true)) available = true; }); t.detach(); @@ -94,7 +96,7 @@ struct SyncButton : Button { void onAction(event::Action &e) override { available = false; std::thread t([this]() { - if (pluginSync(false)) + if (gPluginManager->sync(false)) completed = true; }); t.detach(); @@ -104,14 +106,14 @@ struct SyncButton : Button { struct LogOutButton : Button { void onAction(event::Action &e) override { - pluginLogOut(); + gPluginManager->logOut(); } }; struct DownloadQuantity : Quantity { float getValue() override { - return pluginGetDownloadProgress(); + return gPluginManager->downloadProgress; } float getDisplayValue() override { @@ -121,7 +123,7 @@ struct DownloadQuantity : Quantity { int getDisplayPrecision() override {return 0;} std::string getLabel() override { - return "Downloading " + pluginGetDownloadName(); + return "Downloading " + gPluginManager->downloadName; } std::string getUnit() override {return "%";} @@ -137,7 +139,7 @@ struct DownloadProgressBar : ProgressBar { struct CancelButton : Button { void onAction(event::Action &e) override { - pluginCancelDownload(); + gPluginManager->cancelDownload(); } }; @@ -224,9 +226,9 @@ void PluginManagerWidget::step() { manageWidget->visible = false; downloadWidget->visible = false; - if (pluginIsDownloading()) + if (gPluginManager->isDownloading) downloadWidget->visible = true; - else if (pluginIsLoggedIn()) + else if (gPluginManager->isLoggedIn()) manageWidget->visible = true; else loginWidget->visible = true; diff --git a/src/app/RackWidget.cpp b/src/app/RackWidget.cpp index 27b776e1..5b51d673 100644 --- a/src/app/RackWidget.cpp +++ b/src/app/RackWidget.cpp @@ -9,6 +9,7 @@ #include "asset.hpp" #include "system.hpp" #include "logger.hpp" +#include "plugin/PluginManager.hpp" namespace rack { @@ -377,7 +378,7 @@ ModuleWidget *RackWidget::moduleFromJson(json_t *moduleJ) { std::string modelSlug = json_string_value(modelSlugJ); // Get Model - Model *model = pluginGetModel(pluginSlug, modelSlug); + Model *model = gPluginManager->getModel(pluginSlug, modelSlug); if (!model) return NULL; diff --git a/src/main.cpp b/src/main.cpp index 608abb34..d35d98d1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -10,6 +10,8 @@ #include "settings.hpp" #include "engine/Engine.hpp" #include "app/Scene.hpp" +#include "tags.hpp" +#include "plugin/PluginManager.hpp" #ifdef ARCH_WIN #include @@ -67,7 +69,8 @@ int main(int argc, char *argv[]) { INFO("Local directory: %s", asset::local("").c_str()); // Initialize app - pluginInit(devMode); + tagsInit(); + gPluginManager = new PluginManager(devMode); gEngine = new Engine; rtmidiInit(); bridgeInit(); @@ -118,7 +121,8 @@ int main(int argc, char *argv[]) { delete gEngine; gEngine = NULL; midiDestroy(); - pluginDestroy(); + delete gPluginManager; + gPluginManager = NULL; logger::destroy(); return 0; diff --git a/src/plugin/Plugin.cpp b/src/plugin/Plugin.cpp new file mode 100644 index 00000000..2cea2ed4 --- /dev/null +++ b/src/plugin/Plugin.cpp @@ -0,0 +1,21 @@ +#include "plugin/Plugin.hpp" +#include "plugin/Model.hpp" + + +namespace rack { + + +Plugin::~Plugin() { + for (Model *model : models) { + delete model; + } +} + +void Plugin::addModel(Model *model) { + assert(!model->plugin); + model->plugin = this; + models.push_back(model); +} + + +} // namespace rack diff --git a/src/plugin.cpp b/src/plugin/PluginManager.cpp similarity index 84% rename from src/plugin.cpp rename to src/plugin/PluginManager.cpp index 923a051f..0da5527d 100644 --- a/src/plugin.cpp +++ b/src/plugin/PluginManager.cpp @@ -19,7 +19,7 @@ #endif #include -#include "plugin.hpp" +#include "plugin/PluginManager.hpp" #include "system.hpp" #include "logger.hpp" #include "network.hpp" @@ -32,33 +32,11 @@ namespace rack { -std::list gPlugins; -std::string gToken; - - -static bool isDownloading = false; -static float downloadProgress = 0.0; -static std::string downloadName; -static std::string loginStatus; - - -Plugin::~Plugin() { - for (Model *model : models) { - delete model; - } -} - -void Plugin::addModel(Model *model) { - assert(!model->plugin); - model->plugin = this; - models.push_back(model); -} - //////////////////// // private API //////////////////// -static bool loadPlugin(std::string path) { +static bool PluginManager_loadPlugin(PluginManager *pluginManager, std::string path) { std::string libraryFilename; #if ARCH_LIN libraryFilename = path + "/" + "plugin.so"; @@ -112,7 +90,7 @@ static bool loadPlugin(std::string path) { initCallback(plugin); // Reject plugin if slug already exists - Plugin *oldPlugin = pluginGetPlugin(plugin->slug); + Plugin *oldPlugin = pluginManager->getPlugin(plugin->slug); if (oldPlugin) { WARN("Plugin \"%s\" is already loaded, not attempting to load it again", plugin->slug.c_str()); // TODO @@ -121,13 +99,13 @@ static bool loadPlugin(std::string path) { } // Add plugin to list - gPlugins.push_back(plugin); + pluginManager->plugins.push_back(plugin); INFO("Loaded plugin %s %s from %s", plugin->slug.c_str(), plugin->version.c_str(), libraryFilename.c_str()); return true; } -static bool syncPlugin(std::string slug, json_t *manifestJ, bool dryRun) { +static bool PluginManager_syncPlugin(PluginManager *pluginManager, std::string slug, json_t *manifestJ, bool dryRun) { // Check that "status" is "available" json_t *statusJ = json_object_get(manifestJ, "status"); if (!statusJ) { @@ -147,7 +125,7 @@ static bool syncPlugin(std::string slug, json_t *manifestJ, bool dryRun) { std::string latestVersion = json_string_value(latestVersionJ); // Check whether we already have a plugin with the same slug and version - Plugin *plugin = pluginGetPlugin(slug); + Plugin *plugin = pluginManager->getPlugin(slug); if (plugin && plugin->version == latestVersion) { return false; } @@ -175,7 +153,7 @@ static bool syncPlugin(std::string slug, json_t *manifestJ, bool dryRun) { if (dryRun) { downloadUrl += "/available"; } - downloadUrl += "?token=" + network::encodeUrl(gToken); + downloadUrl += "?token=" + network::encodeUrl(pluginManager->token); downloadUrl += "&slug=" + network::encodeUrl(slug); downloadUrl += "&version=" + network::encodeUrl(latestVersion); downloadUrl += "&arch=" + network::encodeUrl(arch); @@ -194,28 +172,28 @@ static bool syncPlugin(std::string slug, json_t *manifestJ, bool dryRun) { return json_boolean_value(successJ); } else { - downloadName = name; - downloadProgress = 0.0; + pluginManager->downloadName = name; + pluginManager->downloadProgress = 0.0; INFO("Downloading plugin %s %s %s", slug.c_str(), latestVersion.c_str(), arch.c_str()); // Download zip std::string pluginDest = asset::local("plugins/" + slug + ".zip"); - if (!network::requestDownload(downloadUrl, pluginDest, &downloadProgress)) { + if (!network::requestDownload(downloadUrl, pluginDest, &pluginManager->downloadProgress)) { WARN("Plugin %s download was unsuccessful", slug.c_str()); return false; } - downloadName = ""; + pluginManager->downloadName = ""; return true; } } -static void loadPlugins(std::string path) { +static void PluginManager_loadPlugins(PluginManager *pluginManager, std::string path) { std::string message; for (std::string pluginPath : system::listEntries(path)) { if (!system::isDirectory(pluginPath)) continue; - if (!loadPlugin(pluginPath)) { + if (!PluginManager_loadPlugin(pluginManager, pluginPath)) { message += string::f("Could not load plugin %s\n", pluginPath.c_str()); } } @@ -321,14 +299,12 @@ static void extractPackages(std::string path) { // public API //////////////////// -void pluginInit(bool devMode) { - tagsInit(); - +PluginManager::PluginManager(bool devMode) { // Load core // This function is defined in core.cpp Plugin *corePlugin = new Plugin; init(corePlugin); - gPlugins.push_back(corePlugin); + plugins.push_back(corePlugin); // Get local plugins directory std::string localPlugins = asset::local("plugins"); @@ -346,15 +322,15 @@ void pluginInit(bool devMode) { // Extract packages and load plugins extractPackages(localPlugins); - loadPlugins(localPlugins); + PluginManager_loadPlugins(this, localPlugins); } -void pluginDestroy() { - for (Plugin *plugin : gPlugins) { +PluginManager::~PluginManager() { + for (Plugin *plugin : plugins) { // Free library handle #if ARCH_WIN if (plugin->handle) - FreeLibrary((HINSTANCE)plugin->handle); + FreeLibrary((HINSTANCE) plugin->handle); #else if (plugin->handle) dlclose(plugin->handle); @@ -364,11 +340,40 @@ void pluginDestroy() { // It might be best to let them leak anyway, because "crash on exit" issues would occur with badly-written plugins. // delete plugin; } - gPlugins.clear(); + plugins.clear(); +} + +void PluginManager::logIn(std::string email, std::string password) { + json_t *reqJ = json_object(); + json_object_set(reqJ, "email", json_string(email.c_str())); + json_object_set(reqJ, "password", json_string(password.c_str())); + json_t *resJ = network::requestJson(network::METHOD_POST, API_HOST + "/token", reqJ); + json_decref(reqJ); + + if (resJ) { + json_t *errorJ = json_object_get(resJ, "error"); + if (errorJ) { + const char *errorStr = json_string_value(errorJ); + loginStatus = errorStr; + } + else { + json_t *tokenJ = json_object_get(resJ, "token"); + if (tokenJ) { + const char *tokenStr = json_string_value(tokenJ); + token = tokenStr; + loginStatus = ""; + } + } + json_decref(resJ); + } +} + +void PluginManager::logOut() { + token = ""; } -bool pluginSync(bool dryRun) { - if (gToken.empty()) +bool PluginManager::sync(bool dryRun) { + if (token.empty()) return false; bool available = false; @@ -384,7 +389,7 @@ bool pluginSync(bool dryRun) { // Get user's plugins list json_t *pluginsReqJ = json_object(); - json_object_set(pluginsReqJ, "token", json_string(gToken.c_str())); + json_object_set(pluginsReqJ, "token", json_string(token.c_str())); json_t *pluginsResJ = network::requestJson(network::METHOD_GET, API_HOST + "/plugins", pluginsReqJ); json_decref(pluginsReqJ); if (!pluginsResJ) { @@ -438,7 +443,7 @@ bool pluginSync(bool dryRun) { if (!manifestJ) continue; - if (syncPlugin(slug, manifestJ, dryRun)) { + if (PluginManager_syncPlugin(this, slug, manifestJ, dryRun)) { available = true; } } @@ -446,61 +451,16 @@ bool pluginSync(bool dryRun) { return available; } -void pluginLogIn(std::string email, std::string password) { - json_t *reqJ = json_object(); - json_object_set(reqJ, "email", json_string(email.c_str())); - json_object_set(reqJ, "password", json_string(password.c_str())); - json_t *resJ = network::requestJson(network::METHOD_POST, API_HOST + "/token", reqJ); - json_decref(reqJ); - - if (resJ) { - json_t *errorJ = json_object_get(resJ, "error"); - if (errorJ) { - const char *errorStr = json_string_value(errorJ); - loginStatus = errorStr; - } - else { - json_t *tokenJ = json_object_get(resJ, "token"); - if (tokenJ) { - const char *tokenStr = json_string_value(tokenJ); - gToken = tokenStr; - loginStatus = ""; - } - } - json_decref(resJ); - } -} - -void pluginLogOut() { - gToken = ""; -} - -void pluginCancelDownload() { +void PluginManager::cancelDownload() { // TODO } -bool pluginIsLoggedIn() { - return gToken != ""; -} - -bool pluginIsDownloading() { - return isDownloading; +bool PluginManager::isLoggedIn() { + return token != ""; } -float pluginGetDownloadProgress() { - return downloadProgress; -} - -std::string pluginGetDownloadName() { - return downloadName; -} - -std::string pluginGetLoginStatus() { - return loginStatus; -} - -Plugin *pluginGetPlugin(std::string pluginSlug) { - for (Plugin *plugin : gPlugins) { +Plugin *PluginManager::getPlugin(std::string pluginSlug) { + for (Plugin *plugin : plugins) { if (plugin->slug == pluginSlug) { return plugin; } @@ -508,8 +468,8 @@ Plugin *pluginGetPlugin(std::string pluginSlug) { return NULL; } -Model *pluginGetModel(std::string pluginSlug, std::string modelSlug) { - Plugin *plugin = pluginGetPlugin(pluginSlug); +Model *PluginManager::getModel(std::string pluginSlug, std::string modelSlug) { + Plugin *plugin = getPlugin(pluginSlug); if (plugin) { for (Model *model : plugin->models) { if (model->slug == modelSlug) { @@ -521,4 +481,7 @@ Model *pluginGetModel(std::string pluginSlug, std::string modelSlug) { } +PluginManager *gPluginManager = NULL; + + } // namespace rack diff --git a/src/settings.cpp b/src/settings.cpp index 43b7ceb5..ac26b57b 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -1,7 +1,7 @@ #include "settings.hpp" #include "logger.hpp" #include "window.hpp" -#include "plugin.hpp" +#include "plugin/PluginManager.hpp" #include "app/Scene.hpp" #include "app/ModuleBrowser.hpp" #include "engine/Engine.hpp" @@ -20,7 +20,7 @@ static json_t *settingsToJson() { json_t *rootJ = json_object(); // token - json_t *tokenJ = json_string(gToken.c_str()); + json_t *tokenJ = json_string(gPluginManager->token.c_str()); json_object_set_new(rootJ, "token", tokenJ); if (!windowIsMaximized()) { @@ -83,7 +83,7 @@ static void settingsFromJson(json_t *rootJ) { // token json_t *tokenJ = json_object_get(rootJ, "token"); if (tokenJ) - gToken = json_string_value(tokenJ); + gPluginManager->token = json_string_value(tokenJ); // windowSize json_t *windowSizeJ = json_object_get(rootJ, "windowSize");