mirror of
https://github.com/WarmUpTill/SceneSwitcher.git
synced 2026-08-20 00:05:41 -05:00
Add option to check macro conditions in parallel to other macros
This commit is contained in:
@@ -19,6 +19,8 @@ void GlobalMacroSettings::Save(obs_data_t *obj) const
|
||||
obs_data_set_bool(data, "highlightExecuted", _highlightExecuted);
|
||||
obs_data_set_bool(data, "highlightConditions", _highlightConditions);
|
||||
obs_data_set_bool(data, "highlightActions", _highlightActions);
|
||||
obs_data_set_bool(data, "newMacroCheckInParallel",
|
||||
_newMacroCheckInParallel);
|
||||
obs_data_set_bool(data, "newMacroRegisterHotkey",
|
||||
_newMacroRegisterHotkeys);
|
||||
obs_data_set_bool(data, "newMacroUseShortCircuitEvaluation",
|
||||
@@ -41,6 +43,8 @@ void GlobalMacroSettings::Load(obs_data_t *obj)
|
||||
_highlightExecuted = obs_data_get_bool(data, "highlightExecuted");
|
||||
_highlightConditions = obs_data_get_bool(data, "highlightConditions");
|
||||
_highlightActions = obs_data_get_bool(data, "highlightActions");
|
||||
_newMacroCheckInParallel =
|
||||
obs_data_get_bool(data, "newMacroCheckInParallel");
|
||||
_newMacroRegisterHotkeys =
|
||||
obs_data_get_bool(data, "newMacroRegisterHotkey");
|
||||
_newMacroUseShortCircuitEvaluation =
|
||||
@@ -62,12 +66,16 @@ MacroSettingsDialog::MacroSettingsDialog(QWidget *parent,
|
||||
"AdvSceneSwitcher.macroTab.highlightTrueConditions"))),
|
||||
_highlightActions(new QCheckBox(obs_module_text(
|
||||
"AdvSceneSwitcher.macroTab.highlightPerformedActions"))),
|
||||
_newMacroCheckInParallel(new QCheckBox(obs_module_text(
|
||||
"AdvSceneSwitcher.macroTab.newMacroCheckInParallel"))),
|
||||
_newMacroRegisterHotkeys(new QCheckBox(obs_module_text(
|
||||
"AdvSceneSwitcher.macroTab.newMacroRegisterHotkey"))),
|
||||
_newMacroUseShortCircuitEvaluation(new QCheckBox(obs_module_text(
|
||||
"AdvSceneSwitcher.macroTab.newMacroUseShortCircuitEvaluation"))),
|
||||
_saveSettingsOnMacroChange(new QCheckBox(obs_module_text(
|
||||
"AdvSceneSwitcher.macroTab.saveSettingsOnMacroChange"))),
|
||||
_currentCheckInParallel(new QCheckBox(obs_module_text(
|
||||
"AdvSceneSwitcher.macroTab.currentCheckInParallel"))),
|
||||
_currentMacroRegisterHotkeys(new QCheckBox(obs_module_text(
|
||||
"AdvSceneSwitcher.macroTab.currentRegisterHotkeys"))),
|
||||
_currentUseShortCircuitEvaluation(new QCheckBox(obs_module_text(
|
||||
@@ -107,6 +115,11 @@ MacroSettingsDialog::MacroSettingsDialog(QWidget *parent,
|
||||
setWindowModality(Qt::WindowModality::WindowModal);
|
||||
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
||||
|
||||
_newMacroCheckInParallel->setToolTip(obs_module_text(
|
||||
"AdvSceneSwitcher.macroTab.checkInParallel.tooltip"));
|
||||
_currentCheckInParallel->setToolTip(obs_module_text(
|
||||
"AdvSceneSwitcher.macroTab.checkInParallel.tooltip"));
|
||||
|
||||
_newMacroUseShortCircuitEvaluation->setToolTip(obs_module_text(
|
||||
"AdvSceneSwitcher.macroTab.shortCircuit.tooltip"));
|
||||
_saveSettingsOnMacroChange->setToolTip(obs_module_text(
|
||||
@@ -146,6 +159,8 @@ MacroSettingsDialog::MacroSettingsDialog(QWidget *parent,
|
||||
obs_module_text("AdvSceneSwitcher.macroTab.generalSettings"));
|
||||
auto generalLayout = new QVBoxLayout;
|
||||
generalLayout->addWidget(_saveSettingsOnMacroChange);
|
||||
generalLayout->addWidget(_currentCheckInParallel);
|
||||
generalLayout->addWidget(_newMacroCheckInParallel);
|
||||
generalLayout->addWidget(_currentSkipOnStartup);
|
||||
generalLayout->addWidget(_currentStopActionsIfNotDone);
|
||||
generalLayout->addWidget(_currentUseShortCircuitEvaluation);
|
||||
@@ -273,6 +288,7 @@ MacroSettingsDialog::MacroSettingsDialog(QWidget *parent,
|
||||
_highlightExecutedMacros->setChecked(settings._highlightExecuted);
|
||||
_highlightConditions->setChecked(settings._highlightConditions);
|
||||
_highlightActions->setChecked(settings._highlightActions);
|
||||
_newMacroCheckInParallel->setChecked(settings._newMacroCheckInParallel);
|
||||
_newMacroRegisterHotkeys->setChecked(settings._newMacroRegisterHotkeys);
|
||||
_newMacroUseShortCircuitEvaluation->setChecked(
|
||||
settings._newMacroUseShortCircuitEvaluation);
|
||||
@@ -280,20 +296,23 @@ MacroSettingsDialog::MacroSettingsDialog(QWidget *parent,
|
||||
settings._saveSettingsOnMacroChange);
|
||||
|
||||
if (!macro || macro->IsGroup()) {
|
||||
hotkeyOptions->hide();
|
||||
|
||||
// General group
|
||||
_currentSkipOnStartup->hide();
|
||||
_currentStopActionsIfNotDone->hide();
|
||||
_currentUseShortCircuitEvaluation->hide();
|
||||
_currentCheckInParallel->hide();
|
||||
SetLayoutVisible(customConditionIntervalLayout, false);
|
||||
SetLayoutVisible(pauseStateSaveBehavorLayout, false);
|
||||
|
||||
// Hotkey group
|
||||
_currentMacroRegisterHotkeys->hide();
|
||||
|
||||
inputOptions->hide();
|
||||
_dockOptions->hide();
|
||||
return;
|
||||
}
|
||||
|
||||
_currentCheckInParallel->setChecked(macro->CheckInParallel());
|
||||
_currentMacroRegisterHotkeys->setChecked(macro->PauseHotkeysEnabled());
|
||||
_currentUseShortCircuitEvaluation->setChecked(
|
||||
macro->ShortCircuitEvaluationEnabled());
|
||||
@@ -431,6 +450,8 @@ bool MacroSettingsDialog::AskForSettings(QWidget *parent,
|
||||
userInput._highlightConditions =
|
||||
dialog._highlightConditions->isChecked();
|
||||
userInput._highlightActions = dialog._highlightActions->isChecked();
|
||||
userInput._newMacroCheckInParallel =
|
||||
dialog._newMacroCheckInParallel->isChecked();
|
||||
userInput._newMacroRegisterHotkeys =
|
||||
dialog._newMacroRegisterHotkeys->isChecked();
|
||||
userInput._newMacroUseShortCircuitEvaluation =
|
||||
@@ -441,6 +462,7 @@ bool MacroSettingsDialog::AskForSettings(QWidget *parent,
|
||||
return true;
|
||||
}
|
||||
|
||||
macro->SetCheckInParallel(dialog._currentCheckInParallel->isChecked());
|
||||
macro->EnablePauseHotkeys(
|
||||
dialog._currentMacroRegisterHotkeys->isChecked());
|
||||
macro->SetShortCircuitEvaluation(
|
||||
|
||||
@@ -23,6 +23,7 @@ public:
|
||||
bool _highlightExecuted = false;
|
||||
bool _highlightConditions = false;
|
||||
bool _highlightActions = false;
|
||||
bool _newMacroCheckInParallel = false;
|
||||
bool _newMacroRegisterHotkeys = true;
|
||||
bool _newMacroUseShortCircuitEvaluation = false;
|
||||
bool _saveSettingsOnMacroChange = true;
|
||||
@@ -52,10 +53,12 @@ private:
|
||||
QCheckBox *_highlightExecutedMacros;
|
||||
QCheckBox *_highlightConditions;
|
||||
QCheckBox *_highlightActions;
|
||||
QCheckBox *_newMacroCheckInParallel;
|
||||
QCheckBox *_newMacroRegisterHotkeys;
|
||||
QCheckBox *_newMacroUseShortCircuitEvaluation;
|
||||
QCheckBox *_saveSettingsOnMacroChange;
|
||||
// Current macro specific settings
|
||||
QCheckBox *_currentCheckInParallel;
|
||||
QCheckBox *_currentMacroRegisterHotkeys;
|
||||
QCheckBox *_currentUseShortCircuitEvaluation;
|
||||
QCheckBox *_currentUseCustomConditionCheckInterval;
|
||||
|
||||
@@ -252,19 +252,52 @@ bool Macro::CheckConditions(bool ignorePause)
|
||||
return false;
|
||||
}
|
||||
|
||||
_stop = false;
|
||||
_matched = false;
|
||||
for (auto &condition : _conditions) {
|
||||
if (!condition) {
|
||||
continue;
|
||||
}
|
||||
const auto checkConditionsTask =
|
||||
[this,
|
||||
ignorePause](const std::deque<std::shared_ptr<MacroCondition>>
|
||||
&conditions) {
|
||||
for (auto &condition : conditions) {
|
||||
if (!condition) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (_paused && !ignorePause) {
|
||||
vblog(LOG_INFO, "Macro %s is paused", _name.c_str());
|
||||
if (_paused && !ignorePause) {
|
||||
vblog(LOG_INFO, "Macro %s is paused",
|
||||
_name.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
_matched = CheckConditionHelper(condition);
|
||||
}
|
||||
return _matched;
|
||||
};
|
||||
|
||||
if (CheckInParallel()) {
|
||||
if (!_conditionCheckFuture.valid()) {
|
||||
_stop = false;
|
||||
_matched = false;
|
||||
_conditionCheckFuture = std::async(
|
||||
std::launch::async,
|
||||
[this, checkConditionsTask]() {
|
||||
// Copy to avoid settings modifications
|
||||
// causing issues
|
||||
const auto conditionsCopy = _conditions;
|
||||
checkConditionsTask(conditionsCopy);
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
_matched = CheckConditionHelper(condition);
|
||||
if (_conditionCheckFuture.wait_for(std::chrono::seconds(0)) !=
|
||||
std::future_status::ready) {
|
||||
vblog(LOG_INFO,
|
||||
"Macro %s still waiting for condition check result",
|
||||
_name.c_str());
|
||||
return false;
|
||||
}
|
||||
_conditionCheckFuture.get();
|
||||
} else {
|
||||
_stop = false;
|
||||
_matched = false;
|
||||
_matched = checkConditionsTask(_conditions);
|
||||
}
|
||||
|
||||
vblog(LOG_INFO, "Macro %s returned %d", _name.c_str(), _matched);
|
||||
@@ -344,6 +377,13 @@ bool Macro::ConditionsShouldBeChecked() const
|
||||
|
||||
bool Macro::ShouldRunActions() const
|
||||
{
|
||||
if (CheckInParallel() && _conditionCheckFuture.valid()) {
|
||||
vblog(LOG_INFO,
|
||||
"%s not ready to perform actions as condition check is still running",
|
||||
_name.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
const bool hasActionsToExecute =
|
||||
!_paused && (_matched || _elseActions.size() > 0) &&
|
||||
(!_performActionsOnChange || _conditionSateChanged);
|
||||
@@ -519,6 +559,29 @@ void Macro::Stop()
|
||||
if (_backgroundThread.joinable()) {
|
||||
_backgroundThread.join();
|
||||
}
|
||||
if (_conditionCheckFuture.valid()) {
|
||||
_conditionCheckFuture.get();
|
||||
}
|
||||
}
|
||||
|
||||
void Macro::SetCheckInParallel(bool parallel)
|
||||
{
|
||||
_checkInParallel = parallel;
|
||||
_conditionCheckFuture = {};
|
||||
}
|
||||
|
||||
bool Macro::ParallelTasksCompleted() const
|
||||
{
|
||||
if (!CheckInParallel() && !RunInParallel()) {
|
||||
return true;
|
||||
}
|
||||
if (RunInParallel() && !_done) {
|
||||
return false;
|
||||
}
|
||||
if (CheckInParallel() && _conditionCheckFuture.valid()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
MacroInputVariables Macro::GetInputVariables() const
|
||||
@@ -720,6 +783,7 @@ bool Macro::Save(obs_data_t *obj, bool saveForCopy) const
|
||||
static_cast<int>(_pauseSaveBehavior));
|
||||
obs_data_set_bool(obj, "pause", _paused);
|
||||
obs_data_set_bool(obj, "parallel", _runInParallel);
|
||||
obs_data_set_bool(obj, "checkConditionsInParallel", _checkInParallel);
|
||||
obs_data_set_bool(obj, "onChange", _performActionsOnChange);
|
||||
obs_data_set_bool(obj, "skipExecOnStart", _skipExecOnStart);
|
||||
obs_data_set_bool(obj, "stopActionsIfNotDone", _stopActionsIfNotDone);
|
||||
@@ -805,6 +869,7 @@ bool Macro::Load(obs_data_t *obj)
|
||||
break;
|
||||
}
|
||||
_runInParallel = obs_data_get_bool(obj, "parallel");
|
||||
_checkInParallel = obs_data_get_bool(obj, "checkConditionsInParallel");
|
||||
_performActionsOnChange = obs_data_get_bool(obj, "onChange");
|
||||
_skipExecOnStart = obs_data_get_bool(obj, "skipExecOnStart");
|
||||
_stopActionsIfNotDone = obs_data_get_bool(obj, "stopActionsIfNotDone");
|
||||
@@ -1476,6 +1541,14 @@ std::weak_ptr<Macro> GetWeakMacroByName(const char *name)
|
||||
void InvalidateMacroTempVarValues()
|
||||
{
|
||||
for (const auto &m : macros) {
|
||||
// Do not invalidate the temp vars set during condition checks
|
||||
// or action executions running in parallel to the "main" macro
|
||||
// loop, as otherwise access to the information stored in those
|
||||
// variables might get lost while those checks or actions are
|
||||
// still ongoing.
|
||||
if (!m->ParallelTasksCompleted()) {
|
||||
continue;
|
||||
}
|
||||
m->InvalidateTempVarValues();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "variable-string.hpp"
|
||||
#include "temp-variable.hpp"
|
||||
|
||||
#include <future>
|
||||
#include <QString>
|
||||
#include <QByteArray>
|
||||
#include <string>
|
||||
@@ -78,6 +79,9 @@ public:
|
||||
void AddHelperThread(std::thread &&);
|
||||
void SetRunInParallel(bool parallel) { _runInParallel = parallel; }
|
||||
bool RunInParallel() const { return _runInParallel; }
|
||||
bool CheckInParallel() const { return _checkInParallel; }
|
||||
void SetCheckInParallel(bool parallel);
|
||||
bool ParallelTasksCompleted() const;
|
||||
|
||||
// Input variables
|
||||
MacroInputVariables GetInputVariables() const;
|
||||
@@ -205,7 +209,9 @@ private:
|
||||
bool _conditionSateChanged = false;
|
||||
|
||||
bool _runInParallel = false;
|
||||
bool _checkInParallel = false;
|
||||
bool _matched = false;
|
||||
std::future<void> _conditionCheckFuture;
|
||||
bool _lastMatched = false;
|
||||
bool _performActionsOnChange = true;
|
||||
bool _skipExecOnStart = false;
|
||||
|
||||
Reference in New Issue
Block a user