From da713fddaa28dd5dc6c9e9a46e62e39ddd8e2102 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sat, 10 Nov 2018 19:08:49 +0000 Subject: [PATCH] fixed memory leaks, better handling when switching scene collections( big cause of duplicate usernames and webhook urls), option to remove all settings on next restart --- Config.cpp | 25 +++++-- Config.h | 148 +++++++++++++++++++++++---------------- forms/SettingsDialog.cpp | 28 +++++++- forms/SettingsDialog.h | 2 +- forms/SettingsDialog.ui | 21 ++++-- obs-util.h | 1 - sc2switcher.cpp | 2 + 7 files changed, 154 insertions(+), 73 deletions(-) diff --git a/Config.cpp b/Config.cpp index 78bb6d4..fe98a46 100644 --- a/Config.cpp +++ b/Config.cpp @@ -16,14 +16,31 @@ Config::Config() : isRunning(false), switcherEnabled(false), scoresEnabled(false), - popupsEnabled(true) {} + popupsEnabled(true), + webhookEnabled(false), + clearSettings(false) {} Config* Config::Current() { - return _instance; + return _instance; } Config::~Config() { - delete _instance; + //delete _instance; + obs_weak_source_release(inGameScene); + obs_weak_source_release(outGameScene); + obs_weak_source_release(replayScene); + obs_weak_source_release(obsScene); + obs_weak_source_release(menuScenes[MENU_SCORESCREEN]); + obs_weak_source_release(menuScenes[MENU_PROFILE]); + obs_weak_source_release(menuScenes[MENU_LOBBY]); + obs_weak_source_release(menuScenes[MENU_HOME]); + obs_weak_source_release(menuScenes[MENU_CAMPAIGN]); + obs_weak_source_release(menuScenes[MENU_COLLECTION]); + obs_weak_source_release(menuScenes[MENU_COOP]); + obs_weak_source_release(menuScenes[MENU_CUSTOM]); + obs_weak_source_release(menuScenes[MENU_REPLAYS]); + obs_weak_source_release(menuScenes[MENU_VERSUS]); + } void Config::checkForUpdates() { @@ -61,7 +78,7 @@ void Config::checkForUpdates() { json_t* url = json_object_get(root, "tag_name"); const char *urlText = json_string_value(url); float latestVer = stof(urlText); - float currentVer = 0.94; + float currentVer = 0.95; if(latestVer > currentVer) { json_t* url2 = json_object_get(root, "html_url"); const char *urlText2 = json_string_value(url2); diff --git a/Config.h b/Config.h index 97d4dac..87b6fef 100644 --- a/Config.h +++ b/Config.h @@ -42,80 +42,86 @@ class Config { bool switcherEnabled; bool scoresEnabled; bool popupsEnabled; - bool webhookEnabled; vector webhookURLList; + bool clearSettings; + private: static Config* _instance; }; static void LoadSaveHandler(obs_data_t *save_data, bool saving, void *) { - Config* cfg = Config::Current(); - if (saving) { - obs_data_t *obj = obs_data_create(); - - // settings - obs_data_set_bool(obj, "is_running", cfg->isRunning); - obs_data_set_bool(obj, "switcher_enabled", cfg->switcherEnabled); - obs_data_set_bool(obj, "scores_enabled", cfg->scoresEnabled); - obs_data_set_bool(obj, "popups_enabled", cfg->popupsEnabled); - obs_data_set_string(obj, "ip_addr", cfg->ipAddr.c_str()); - obs_data_set_bool(obj, "webhook_enabled", cfg->webhookEnabled); - - obs_data_array_t *array = obs_data_array_create(); - for (string &s : cfg->webhookURLList) { - obs_data_t *array_obj = obs_data_create(); - obs_data_set_string(array_obj, "URL", s.c_str()); - obs_data_array_push_back(array, array_obj); - obs_data_release(array_obj); - } - obs_data_set_array(obj, "webhookURLs", array); - obs_data_array_release(array); - - obs_data_array_t *array2 = obs_data_array_create(); - for (string &s : cfg->usernames) { - obs_data_t *array_obj = obs_data_create(); - obs_data_set_string(array_obj, "username", s.c_str()); - obs_data_array_push_back(array2, array_obj); - obs_data_release(array_obj); + Config* cfg = Config::Current(); + if(!cfg->clearSettings) { + obs_data_t *obj = obs_data_create(); + + // settings + obs_data_set_bool(obj, "is_running", cfg->isRunning); + obs_data_set_bool(obj, "switcher_enabled", cfg->switcherEnabled); + obs_data_set_bool(obj, "scores_enabled", cfg->scoresEnabled); + obs_data_set_bool(obj, "popups_enabled", cfg->popupsEnabled); + obs_data_set_string(obj, "ip_addr", cfg->ipAddr.c_str()); + obs_data_set_bool(obj, "webhook_enabled", cfg->webhookEnabled); + + obs_data_array_t *array = obs_data_array_create(); + for (string &s : cfg->webhookURLList) { + obs_data_t *array_obj = obs_data_create(); + obs_data_set_string(array_obj, "URL", s.c_str()); + obs_data_array_push_back(array, array_obj); + obs_data_release(array_obj); + } + obs_data_set_array(obj, "webhookURLs", array); + obs_data_array_release(array); + + obs_data_array_t *array2 = obs_data_array_create(); + for (string &s : cfg->usernames) { + obs_data_t *array_obj = obs_data_create(); + obs_data_set_string(array_obj, "username", s.c_str()); + obs_data_array_push_back(array2, array_obj); + obs_data_release(array_obj); + } + obs_data_set_array(obj, "usernames", array2); + obs_data_array_release(array2); + + obs_data_set_string(obj, "textSourceName", cfg->textSourceName.c_str()); + obs_data_set_string(obj, "scoreString", cfg->scoreString.c_str()); + + // scenes + obs_data_set_string(obj, "in_game_scene", GetWeakSourceName(cfg->inGameScene).c_str()); + obs_data_set_string(obj, "out_game_scene", GetWeakSourceName(cfg->outGameScene).c_str()); + obs_data_set_string(obj, "replay_scene", GetWeakSourceName(cfg->replayScene).c_str()); + obs_data_set_string(obj, "obs_scene", GetWeakSourceName(cfg->obsScene).c_str()); + obs_data_set_string(obj, "MENU_SCORESCREEN", GetWeakSourceName(cfg->menuScenes[MENU_SCORESCREEN]).c_str()); + obs_data_set_string(obj, "MENU_PROFILE", GetWeakSourceName(cfg->menuScenes[MENU_PROFILE]).c_str()); + obs_data_set_string(obj, "MENU_LOBBY", GetWeakSourceName(cfg->menuScenes[MENU_LOBBY]).c_str()); + obs_data_set_string(obj, "MENU_HOME", GetWeakSourceName(cfg->menuScenes[MENU_HOME]).c_str()); + obs_data_set_string(obj, "MENU_CAMPAIGN", GetWeakSourceName(cfg->menuScenes[MENU_CAMPAIGN]).c_str()); + obs_data_set_string(obj, "MENU_COLLECTION", GetWeakSourceName(cfg->menuScenes[MENU_COLLECTION]).c_str()); + obs_data_set_string(obj, "MENU_COOP", GetWeakSourceName(cfg->menuScenes[MENU_COOP]).c_str()); + obs_data_set_string(obj, "MENU_CUSTOM", GetWeakSourceName(cfg->menuScenes[MENU_CUSTOM]).c_str()); + obs_data_set_string(obj, "MENU_REPLAYS", GetWeakSourceName(cfg->menuScenes[MENU_REPLAYS]).c_str()); + obs_data_set_string(obj, "MENU_VERSUS", GetWeakSourceName(cfg->menuScenes[MENU_VERSUS]).c_str()); + + obs_data_set_obj(save_data, "sc2switcher2", obj); + obs_data_release(obj); } - obs_data_set_array(obj, "usernames", array2); - obs_data_array_release(array2); - - obs_data_set_string(obj, "textSourceName", cfg->textSourceName.c_str()); - obs_data_set_string(obj, "scoreString", cfg->scoreString.c_str()); - - // scenes - obs_data_set_string(obj, "in_game_scene", GetWeakSourceName(cfg->inGameScene).c_str()); - obs_data_set_string(obj, "out_game_scene", GetWeakSourceName(cfg->outGameScene).c_str()); - obs_data_set_string(obj, "replay_scene", GetWeakSourceName(cfg->replayScene).c_str()); - obs_data_set_string(obj, "obs_scene", GetWeakSourceName(cfg->obsScene).c_str()); - obs_data_set_string(obj, "MENU_SCORESCREEN", GetWeakSourceName(cfg->menuScenes[MENU_SCORESCREEN]).c_str()); - obs_data_set_string(obj, "MENU_PROFILE", GetWeakSourceName(cfg->menuScenes[MENU_PROFILE]).c_str()); - obs_data_set_string(obj, "MENU_LOBBY", GetWeakSourceName(cfg->menuScenes[MENU_LOBBY]).c_str()); - obs_data_set_string(obj, "MENU_HOME", GetWeakSourceName(cfg->menuScenes[MENU_HOME]).c_str()); - obs_data_set_string(obj, "MENU_CAMPAIGN", GetWeakSourceName(cfg->menuScenes[MENU_CAMPAIGN]).c_str()); - obs_data_set_string(obj, "MENU_COLLECTION", GetWeakSourceName(cfg->menuScenes[MENU_COLLECTION]).c_str()); - obs_data_set_string(obj, "MENU_COOP", GetWeakSourceName(cfg->menuScenes[MENU_COOP]).c_str()); - obs_data_set_string(obj, "MENU_CUSTOM", GetWeakSourceName(cfg->menuScenes[MENU_CUSTOM]).c_str()); - obs_data_set_string(obj, "MENU_REPLAYS", GetWeakSourceName(cfg->menuScenes[MENU_REPLAYS]).c_str()); - obs_data_set_string(obj, "MENU_VERSUS", GetWeakSourceName(cfg->menuScenes[MENU_VERSUS]).c_str()); - - - obs_data_set_obj(save_data, "sc2switcher2", obj); - obs_data_release(obj); } - else { + else { + Config* cfg = Config::Current(); + obs_data_t *obj = obs_data_get_obj(save_data, "sc2switcher2"); if (!obj) { obj = obs_data_create(); } + cfg->ipAddr = obs_data_get_string(obj, "ip_addr"); - + + vector emptyusernames; + cfg->usernames = emptyusernames; obs_data_array_t *array = obs_data_get_array(obj, "usernames"); size_t count = obs_data_array_count(array); vector seen; @@ -129,11 +135,17 @@ static void LoadSaveHandler(obs_data_t *save_data, bool saving, void *) { } obs_data_array_release(array); + vector emptywebhookURLList; + cfg->webhookURLList = emptywebhookURLList; obs_data_array_t *array2 = obs_data_get_array(obj, "webhookURLs"); size_t count2 = obs_data_array_count(array2); + vector seen2; for (size_t i = 0; i < count2; i++) { obs_data_t *array_obj = obs_data_array_item(array2, i); - cfg->webhookURLList.push_back(obs_data_get_string(array_obj, "URL")); + std::string url = obs_data_get_string(array_obj, "URL"); + if (std::find(seen2.begin(), seen2.end(), url) == seen2.end() && url != "") { + cfg->webhookURLList.push_back(url); + } obs_data_release(array_obj); } obs_data_array_release(array2); @@ -150,6 +162,24 @@ static void LoadSaveHandler(obs_data_t *save_data, bool saving, void *) { cfg->switcherEnabled = obs_data_get_bool(obj, "switcher_enabled"); cfg->scoresEnabled = obs_data_get_bool(obj, "scores_enabled"); cfg->popupsEnabled = obs_data_get_bool(obj, "popups_enabled"); + cfg->webhookEnabled = obs_data_get_bool(obj, "webhook_enabled"); + + + obs_weak_source_release(cfg->inGameScene); + obs_weak_source_release(cfg->outGameScene); + obs_weak_source_release(cfg->replayScene); + obs_weak_source_release(cfg->obsScene); + obs_weak_source_release(cfg->menuScenes[MENU_SCORESCREEN]); + obs_weak_source_release(cfg->menuScenes[MENU_PROFILE]); + obs_weak_source_release(cfg->menuScenes[MENU_LOBBY]); + obs_weak_source_release(cfg->menuScenes[MENU_HOME]); + obs_weak_source_release(cfg->menuScenes[MENU_CAMPAIGN]); + obs_weak_source_release(cfg->menuScenes[MENU_COLLECTION]); + obs_weak_source_release(cfg->menuScenes[MENU_COOP]); + obs_weak_source_release(cfg->menuScenes[MENU_CUSTOM]); + obs_weak_source_release(cfg->menuScenes[MENU_REPLAYS]); + obs_weak_source_release(cfg->menuScenes[MENU_VERSUS]); + cfg->inGameScene = GetWeakSourceByName(obs_data_get_string(obj, "in_game_scene")); cfg->outGameScene = GetWeakSourceByName(obs_data_get_string(obj, "out_game_scene")); @@ -165,10 +195,8 @@ static void LoadSaveHandler(obs_data_t *save_data, bool saving, void *) { cfg->menuScenes[MENU_CUSTOM] = GetWeakSourceByName(obs_data_get_string(obj, "MENU_CUSTOM")); cfg->menuScenes[MENU_REPLAYS] = GetWeakSourceByName(obs_data_get_string(obj, "MENU_REPLAYS")); cfg->menuScenes[MENU_VERSUS] = GetWeakSourceByName(obs_data_get_string(obj, "MENU_VERSUS")); - - cfg->webhookEnabled = obs_data_get_bool(obj, "webhook_enabled"); + obs_data_release(obj); - } } diff --git a/forms/SettingsDialog.cpp b/forms/SettingsDialog.cpp index 3ee5b6f..b04c12f 100644 --- a/forms/SettingsDialog.cpp +++ b/forms/SettingsDialog.cpp @@ -108,12 +108,27 @@ SettingsDialog::SettingsDialog(QWidget* parent) : if(config->switcherEnabled) { ui->switcherEnabled->setChecked(true); } + else { + ui->switcherEnabled->setChecked(false); + } if(config->scoresEnabled) { ui->scoresEnabled->setChecked(true); } + else { + ui->scoresEnabled->setChecked(false); + } if(config->popupsEnabled) { ui->popupsEnabled->setChecked(true); } + else { + ui->popupsEnabled->setChecked(false); + } + if(config->clearSettings) { + ui->clearSettings->setChecked(true); + } + else { + ui->clearSettings->setChecked(false); + } if(config->webhookEnabled) { ui->webhookEnabled->setChecked(true); @@ -135,7 +150,7 @@ SettingsDialog::~SettingsDialog() { } void SettingsDialog::closeEvent(QCloseEvent*) { - obs_frontend_save(); + //obs_frontend_save(); } @@ -143,7 +158,7 @@ void SettingsDialog::on_inGameScene_currentTextChanged(const QString& text) { if(!isLoading) { obs_source_t* scene = obs_get_source_by_name(text.toUtf8().constData()); obs_weak_source_t* ws = obs_source_get_weak_source(scene); - + config->inGameScene = ws; obs_weak_source_release(ws); @@ -418,6 +433,15 @@ void SettingsDialog::on_scoresEnabled_stateChanged(int state) { } } +void SettingsDialog::on_clearSettings_stateChanged(int state) { + if(state == Qt::Checked) { + config->clearSettings = true; + } + else { + config->clearSettings = false; + } +} + void SettingsDialog::on_popupsEnabled_stateChanged(int state) { if(state == Qt::Checked) { config->popupsEnabled = true; diff --git a/forms/SettingsDialog.h b/forms/SettingsDialog.h index 6ec3f82..67239b9 100644 --- a/forms/SettingsDialog.h +++ b/forms/SettingsDialog.h @@ -39,8 +39,8 @@ class SettingsDialog : public QDialog void on_switcherEnabled_stateChanged(int state); void on_scoresEnabled_stateChanged(int state); void on_popupsEnabled_stateChanged(int state); - void on_webhookEnabled_stateChanged(int state); + void on_clearSettings_stateChanged(int state); void on_tWinPlus_clicked(); void on_tWinMinus_clicked(); diff --git a/forms/SettingsDialog.ui b/forms/SettingsDialog.ui index fc4e1f3..d3af421 100755 --- a/forms/SettingsDialog.ui +++ b/forms/SettingsDialog.ui @@ -40,11 +40,22 @@ - - - - - + + + + + + + + + + + + Clear Settings On Next Restart + + + + diff --git a/obs-util.h b/obs-util.h index c343674..5065162 100644 --- a/obs-util.h +++ b/obs-util.h @@ -9,7 +9,6 @@ static inline OBSWeakSource GetWeakSourceByName(const char *name) obs_source_t *source = obs_get_source_by_name(name); if (source) { weak = obs_source_get_weak_source(source); - obs_weak_source_release(weak); obs_source_release(source); } diff --git a/sc2switcher.cpp b/sc2switcher.cpp index af7cee7..4dfb6da 100755 --- a/sc2switcher.cpp +++ b/sc2switcher.cpp @@ -45,4 +45,6 @@ bool obs_module_load(void) { void obs_module_unload(void) { delete sw; delete wh; + Config* cfg = Config::Current(); + cfg->~Config(); }