From be8744f0d0f3b734dd6c713bd284fe1863f05aaa Mon Sep 17 00:00:00 2001 From: WarmUpTill <19472752+WarmUpTill@users.noreply.github.com> Date: Mon, 2 Mar 2026 19:27:42 +0100 Subject: [PATCH] Add action trigger modes * always -> same as old behavior, if "on change" was disabled * results changes -> same as old behavior, if "on change" was enabled * any condition changes * any condition changes and evaluates to true --- data/locale/de-DE.ini | 1 - data/locale/en-US.ini | 7 +++- data/locale/es-ES.ini | 1 - data/locale/fr-FR.ini | 1 - data/locale/ja-JP.ini | 1 - data/locale/pt-BR.ini | 1 - data/locale/tr-TR.ini | 1 - data/locale/zh-CN.ini | 1 - forms/advanced-scene-switcher.ui | 22 ++++------ lib/advanced-scene-switcher.hpp | 2 +- lib/macro/macro-condition.cpp | 11 +++++ lib/macro/macro-condition.hpp | 14 ++++++- lib/macro/macro-tab.cpp | 37 +++++++++++++---- lib/macro/macro-tree.cpp | 3 +- lib/macro/macro.cpp | 71 ++++++++++++++++++++++++-------- lib/macro/macro.hpp | 24 ++++++++--- 16 files changed, 143 insertions(+), 55 deletions(-) diff --git a/data/locale/de-DE.ini b/data/locale/de-DE.ini index f1eb744f..1de1b3ba 100644 --- a/data/locale/de-DE.ini +++ b/data/locale/de-DE.ini @@ -76,7 +76,6 @@ AdvSceneSwitcher.macroTab.name="Name:" AdvSceneSwitcher.macroTab.run="Makro ausführen" AdvSceneSwitcher.macroTab.runFail="Ausführen von \"%1\" fehlgeschlagen!\nEntweder ist eine der Aktionen fehlgeschlagen oder das Makro wird bereits ausgeführt.\nSoll die aktuelle Ausführung gestoppt werden?" AdvSceneSwitcher.macroTab.runInParallel="Parallel zu anderen Makros ausführen" -AdvSceneSwitcher.macroTab.onChange="Nur bei Änderung ausführen" AdvSceneSwitcher.macroTab.defaultname="Makro %1" AdvSceneSwitcher.macroTab.defaultGroupName="Gruppe %1" AdvSceneSwitcher.macroTab.removeGroupPopup.text="Sicher, dass \"%1\" und alle zugehörigen Elemente gelöscht werden?" diff --git a/data/locale/en-US.ini b/data/locale/en-US.ini index 3bf5dc71..f2641368 100644 --- a/data/locale/en-US.ini +++ b/data/locale/en-US.ini @@ -177,7 +177,12 @@ AdvSceneSwitcher.macroTab.run.tooltip="Run all macro actions regardless of condi AdvSceneSwitcher.macroTab.runElse="Run macro (else)" AdvSceneSwitcher.macroTab.runFail="Running \"%1\" failed!\nEither one of the actions failed or the macro is running already.\nDo you want to stop it?" AdvSceneSwitcher.macroTab.runInParallel="Run macro in parallel to other macros" -AdvSceneSwitcher.macroTab.onChange="Perform actions only on condition change" +AdvSceneSwitcher.macroTab.actionTriggerMode.label="Perform actions:" +AdvSceneSwitcher.macroTab.actionTriggerMode.tooltip="Controls when the actions of this macro are performed.\n\n\"Always\" - actions are performed every time the conditions are met.\n\"Macro result changed\" - actions are only performed when the macro transitions between matching and not matching.\n\"Any condition changed\" - actions are only performed when any individual condition changes its result.\n\"Any condition triggered\" - actions are only performed when any individual condition changes from false to true." +AdvSceneSwitcher.macroTab.actionTriggerMode.always="always" +AdvSceneSwitcher.macroTab.actionTriggerMode.onOverallChange="only when result changes" +AdvSceneSwitcher.macroTab.actionTriggerMode.onAnyConditionChange="only when any condition changes" +AdvSceneSwitcher.macroTab.actionTriggerMode.onAnyConditionTriggered="only when any condition becomes true" AdvSceneSwitcher.macroTab.defaultname="Macro %1" AdvSceneSwitcher.macroTab.defaultGroupName="Group %1" AdvSceneSwitcher.macroTab.macroNameExists="The name \"%1\" is already used by a macro." diff --git a/data/locale/es-ES.ini b/data/locale/es-ES.ini index b133eb9e..28b10249 100644 --- a/data/locale/es-ES.ini +++ b/data/locale/es-ES.ini @@ -72,7 +72,6 @@ AdvSceneSwitcher.macroTab.add="Agregar nueva macro" AdvSceneSwitcher.macroTab.name="Nombre:" AdvSceneSwitcher.macroTab.run="Ejecutar macro" AdvSceneSwitcher.macroTab.runInParallel="Ejecutar macro en paralelo a otras macros" -AdvSceneSwitcher.macroTab.onChange="Realizar acciones solo en el cambio de condición" AdvSceneSwitcher.macroTab.defaultname="Macro %1" AdvSceneSwitcher.macroTab.copy="Crear copia" AdvSceneSwitcher.macroTab.expandAll="Expandir todo" diff --git a/data/locale/fr-FR.ini b/data/locale/fr-FR.ini index 8832a067..9e510f89 100644 --- a/data/locale/fr-FR.ini +++ b/data/locale/fr-FR.ini @@ -78,7 +78,6 @@ AdvSceneSwitcher.macroTab.add="Ajouter une nouvelle macro" AdvSceneSwitcher.macroTab.name="Nom :" AdvSceneSwitcher.macroTab.run="Exécuter la macro" AdvSceneSwitcher.macroTab.runInParallel="Exécuter la macro en parallèle avec d'autres macros" -AdvSceneSwitcher.macroTab.onChange="Exécuter des actions uniquement en cas de changement de condition" AdvSceneSwitcher.macroTab.defaultname="Macro %1" AdvSceneSwitcher.macroTab.defaultGroupName="Groupe %1" AdvSceneSwitcher.macroTab.removeSingleMacroPopup.text="Êtes-vous sûr de vouloir supprimer \"%1\" ?" diff --git a/data/locale/ja-JP.ini b/data/locale/ja-JP.ini index c3a0f0a0..baefc74b 100644 --- a/data/locale/ja-JP.ini +++ b/data/locale/ja-JP.ini @@ -164,7 +164,6 @@ AdvSceneSwitcher.macroTab.run.tooltip="条件に関係なくすべてのマク AdvSceneSwitcher.macroTab.runElse="マクロ実行(else)" AdvSceneSwitcher.macroTab.runFail="\"%1\" の実行に失敗しました!\nいずれかのアクションが失敗したか、マクロがすでに実行されています。\n停止しますか?" AdvSceneSwitcher.macroTab.runInParallel="他のマクロと並行してマクロを実行する" -AdvSceneSwitcher.macroTab.onChange="条件変更時のみアクションを実行" AdvSceneSwitcher.macroTab.defaultname="マクロ %1" AdvSceneSwitcher.macroTab.defaultGroupName="グループ %1" AdvSceneSwitcher.macroTab.macroNameExists="名前 \"%1\" は既にマクロで使用されています。" diff --git a/data/locale/pt-BR.ini b/data/locale/pt-BR.ini index 3fb2a40c..1aa09ad8 100644 --- a/data/locale/pt-BR.ini +++ b/data/locale/pt-BR.ini @@ -147,7 +147,6 @@ AdvSceneSwitcher.macroTab.run.tooltip="Execute todas as ações da macro indepen AdvSceneSwitcher.macroTab.runElse="Executar macro (alternativa)" AdvSceneSwitcher.macroTab.runFail="Falha ao executar \"%1\"!\nUma das ações falhou ou a macro já está em execução.\nDeseja interrompê-la?" AdvSceneSwitcher.macroTab.runInParallel="Executar macro em paralelo com outras macros" -AdvSceneSwitcher.macroTab.onChange="Executar ações apenas quando houver mudança na condição" AdvSceneSwitcher.macroTab.defaultname="Macro %1" AdvSceneSwitcher.macroTab.defaultGroupName="Grupo %1" AdvSceneSwitcher.macroTab.macroNameExists="O nome \"%1\" já está em uso por uma macro." diff --git a/data/locale/tr-TR.ini b/data/locale/tr-TR.ini index b048c8e2..9afd72af 100644 --- a/data/locale/tr-TR.ini +++ b/data/locale/tr-TR.ini @@ -72,7 +72,6 @@ AdvSceneSwitcher.macroTab.add="Yeni Makro ekle" AdvSceneSwitcher.macroTab.name="İsim:" AdvSceneSwitcher.macroTab.run="Makro Çalıştırma" AdvSceneSwitcher.macroTab.runInParallel="Makroyu diğer makrolara paralel olarak çalıştırın" -AdvSceneSwitcher.macroTab.onChange="Eylemleri yalnızca koşul değişikliğinde gerçekleştirin" AdvSceneSwitcher.macroTab.defaultname="Makro %1" AdvSceneSwitcher.macroTab.copy="Kopya oluştur" AdvSceneSwitcher.macroTab.expandAll="Hepsini Genişlet" diff --git a/data/locale/zh-CN.ini b/data/locale/zh-CN.ini index 9eedcd08..5f27bf5a 100644 --- a/data/locale/zh-CN.ini +++ b/data/locale/zh-CN.ini @@ -151,7 +151,6 @@ AdvSceneSwitcher.macroTab.run.tooltip="无论条件如何,都运行所有宏 AdvSceneSwitcher.macroTab.runElse="运行宏(不满足条件)" AdvSceneSwitcher.macroTab.runFail="运行 \"%1\" 失败!\n要么其中一个操作失败,要么宏已在运行中.\n你想停止它吗?" AdvSceneSwitcher.macroTab.runInParallel="与其他宏并行运行宏" -AdvSceneSwitcher.macroTab.onChange="仅在条件结果发生变化时执行操作(条件结果不变时只执行一次操作)" AdvSceneSwitcher.macroTab.defaultname="宏 %1" AdvSceneSwitcher.macroTab.defaultGroupName="分组 %1" AdvSceneSwitcher.macroTab.macroNameExists="名称 \"%1\" 已被宏使用." diff --git a/forms/advanced-scene-switcher.ui b/forms/advanced-scene-switcher.ui index f1a92514..082ddd5a 100644 --- a/forms/advanced-scene-switcher.ui +++ b/forms/advanced-scene-switcher.ui @@ -793,25 +793,19 @@ - - - AdvSceneSwitcher.macroTab.onChange - + - + AdvSceneSwitcher.macroTab.actionTriggerMode.label + + + true - + - AdvSceneSwitcher.macroTab.onChange - - - AdvSceneSwitcher.macroTab.onChange - - - true + AdvSceneSwitcher.macroTab.actionTriggerMode.tooltip @@ -4125,7 +4119,7 @@ macroName runMacro runMacroInParallel - runMacroOnChange + actionTriggerMode macroSettings macroEdit sceneGroups diff --git a/lib/advanced-scene-switcher.hpp b/lib/advanced-scene-switcher.hpp index 19b88343..a932c267 100644 --- a/lib/advanced-scene-switcher.hpp +++ b/lib/advanced-scene-switcher.hpp @@ -108,7 +108,7 @@ public slots: void on_macroDown_clicked() const; void on_macroName_editingFinished(); void on_runMacroInParallel_stateChanged(int value) const; - void on_runMacroOnChange_stateChanged(int value) const; + void on_actionTriggerMode_currentIndexChanged(int index) const; void MacroSelectionChanged(); void ShowMacroContextMenu(const QPoint &); void CopyMacro(); diff --git a/lib/macro/macro-condition.cpp b/lib/macro/macro-condition.cpp index bd9a58a0..f855f405 100644 --- a/lib/macro/macro-condition.cpp +++ b/lib/macro/macro-condition.cpp @@ -7,6 +7,17 @@ MacroCondition::MacroCondition(Macro *m, bool supportsVariableValue) { } +bool MacroCondition::EvaluateCondition() +{ + bool newValue = CheckCondition(); + _changed = _previousValue.has_value() && (*_previousValue != newValue); + const bool negate = _logic.IsNegationType(GetLogicType()); + _risingEdge = _changed && + ((!negate && newValue) || (negate && !newValue)); + _previousValue = newValue; + return newValue; +} + bool MacroCondition::Save(obs_data_t *obj) const { MacroSegment::Save(obj); diff --git a/lib/macro/macro-condition.hpp b/lib/macro/macro-condition.hpp index 8cac06b3..f75c8937 100644 --- a/lib/macro/macro-condition.hpp +++ b/lib/macro/macro-condition.hpp @@ -4,13 +4,19 @@ #include "duration-modifier.hpp" #include "macro-ref.hpp" +#include + namespace advss { class EXPORT MacroCondition : public MacroSegment { public: MacroCondition(Macro *m, bool supportsVariableValue = false); virtual ~MacroCondition() = default; - virtual bool CheckCondition() = 0; + + bool EvaluateCondition(); + bool HasChanged() const { return _changed; } + bool IsRisingEdge() const { return _risingEdge; } + virtual bool Save(obs_data_t *obj) const = 0; virtual bool Load(obs_data_t *obj) = 0; @@ -28,9 +34,15 @@ public: static std::string_view GetDefaultID(); +protected: + virtual bool CheckCondition() = 0; + private: Logic _logic = Logic(Logic::Type::ROOT_NONE); DurationModifier _durationModifier; + std::optional _previousValue; + bool _changed = false; + bool _risingEdge = false; }; class EXPORT MacroRefCondition : virtual public MacroCondition { diff --git a/lib/macro/macro-tab.cpp b/lib/macro/macro-tab.cpp index 00d1e4ad..8a1b42e6 100644 --- a/lib/macro/macro-tab.cpp +++ b/lib/macro/macro-tab.cpp @@ -474,14 +474,17 @@ void AdvSceneSwitcher::on_runMacroInParallel_stateChanged(int value) const macro->SetRunInParallel(value); } -void AdvSceneSwitcher::on_runMacroOnChange_stateChanged(int value) const +void AdvSceneSwitcher::on_actionTriggerMode_currentIndexChanged(int index) const { auto macro = GetSelectedMacro(); if (!macro) { return; } + auto lock = LockContext(); - macro->SetMatchOnChange(value); + const auto mode = static_cast( + ui->actionTriggerMode->itemData(index).toInt()); + macro->SetActionTriggerMode(mode); } void AdvSceneSwitcher::SetMacroEditAreaDisabled(bool disable) const @@ -489,7 +492,7 @@ void AdvSceneSwitcher::SetMacroEditAreaDisabled(bool disable) const ui->macroName->setDisabled(disable); ui->runMacro->setDisabled(disable); ui->runMacroInParallel->setDisabled(disable); - ui->runMacroOnChange->setDisabled(disable); + ui->actionTriggerMode->setDisabled(disable); ui->macroEdit->SetControlsDisabled(disable); } @@ -519,10 +522,12 @@ void AdvSceneSwitcher::MacroSelectionChanged() { const QSignalBlocker b1(ui->macroName); const QSignalBlocker b2(ui->runMacroInParallel); - const QSignalBlocker b3(ui->runMacroOnChange); + const QSignalBlocker b3(ui->actionTriggerMode); ui->macroName->setText(macro->Name().c_str()); ui->runMacroInParallel->setChecked(macro->RunInParallel()); - ui->runMacroOnChange->setChecked(macro->MatchOnChange()); + ui->actionTriggerMode->setCurrentIndex( + ui->actionTriggerMode->findData(static_cast( + macro->GetActionTriggerMode()))); } macro->ResetUIHelpers(); @@ -552,9 +557,9 @@ void AdvSceneSwitcher::HighlightOnChange() const return; } - if (macro->OnChangePreventedActionsSince( + if (macro->ActionTriggerModePreventedActionsSince( lastOnChangeHighlightCheckTime)) { - HighlightWidget(ui->runMacroOnChange, Qt::yellow, + HighlightWidget(ui->actionTriggerMode, Qt::yellow, Qt::transparent, true); } @@ -682,6 +687,24 @@ void AdvSceneSwitcher::SetupMacroTab() ui->macroSearchRegex, ui->macroSearchShowSettings, [this]() { ui->macros->RefreshFilter(); }); + + static const std::vector< + std::pair> + actionTriggerModes = { + {Macro::ActionTriggerMode::ALWAYS, + "AdvSceneSwitcher.macroTab.actionTriggerMode.always"}, + {Macro::ActionTriggerMode::MACRO_RESULT_CHANGED, + "AdvSceneSwitcher.macroTab.actionTriggerMode.onOverallChange"}, + {Macro::ActionTriggerMode::ANY_CONDITION_CHANGED, + "AdvSceneSwitcher.macroTab.actionTriggerMode.onAnyConditionChange"}, + {Macro::ActionTriggerMode::ANY_CONDITION_TRIGGERED, + "AdvSceneSwitcher.macroTab.actionTriggerMode.onAnyConditionTriggered"}, + }; + + for (const auto &[mode, name] : actionTriggerModes) { + ui->actionTriggerMode->addItem(obs_module_text(name), + static_cast(mode)); + } } void AdvSceneSwitcher::ShowMacroContextMenu(const QPoint &pos) diff --git a/lib/macro/macro-tree.cpp b/lib/macro/macro-tree.cpp index 169f1963..f4c963eb 100644 --- a/lib/macro/macro-tree.cpp +++ b/lib/macro/macro-tree.cpp @@ -224,7 +224,8 @@ void MacroTreeItem::HighlightIfExecuted() if (!wasHighlighted && _lastHighlightCheckTime.time_since_epoch().count() != 0 && - _macro->OnChangePreventedActionsSince(_lastHighlightCheckTime)) { + _macro->ActionTriggerModePreventedActionsSince( + _lastHighlightCheckTime)) { HighlightWidget(this, Qt::yellow, QColor(0, 0, 0, 0), true); } diff --git a/lib/macro/macro.cpp b/lib/macro/macro.cpp index 91a526b1..c061e6c0 100644 --- a/lib/macro/macro.cpp +++ b/lib/macro/macro.cpp @@ -111,7 +111,7 @@ static bool checkCondition(const std::shared_ptr &condition) const auto startTime = std::chrono::high_resolution_clock::now(); bool conditionMatched = false; condition->WithLock([&condition, &conditionMatched]() { - conditionMatched = condition->CheckCondition(); + conditionMatched = condition->EvaluateCondition(); }); const auto endTime = std::chrono::high_resolution_clock::now(); const auto timeSpent = endTime - startTime; @@ -241,12 +241,36 @@ bool Macro::CheckConditions(bool ignorePause) vblog(LOG_INFO, "Macro %s returned %d", _name.c_str(), _matched); - _conditionSateChanged = _lastMatched != _matched; + _actionModeMatch = false; + switch (_actionTriggerMode) { + case Macro::ActionTriggerMode::ALWAYS: + _actionModeMatch = true; + break; + case Macro::ActionTriggerMode::MACRO_RESULT_CHANGED: + _actionModeMatch = _lastMatched != _matched; + break; + case Macro::ActionTriggerMode::ANY_CONDITION_CHANGED: + for (const auto &condition : _conditions) { + if (condition->HasChanged()) { + _actionModeMatch = true; + } + } + break; + case Macro::ActionTriggerMode::ANY_CONDITION_TRIGGERED: + for (const auto &condition : _conditions) { + if (condition->IsRisingEdge()) { + _actionModeMatch = true; + } + } + break; + default: + break; + } + const bool hasActionsToExecute = _matched ? (_actions.size() > 0) : (_elseActions.size() > 0); - if (!_conditionSateChanged && _performActionsOnChange && - hasActionsToExecute) { - _lastOnChangeActionsPreventedTime = + if (!_actionModeMatch && hasActionsToExecute) { + _lastActionRunModePreventTime = std::chrono::high_resolution_clock::now(); } @@ -306,9 +330,9 @@ bool Macro::WasExecutedSince(const TimePoint &time) const return _lastExecutionTime > time; } -bool Macro::OnChangePreventedActionsSince(const TimePoint &time) const +bool Macro::ActionTriggerModePreventedActionsSince(const TimePoint &time) const { - return _lastOnChangeActionsPreventedTime > time; + return _lastActionRunModePreventTime > time; } Macro::TimePoint Macro::GetLastExecutionTime() const @@ -342,10 +366,9 @@ bool Macro::ShouldRunActions() const const bool hasActionsToExecute = !_paused && (_matched || _elseActions.size() > 0) && - (!_performActionsOnChange || _conditionSateChanged); + _actionModeMatch; - if (VerboseLoggingEnabled() && _performActionsOnChange && - !_conditionSateChanged) { + if (VerboseLoggingEnabled() && !_actionModeMatch) { if (_matched && _actions.size() > 0) { blog(LOG_INFO, "skip actions for Macro %s (on change)", _name.c_str()); @@ -376,6 +399,16 @@ void Macro::ResetTimers() _lastExecutionTime = {}; } +void Macro::SetActionTriggerMode(ActionTriggerMode mode) +{ + _actionTriggerMode = mode; +} + +Macro::ActionTriggerMode Macro::GetActionTriggerMode() const +{ + return _actionTriggerMode; +} + bool Macro::RunActionsHelper( const std::deque> &actionsToRun, bool ignorePause) @@ -433,11 +466,6 @@ bool Macro::WasPausedSince(const TimePoint &time) const return _lastUnpauseTime > time; } -void Macro::SetMatchOnChange(bool onChange) -{ - _performActionsOnChange = onChange; -} - void Macro::SetStopActionsIfNotDone(bool stopActionsIfNotDone) { _stopActionsIfNotDone = stopActionsIfNotDone; @@ -758,7 +786,8 @@ bool Macro::Save(obs_data_t *obj, bool saveForCopy) const 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_int(obj, "actionTriggerMode", + static_cast(_actionTriggerMode)); obs_data_set_bool(obj, "skipExecOnStart", _skipExecOnStart); obs_data_set_bool(obj, "stopActionsIfNotDone", _stopActionsIfNotDone); obs_data_set_bool(obj, "useShortCircuitEvaluation", @@ -844,7 +873,15 @@ bool Macro::Load(obs_data_t *obj) } _runInParallel = obs_data_get_bool(obj, "parallel"); _checkInParallel = obs_data_get_bool(obj, "checkConditionsInParallel"); - _performActionsOnChange = obs_data_get_bool(obj, "onChange"); + if (obs_data_has_user_value(obj, "onChange")) { + const bool onChange = obs_data_get_bool(obj, "onChange"); + _actionTriggerMode = + onChange ? ActionTriggerMode::MACRO_RESULT_CHANGED + : ActionTriggerMode::ALWAYS; + } else { + _actionTriggerMode = static_cast( + obs_data_get_int(obj, "actionTriggerMode")); + } _skipExecOnStart = obs_data_get_bool(obj, "skipExecOnStart"); _stopActionsIfNotDone = obs_data_get_bool(obj, "stopActionsIfNotDone"); _useShortCircuitEvaluation = diff --git a/lib/macro/macro.hpp b/lib/macro/macro.hpp index 318a41bc..45433d12 100644 --- a/lib/macro/macro.hpp +++ b/lib/macro/macro.hpp @@ -26,6 +26,16 @@ class Macro { public: enum class PauseStateSaveBehavior { PERSIST, PAUSE, UNPAUSE }; + enum class ActionTriggerMode { + // Trigger always + ALWAYS, + // Trigger when macro match result flips + MACRO_RESULT_CHANGED, + // Trigger when any individual condition changes + ANY_CONDITION_CHANGED, + // Trigger when any individual condition evaluates to true + ANY_CONDITION_TRIGGERED, + }; Macro(const std::string &name = ""); Macro(const std::string &name, const GlobalMacroSettings &settings); @@ -54,8 +64,8 @@ public: bool GetStop() const { return _stop; } void ResetTimers(); - void SetMatchOnChange(bool onChange); - bool MatchOnChange() const { return _performActionsOnChange; } + void SetActionTriggerMode(ActionTriggerMode); + ActionTriggerMode GetActionTriggerMode() const; void SetSkipExecOnStart(bool skip) { _skipExecOnStart = skip; } bool SkipExecOnStart() const { return _skipExecOnStart; } @@ -137,7 +147,7 @@ public: const QList &GetElseActionSplitterPosition() const; bool HasValidSplitterPositions() const; bool WasExecutedSince(const TimePoint &) const; - bool OnChangePreventedActionsSince(const TimePoint &) const; + bool ActionTriggerModePreventedActionsSince(const TimePoint &) const; TimePoint GetLastExecutionTime() const; void ResetUIHelpers(); @@ -169,7 +179,7 @@ private: TimePoint _lastCheckTime{}; TimePoint _lastUnpauseTime{}; TimePoint _lastExecutionTime{}; - TimePoint _lastOnChangeActionsPreventedTime{}; + TimePoint _lastActionRunModePreventTime{}; std::vector _helperThreads; std::deque> _conditions; @@ -184,14 +194,13 @@ private: bool _useShortCircuitEvaluation = false; bool _useCustomConditionCheckInterval = false; Duration _customConditionCheckInterval = 0.3; - bool _conditionSateChanged = false; + bool _actionModeMatch = false; bool _runInParallel = false; bool _checkInParallel = false; bool _matched = false; std::future _conditionCheckFuture; bool _lastMatched = false; - bool _performActionsOnChange = true; bool _skipExecOnStart = false; bool _stopActionsIfNotDone = false; bool _paused = false; @@ -201,6 +210,9 @@ private: obs_hotkey_id _unpauseHotkey = OBS_INVALID_HOTKEY_ID; obs_hotkey_id _togglePauseHotkey = OBS_INVALID_HOTKEY_ID; + ActionTriggerMode _actionTriggerMode = + ActionTriggerMode::MACRO_RESULT_CHANGED; + PauseStateSaveBehavior _pauseSaveBehavior = PauseStateSaveBehavior::PERSIST;