mirror of
https://github.com/WarmUpTill/SceneSwitcher.git
synced 2026-03-21 17:34:57 -05:00
Add option to check macro conditions in parallel to other macros
This commit is contained in:
parent
9e20b341d8
commit
ea93c44db7
|
|
@ -199,8 +199,11 @@ AdvSceneSwitcher.macroTab.highlightTrueConditions="Highlight conditions of curre
|
|||
AdvSceneSwitcher.macroTab.highlightPerformedActions="Highlight recently performed actions of currently selected macro"
|
||||
AdvSceneSwitcher.macroTab.newMacroRegisterHotkey="Register hotkeys to control the pause state of new macros"
|
||||
AdvSceneSwitcher.macroTab.newMacroUseShortCircuitEvaluation="Enable short circuit evaluation of macro conditions for new macros"
|
||||
AdvSceneSwitcher.macroTab.saveSettingsOnMacroChange="Save settings when selecting a new macro"
|
||||
AdvSceneSwitcher.macroTab.newMacroCheckInParallel="Evaluate conditions of new macros in parallel to other macros"
|
||||
AdvSceneSwitcher.macroTab.checkInParallel.tooltip="If this option is not enabled, this macro's conditions will be evaluated after the preceeding macro's condition check has completed.\nSo, if there are three macros - Macro A, Macro B, and Macro C - in the macro list the order the conditions in are evaluated is:\n • Macro A's conditions\n • Macro B's conditions\n • Macro C's conditions\nIf this option is enabled, the order might differ.\nEnabling this option can be useful for scenarios in which you have multiple long running condition checks, which you don't want to result in \"blocking\" other macros."
|
||||
AdvSceneSwitcher.macroTab.saveSettingsOnMacroChange="Save settings when switching between macros"
|
||||
AdvSceneSwitcher.macroTab.saveSettingsOnMacroChange.tooltip="Saving the settings can be an expensive operation if you are working with a very large scene collection.\nIn this case, it might make sense to disable this option."
|
||||
AdvSceneSwitcher.macroTab.currentCheckInParallel="Evaluate conditions of selected macro in parallel to other macros"
|
||||
AdvSceneSwitcher.macroTab.currentRegisterHotkeys="Register hotkeys to control the pause state of selected macro"
|
||||
AdvSceneSwitcher.macroTab.currentUseShortCircuitEvaluation="Enable short circuit evaluation of macro conditions for currently selected macro"
|
||||
AdvSceneSwitcher.macroTab.shortCircuit.tooltip="Enabling short circuit evaluation might improve the performance, as some condition checks are skipped, if the overall macro cannot be evaluated to \"true\" anymore.\nHowever, please note that condition checks, which are skipped over, will also not update their duration modifier checks."
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user