From 2b90493ae9c1cc99227b84f68b2d20c4a376a9b7 Mon Sep 17 00:00:00 2001 From: WarmUpTill Date: Thu, 7 Jan 2021 18:58:35 +0100 Subject: [PATCH] add switch cooldown option (#97) * add switch cooldown functionality * slightly adjust sequence check for cooldown * add UI implementation for cooldown feature --- data/locale/de-DE.ini | 2 + data/locale/en-US.ini | 2 + forms/advanced-scene-switcher.ui | 183 ++++++++++++++---------- src/advanced-scene-switcher.cpp | 2 + src/general.cpp | 36 +++++ src/headers/advanced-scene-switcher.hpp | 1 + src/headers/switcher-data-structs.hpp | 4 + src/switch-sequence.cpp | 22 ++- 8 files changed, 164 insertions(+), 88 deletions(-) diff --git a/data/locale/de-DE.ini b/data/locale/de-DE.ini index ce34a921..f945907a 100644 --- a/data/locale/de-DE.ini +++ b/data/locale/de-DE.ini @@ -24,6 +24,8 @@ AdvSceneSwitcher.generalTab.generalBehavior.onNoMetDelayTooltip="Kann nur so gen AdvSceneSwitcher.generalTab.generalBehavior.onNoMet.dontSwitch="Nicht wechseln" AdvSceneSwitcher.generalTab.generalBehavior.onNoMet.switchToRandom="Wechsle zu einer Szene auf dem Zufall-Tab" AdvSceneSwitcher.generalTab.generalBehavior.onNoMet.switchTo="Wechsle zu:" +AdvSceneSwitcher.generalTab.generalBehavior.cooldown="Nach einem automatisierten Szenenwechsel wechsle nicht mehr für" +AdvSceneSwitcher.generalTab.generalBehavior.cooldownHint="In diesem Zeitraum werden potentielle erfüllte Bedingungen ignoriert!" AdvSceneSwitcher.generalTab.generalBehavior.verboseLogging="Ausführliches Logging" AdvSceneSwitcher.generalTab.generalBehavior.automaticallyStop="Stoppe Streamen/Aufnehmen auf Szene" AdvSceneSwitcher.generalTab.generalBehavior.disableUIHints="Deaktiviere UI Tipps" diff --git a/data/locale/en-US.ini b/data/locale/en-US.ini index 43de9467..3c4cd5a2 100644 --- a/data/locale/en-US.ini +++ b/data/locale/en-US.ini @@ -24,6 +24,8 @@ AdvSceneSwitcher.generalTab.generalBehavior.onNoMetDelayTooltip="Will only ever AdvSceneSwitcher.generalTab.generalBehavior.onNoMet.dontSwitch="Don't switch" AdvSceneSwitcher.generalTab.generalBehavior.onNoMet.switchToRandom="Switch to any scene in Random tab" AdvSceneSwitcher.generalTab.generalBehavior.onNoMet.switchTo="Switch to:" +AdvSceneSwitcher.generalTab.generalBehavior.cooldown="After a match do not switch scenes for" +AdvSceneSwitcher.generalTab.generalBehavior.cooldownHint="During this time potential matches will be ignored!" AdvSceneSwitcher.generalTab.generalBehavior.verboseLogging="Enable verbose logging" AdvSceneSwitcher.generalTab.generalBehavior.automaticallyStop="Automatically stop streaming/recording on scene" AdvSceneSwitcher.generalTab.generalBehavior.disableUIHints="Disable UI hints" diff --git a/forms/advanced-scene-switcher.ui b/forms/advanced-scene-switcher.ui index dab2b61e..420c4714 100644 --- a/forms/advanced-scene-switcher.ui +++ b/forms/advanced-scene-switcher.ui @@ -152,69 +152,6 @@ AdvSceneSwitcher.generalTab.generalBehavior - - - - - - AdvSceneSwitcher.generalTab.generalBehavior.automaticallyStart1 - - - - - - - - 0 - 0 - - - - - 100 - 0 - - - - - - - - AdvSceneSwitcher.generalTab.generalBehavior.automaticallyStart2 - - - - - - - - 0 - 0 - - - - - 100 - 0 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - @@ -310,7 +247,7 @@ - + @@ -334,7 +271,101 @@ - + + + + Qt::Horizontal + + + + + + + + + AdvSceneSwitcher.generalTab.generalBehavior.disableUIHints + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + AdvSceneSwitcher.generalTab.generalBehavior.automaticallyStart1 + + + + + + + + 0 + 0 + + + + + 100 + 0 + + + + + + + + AdvSceneSwitcher.generalTab.generalBehavior.automaticallyStart2 + + + + + + + + 0 + 0 + + + + + 100 + 0 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + @@ -375,23 +406,23 @@ - - - Qt::Horizontal - - - - - + - + - AdvSceneSwitcher.generalTab.generalBehavior.disableUIHints + AdvSceneSwitcher.generalTab.generalBehavior.cooldown - + + + s + + + + + Qt::Horizontal diff --git a/src/advanced-scene-switcher.cpp b/src/advanced-scene-switcher.cpp index e6bcd6ed..dcc5afca 100644 --- a/src/advanced-scene-switcher.cpp +++ b/src/advanced-scene-switcher.cpp @@ -481,6 +481,8 @@ void SwitcherData::Thread() checkNoMatchSwitch(match, scene, transition, sleep); + checkSwitchCooldown(match); + // After this point we will call frontend functions // obs_frontend_set_current_scene() and // obs_frontend_set_current_transition() diff --git a/src/general.cpp b/src/general.cpp index 9de405a9..a9bbb5ad 100644 --- a/src/general.cpp +++ b/src/general.cpp @@ -83,6 +83,14 @@ void AdvSceneSwitcher::on_noMatchSwitchScene_currentTextChanged( UpdateNonMatchingScene(text); } +void AdvSceneSwitcher::on_cooldownTime_valueChanged(double i) +{ + if (loading) + return; + std::lock_guard lock(switcher->m); + switcher->cooldown = i; +} + void AdvSceneSwitcher::on_checkInterval_valueChanged(int value) { if (loading) @@ -471,6 +479,8 @@ void SwitcherData::saveGeneralSettings(obs_data_t *obj) switcher->switchIfNotMatching); obs_data_set_double(obj, "noMatchDelay", switcher->noMatchDelay); + obs_data_set_double(obj, "cooldown", switcher->cooldown); + obs_data_set_bool(obj, "active", !switcher->stop); obs_data_set_int(obj, "startup_behavior", switcher->startupBehavior); @@ -548,6 +558,8 @@ void SwitcherData::loadGeneralSettings(obs_data_t *obj) GetWeakSourceByName(nonMatchingScene.c_str()); switcher->noMatchDelay = obs_data_get_double(obj, "noMatchDelay"); + switcher->cooldown = obs_data_get_double(obj, "cooldown"); + switcher->stop = !obs_data_get_bool(obj, "active"); switcher->startupBehavior = (StartupBehavior)obs_data_get_int(obj, "startup_behavior"); @@ -680,6 +692,26 @@ void SwitcherData::checkNoMatchSwitch(bool &match, OBSWeakSource &scene, } } +void SwitcherData::checkSwitchCooldown(bool &match) +{ + if (!match || cooldown == 0.) { + return; + } + + auto now = std::chrono::high_resolution_clock::now(); + auto timePassed = std::chrono::duration_cast( + now - lastMatchTime); + + if (timePassed.count() > cooldown * 1000) { + lastMatchTime = now; + return; + } + + match = false; + if (verbose) + blog(LOG_INFO, "cooldown active - ignoring match"); +} + void AdvSceneSwitcher::setupGeneralTab() { populateSceneSelection(ui->noMatchSwitchScene, false); @@ -703,6 +735,10 @@ void AdvSceneSwitcher::setupGeneralTab() "AdvSceneSwitcher.generalTab.generalBehavior.onNoMetDelayTooltip")); ui->checkInterval->setValue(switcher->interval); + ui->cooldownTime->setValue(switcher->cooldown); + ui->cooldownTime->setToolTip(obs_module_text( + "AdvSceneSwitcher.generalTab.generalBehavior.cooldownHint")); + ui->autoStopSceneCheckBox->setChecked(switcher->autoStopEnable); ui->autoStopScenes->setCurrentText( GetWeakSourceName(switcher->autoStopScene).c_str()); diff --git a/src/headers/advanced-scene-switcher.hpp b/src/headers/advanced-scene-switcher.hpp index ad913a8e..e0a4be8c 100644 --- a/src/headers/advanced-scene-switcher.hpp +++ b/src/headers/advanced-scene-switcher.hpp @@ -88,6 +88,7 @@ public slots: void on_noMatchSwitch_clicked(); void on_noMatchRandomSwitch_clicked(); void on_noMatchDelay_valueChanged(double i); + void on_cooldownTime_valueChanged(double i); void on_startupBehavior_currentIndexChanged(int index); void on_noMatchSwitchScene_currentTextChanged(const QString &text); void on_checkInterval_valueChanged(int value); diff --git a/src/headers/switcher-data-structs.hpp b/src/headers/switcher-data-structs.hpp index 8841bbc4..6ea4c538 100644 --- a/src/headers/switcher-data-structs.hpp +++ b/src/headers/switcher-data-structs.hpp @@ -68,6 +68,9 @@ struct SwitcherData { double noMatchCount = 0; StartupBehavior startupBehavior = PERSIST; + double cooldown = 0.; + std::chrono::high_resolution_clock::time_point lastMatchTime; + std::deque windowSwitches; std::vector ignoreIdleWindows; std::string lastTitle; @@ -187,6 +190,7 @@ struct SwitcherData { OBSWeakSource &transition); void checkNoMatchSwitch(bool &match, OBSWeakSource &scene, OBSWeakSource &transition, int &sleep); + void checkSwitchCooldown(bool &match); void saveWindowTitleSwitches(obs_data_t *obj); void saveScreenRegionSwitches(obs_data_t *obj); diff --git a/src/switch-sequence.cpp b/src/switch-sequence.cpp index daa67a2e..eb1a1079 100644 --- a/src/switch-sequence.cpp +++ b/src/switch-sequence.cpp @@ -167,7 +167,6 @@ void matchInterruptible(SwitcherData *switcher, SceneSequenceSwitch &s, scene = (s.usePreviousScene) ? switcher->previousScene : s.scene; transition = s.transition; - s.matchCount = 0; if (switcher->verbose) s.logMatch(); } @@ -221,18 +220,17 @@ void SwitcherData::checkSceneSequence(bool &match, OBSWeakSource &scene, continue; if (s.startScene == ws) { - - if (s.interruptible) { - matchInterruptible(switcher, s, match, scene, - transition); - } else { - matchUninterruptible(switcher, s, currentSource, - lock, match, scene, - transition); + if (!match) { + if (s.interruptible) { + matchInterruptible(switcher, s, match, + scene, transition); + } else { + matchUninterruptible(switcher, s, + currentSource, + lock, match, scene, + transition); + } } - - if (match) - break; } else { s.matchCount = 0; }