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

@@ -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"

View File

@@ -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"

View File

@@ -152,69 +152,6 @@
<string>AdvSceneSwitcher.generalTab.generalBehavior</string>
</property>
<layout class="QGridLayout" name="gridLayout_5">
<item row="3" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_50">
<item>
<widget class="QCheckBox" name="autoStartSceneCheckBox">
<property name="text">
<string>AdvSceneSwitcher.generalTab.generalBehavior.automaticallyStart1</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="autoStartType">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>100</width>
<height>0</height>
</size>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_65">
<property name="text">
<string>AdvSceneSwitcher.generalTab.generalBehavior.automaticallyStart2</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="autoStartScenes">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>100</width>
<height>0</height>
</size>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_55">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="0" column="0">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="2">
@@ -310,7 +247,7 @@
</item>
</layout>
</item>
<item row="4" column="0">
<item row="6" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_52">
<item>
<widget class="QCheckBox" name="verboseLogging">
@@ -334,7 +271,101 @@
</item>
</layout>
</item>
<item row="2" column="0">
<item row="3" column="0">
<widget class="Line" name="line_6">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="7" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_48">
<item>
<widget class="QCheckBox" name="uiHintsDisable">
<property name="text">
<string>AdvSceneSwitcher.generalTab.generalBehavior.disableUIHints</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_52">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="5" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_50">
<item>
<widget class="QCheckBox" name="autoStartSceneCheckBox">
<property name="text">
<string>AdvSceneSwitcher.generalTab.generalBehavior.automaticallyStart1</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="autoStartType">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>100</width>
<height>0</height>
</size>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_65">
<property name="text">
<string>AdvSceneSwitcher.generalTab.generalBehavior.automaticallyStart2</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="autoStartScenes">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>100</width>
<height>0</height>
</size>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_55">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="4" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_33">
<item>
<widget class="QCheckBox" name="autoStopSceneCheckBox">
@@ -375,23 +406,23 @@
</layout>
</item>
<item row="1" column="0">
<widget class="Line" name="line_6">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="5" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_48">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QCheckBox" name="uiHintsDisable">
<widget class="QLabel" name="label">
<property name="text">
<string>AdvSceneSwitcher.generalTab.generalBehavior.disableUIHints</string>
<string>AdvSceneSwitcher.generalTab.generalBehavior.cooldown</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_52">
<widget class="QDoubleSpinBox" name="cooldownTime">
<property name="suffix">
<string>s</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>

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