add switch cooldown option (#97)

* add switch cooldown functionality

* slightly adjust sequence check for cooldown

* add UI implementation for cooldown feature
This commit is contained in:
WarmUpTill
2021-01-07 18:58:35 +01:00
committed by GitHub
parent bf97975fa8
commit 2b90493ae9
8 changed files with 164 additions and 88 deletions

View File

@@ -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()

View File

@@ -83,6 +83,14 @@ void AdvSceneSwitcher::on_noMatchSwitchScene_currentTextChanged(
UpdateNonMatchingScene(text);
}
void AdvSceneSwitcher::on_cooldownTime_valueChanged(double i)
{
if (loading)
return;
std::lock_guard<std::mutex> 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<std::chrono::milliseconds>(
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());

View File

@@ -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);

View File

@@ -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<WindowSwitch> windowSwitches;
std::vector<std::string> 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);

View File

@@ -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;
}