Add option to conditionally run action of other macros

This commit is contained in:
WarmUpTill 2024-05-02 21:07:00 +02:00 committed by WarmUpTill
parent 9a4eef4a83
commit 406b5d61f5
7 changed files with 251 additions and 27 deletions

View File

@ -469,7 +469,6 @@ AdvSceneSwitcher.action.macro.type.unpause="Nicht mehr pausieren"
AdvSceneSwitcher.action.macro.type.resetCounter="Zähler zurücksetzen"
AdvSceneSwitcher.action.macro.type.run="Aktionen ausführen"
AdvSceneSwitcher.action.macro.type.stop="Aktionen stoppen"
AdvSceneSwitcher.action.macro.entry="{{actions}}{{actionIndex}}{{macros}}"
AdvSceneSwitcher.action.pluginState="Plugin-Status"
AdvSceneSwitcher.action.pluginState.type.stop="Erweiterten Automatischen Szenenwechsler stoppen"
AdvSceneSwitcher.action.pluginState.type.noMatch="Ändern des Nichtübereinstimmungsverhaltens:"

View File

@ -812,12 +812,20 @@ AdvSceneSwitcher.action.macro="Macro"
AdvSceneSwitcher.action.macro.type.pause="Pause"
AdvSceneSwitcher.action.macro.type.unpause="Unpause"
AdvSceneSwitcher.action.macro.type.resetCounter="Reset counter"
AdvSceneSwitcher.action.macro.type.run="Run actions"
AdvSceneSwitcher.action.macro.type.run="Run macro"
AdvSceneSwitcher.action.macro.type.run.conditions.ignore="Do not consider condition state"
AdvSceneSwitcher.action.macro.type.run.conditions.true="Only if conditions evaluate to true"
AdvSceneSwitcher.action.macro.type.run.conditions.false="Only if conditions evaluate to false"
AdvSceneSwitcher.action.macro.type.run.actionType.regular="actions"
AdvSceneSwitcher.action.macro.type.run.actionType.else="else-actions"
AdvSceneSwitcher.action.macro.type.run.skipWhenPaused="Skip execution when macro is paused"
AdvSceneSwitcher.action.macro.type.stop="Stop actions"
AdvSceneSwitcher.action.macro.type.disableAction="Disable action"
AdvSceneSwitcher.action.macro.type.enableAction="Enable action"
AdvSceneSwitcher.action.macro.type.toggleAction="Toggle action"
AdvSceneSwitcher.action.macro.entry="{{actions}}{{actionIndex}}{{macros}}"
AdvSceneSwitcher.action.macro.entry.run="{{actions}}{{actionTypes}}of{{macros}}"
AdvSceneSwitcher.action.macro.entry.run.condition="{{conditionBehaviors}}of{{conditionMacros}}"
AdvSceneSwitcher.action.macro.entry.other="{{actions}}{{actionIndex}}{{macros}}"
AdvSceneSwitcher.action.pluginState="Plugin state"
AdvSceneSwitcher.action.pluginState.type.stop="Stop the Advanced Scene Switcher plugin"
AdvSceneSwitcher.action.pluginState.type.noMatch="Change the no-match behaviour:"

View File

@ -386,7 +386,6 @@ AdvSceneSwitcher.action.macro.type.unpause="Reanudar"
AdvSceneSwitcher.action.macro.type.resetCounter="Reiniciar contador"
AdvSceneSwitcher.action.macro.type.run="Ejecutar"
AdvSceneSwitcher.action.macro.type.stop="Detener"
AdvSceneSwitcher.action.macro.entry="{{actions}}{{actionIndex}}{{macros}}"
AdvSceneSwitcher.action.pluginState="Estado del complemento"
AdvSceneSwitcher.action.pluginState.type.stop="Detener el complemento Advanced Scene Switcher"
AdvSceneSwitcher.action.pluginState.type.noMatch="Cambiar el comportamiento de no coincidencia:"

View File

@ -315,7 +315,6 @@ AdvSceneSwitcher.action.macro.type.pause="Duraklat"
AdvSceneSwitcher.action.macro.type.unpause="Duraklatma"
AdvSceneSwitcher.action.macro.type.resetCounter="Sayacı sıfırla"
AdvSceneSwitcher.action.macro.type.run="Çalıştır"
AdvSceneSwitcher.action.macro.entry="{{actions}}{{actionIndex}}{{macros}}"
AdvSceneSwitcher.action.pluginState="Eklenti durumu"
AdvSceneSwitcher.action.pluginState.type.stop="Advanced Scene Switcher eklentisini durdurun"
AdvSceneSwitcher.action.pluginState.type.noMatch="Eşleşmeme davranışını değiştirin:"

View File

@ -524,7 +524,6 @@ AdvSceneSwitcher.action.macro.type.unpause="取消暂停"
AdvSceneSwitcher.action.macro.type.resetCounter="复位计数器"
AdvSceneSwitcher.action.macro.type.run="运行操作"
AdvSceneSwitcher.action.macro.type.stop="停止操作"
AdvSceneSwitcher.action.macro.entry="{{actions}}{{actionIndex}}{{macros}}"
AdvSceneSwitcher.action.pluginState="插件状态"
AdvSceneSwitcher.action.pluginState.type.stop="停止高级场景切换插件"
AdvSceneSwitcher.action.pluginState.type.noMatch="没有匹配项时:"

View File

@ -48,9 +48,7 @@ bool MacroActionMacro::PerformAction()
macro->ResetRunCount();
break;
case Action::RUN:
if (!macro->Paused()) {
macro->PerformActions(true, false, true);
}
RunActions(macro.get());
break;
case Action::STOP:
macro->Stop();
@ -127,6 +125,7 @@ bool MacroActionMacro::Save(obs_data_t *obj) const
_macro.Save(obj);
_actionIndex.Save(obj, "actionIndex");
obs_data_set_int(obj, "action", static_cast<int>(_action));
_runOptions.Save(obj);
return true;
}
@ -137,6 +136,15 @@ bool MacroActionMacro::Load(obs_data_t *obj)
_actionIndex.Load(obj, "actionIndex");
_action = static_cast<MacroActionMacro::Action>(
obs_data_get_int(obj, "action"));
_runOptions.Load(obj);
return true;
}
bool MacroActionMacro::PostLoad()
{
MacroRefAction::PostLoad();
MacroAction::PostLoad();
_runOptions.macro.PostLoad();
return true;
}
@ -160,11 +168,55 @@ void MacroActionMacro::ResolveVariablesToFixedValues()
_actionIndex.ResolveVariables();
}
static inline void populateActionSelection(QComboBox *list)
void MacroActionMacro::RunActions(Macro *actionMacro) const
{
for (auto entry : actionTypes) {
list->addItem(obs_module_text(entry.second.c_str()));
if (_runOptions.skipWhenPaused && actionMacro->Paused()) {
return;
}
if (_runOptions.logic == RunOptions::Logic::IGNORE_CONDITIONS) {
actionMacro->PerformActions(!_runOptions.runElseActions, false,
true);
return;
}
auto conditionMacro = _runOptions.macro.GetMacro();
if (!conditionMacro) {
return;
}
if ((_runOptions.logic == RunOptions::Logic::CONDITIONS &&
conditionMacro->Matched()) ||
(_runOptions.logic == RunOptions::Logic::INVERT_CONDITIONS &&
!conditionMacro->Matched())) {
actionMacro->PerformActions(!_runOptions.runElseActions, false,
true);
}
}
static void populateActionSelection(QComboBox *list)
{
for (const auto &[_, name] : actionTypes) {
list->addItem(obs_module_text(name.c_str()));
}
}
static void populateConditionBehaviorSelection(QComboBox *list)
{
list->addItem(obs_module_text(
"AdvSceneSwitcher.action.macro.type.run.conditions.ignore"));
list->addItem(obs_module_text(
"AdvSceneSwitcher.action.macro.type.run.conditions.true"));
list->addItem(obs_module_text(
"AdvSceneSwitcher.action.macro.type.run.conditions.false"));
}
static void populateActionTypeSelection(QComboBox *list)
{
list->addItem(obs_module_text(
"AdvSceneSwitcher.action.macro.type.run.actionType.regular"));
list->addItem(obs_module_text(
"AdvSceneSwitcher.action.macro.type.run.actionType.else"));
}
MacroActionMacroEdit::MacroActionMacroEdit(
@ -173,9 +225,20 @@ MacroActionMacroEdit::MacroActionMacroEdit(
_macros(new MacroSelection(parent)),
_actionIndex(new MacroSegmentSelection(
this, MacroSegmentSelection::Type::ACTION)),
_actions(new QComboBox())
_actions(new QComboBox()),
_conditionMacros(new MacroSelection(parent)),
_conditionBehaviors(new QComboBox()),
_actionTypes(new QComboBox()),
_skipWhenPaused(new QCheckBox(obs_module_text(
"AdvSceneSwitcher.action.macro.type.run.skipWhenPaused"))),
_entryLayout(new QHBoxLayout()),
_conditionLayout(new QHBoxLayout())
{
populateActionSelection(_actions);
populateConditionBehaviorSelection(_conditionBehaviors);
populateActionTypeSelection(_actionTypes);
_conditionMacros->HideSelectedMacro();
QWidget::connect(_macros, SIGNAL(currentTextChanged(const QString &)),
this, SLOT(MacroChanged(const QString &)));
@ -184,15 +247,21 @@ MacroActionMacroEdit::MacroActionMacroEdit(
QWidget::connect(_actionIndex,
SIGNAL(SelectionChanged(const IntVariable &)), this,
SLOT(ActionIndexChanged(const IntVariable &)));
QWidget::connect(_conditionMacros,
SIGNAL(currentTextChanged(const QString &)), this,
SLOT(ConditionMacroChanged(const QString &)));
QWidget::connect(_conditionBehaviors, SIGNAL(currentIndexChanged(int)),
this, SLOT(ConditionBehaviorChanged(int)));
QWidget::connect(_actionTypes, SIGNAL(currentIndexChanged(int)), this,
SLOT(ActionTypeChanged(int)));
QWidget::connect(_skipWhenPaused, SIGNAL(stateChanged(int)), this,
SLOT(SkipWhenPausedChanged(int)));
auto mainLayout = new QHBoxLayout;
PlaceWidgets(obs_module_text("AdvSceneSwitcher.action.macro.entry"),
mainLayout,
{{"{{actions}}", _actions},
{"{{actionIndex}}", _actionIndex},
{"{{macros}}", _macros}});
setLayout(mainLayout);
auto layout = new QVBoxLayout();
layout->addLayout(_entryLayout);
layout->addLayout(_conditionLayout);
layout->addWidget(_skipWhenPaused);
setLayout(layout);
_entryData = entryData;
UpdateEntryData();
_loading = false;
@ -207,6 +276,12 @@ void MacroActionMacroEdit::UpdateEntryData()
_actionIndex->SetValue(_entryData->_actionIndex);
_actionIndex->SetMacro(_entryData->_macro.GetMacro());
_macros->SetCurrentMacro(_entryData->_macro);
_conditionMacros->SetCurrentMacro(_entryData->_runOptions.macro);
_conditionBehaviors->setCurrentIndex(
static_cast<int>(_entryData->_runOptions.logic));
_actionTypes->setCurrentIndex(
_entryData->_runOptions.runElseActions ? 1 : 0);
_skipWhenPaused->setChecked(_entryData->_runOptions.skipWhenPaused);
SetWidgetVisibility();
}
@ -244,8 +319,88 @@ void MacroActionMacroEdit::ActionIndexChanged(const IntVariable &value)
_entryData->_actionIndex = value;
}
void MacroActionMacroEdit::ConditionMacroChanged(const QString &text)
{
if (_loading || !_entryData) {
return;
}
auto lock = LockContext();
_entryData->_runOptions.macro = text;
}
void MacroActionMacroEdit::ConditionBehaviorChanged(int value)
{
if (_loading || !_entryData) {
return;
}
auto lock = LockContext();
_entryData->_runOptions.logic =
static_cast<MacroActionMacro::RunOptions::Logic>(value);
SetWidgetVisibility();
}
void MacroActionMacroEdit::ActionTypeChanged(int value)
{
if (_loading || !_entryData) {
return;
}
auto lock = LockContext();
_entryData->_runOptions.runElseActions = value;
}
void MacroActionMacroEdit::SkipWhenPausedChanged(int value)
{
if (_loading || !_entryData) {
return;
}
auto lock = LockContext();
_entryData->_runOptions.skipWhenPaused = value;
}
void MacroActionMacroEdit::SetWidgetVisibility()
{
_entryLayout->removeWidget(_actions);
_entryLayout->removeWidget(_actionIndex);
_entryLayout->removeWidget(_macros);
_entryLayout->removeWidget(_actionTypes);
_conditionLayout->removeWidget(_conditionBehaviors);
_conditionLayout->removeWidget(_conditionMacros);
ClearLayout(_entryLayout);
ClearLayout(_conditionLayout);
const std::unordered_map<std::string, QWidget *> placeholders = {
{"{{actions}}", _actions},
{"{{actionIndex}}", _actionIndex},
{"{{macros}}", _macros},
{"{{actionTypes}}", _actionTypes},
{"{{conditionBehaviors}}", _conditionBehaviors},
{"{{conditionMacros}}", _conditionMacros},
};
PlaceWidgets(
obs_module_text(
_entryData->_action == MacroActionMacro::Action::RUN
? "AdvSceneSwitcher.action.macro.entry.run"
: "AdvSceneSwitcher.action.macro.entry.other"),
_entryLayout, placeholders);
if (_entryData->_runOptions.logic ==
MacroActionMacro::RunOptions::Logic::IGNORE_CONDITIONS) {
_conditionLayout->addWidget(_conditionBehaviors);
_conditionLayout->addStretch();
} else {
PlaceWidgets(
obs_module_text(
"AdvSceneSwitcher.action.macro.entry.run.condition"),
_conditionLayout, placeholders);
}
if (_entryData->_action == MacroActionMacro::Action::RUN ||
_entryData->_action == MacroActionMacro::Action::STOP) {
_macros->HideSelectedMacro();
@ -260,6 +415,42 @@ void MacroActionMacroEdit::SetWidgetVisibility()
MacroActionMacro::Action::ENABLE_ACTION ||
_entryData->_action == MacroActionMacro::Action::TOGGLE_ACTION;
_actionIndex->setVisible(isModifyingActionState);
SetLayoutVisible(_conditionLayout,
_entryData->_action == MacroActionMacro::Action::RUN);
_conditionMacros->setVisible(
_entryData->_action == MacroActionMacro::Action::RUN &&
_entryData->_runOptions.logic !=
MacroActionMacro::RunOptions::Logic::IGNORE_CONDITIONS);
_actionTypes->setVisible(_entryData->_action ==
MacroActionMacro::Action::RUN);
_skipWhenPaused->setVisible(_entryData->_action ==
MacroActionMacro::Action::RUN);
adjustSize();
updateGeometry();
}
void MacroActionMacro::RunOptions::Save(obs_data_t *obj) const
{
OBSDataAutoRelease data = obs_data_create();
obs_data_set_int(data, "logic", static_cast<int>(logic));
obs_data_set_bool(data, "runElseActions", runElseActions);
obs_data_set_bool(data, "skipWhenPaused", skipWhenPaused);
macro.Save(data);
obs_data_set_obj(obj, "runOptions", data);
}
void MacroActionMacro::RunOptions::Load(obs_data_t *obj)
{
if (!obs_data_has_user_value(obj, "runOptions")) {
return;
}
OBSDataAutoRelease data = obs_data_get_obj(obj, "runOptions");
logic = static_cast<Logic>(obs_data_get_int(data, "logic"));
runElseActions = obs_data_get_bool(data, "runElseActions");
skipWhenPaused = obs_data_get_bool(data, "skipWhenPaused");
macro.Load(data);
}
} // namespace advss

View File

@ -3,6 +3,7 @@
#include "macro-selection.hpp"
#include "macro-segment-selection.hpp"
#include <QCheckBox>
#include <QHBoxLayout>
namespace advss {
@ -14,12 +15,27 @@ public:
void LogAction() const;
bool Save(obs_data_t *obj) const;
bool Load(obs_data_t *obj);
bool PostLoad();
std::string GetShortDesc() const;
std::string GetId() const { return id; };
static std::shared_ptr<MacroAction> Create(Macro *m);
std::shared_ptr<MacroAction> Copy() const;
void ResolveVariablesToFixedValues();
struct RunOptions {
void Save(obs_data_t *obj) const;
void Load(obs_data_t *obj);
enum class Logic {
IGNORE_CONDITIONS,
CONDITIONS,
INVERT_CONDITIONS,
};
Logic logic;
bool runElseActions = false;
bool skipWhenPaused = true;
MacroRef macro;
};
enum class Action {
PAUSE,
UNPAUSE,
@ -32,8 +48,11 @@ public:
};
Action _action = Action::PAUSE;
IntVariable _actionIndex = 1;
RunOptions _runOptions = {};
private:
void RunActions(Macro *actionMacro) const;
static bool _registered;
static const std::string id;
};
@ -58,18 +77,28 @@ private slots:
void MacroChanged(const QString &text);
void ActionChanged(int value);
void ActionIndexChanged(const IntVariable &value);
void ConditionMacroChanged(const QString &text);
void ConditionBehaviorChanged(int value);
void ActionTypeChanged(int value);
void SkipWhenPausedChanged(int value);
signals:
void HeaderInfoChanged(const QString &);
protected:
MacroSelection *_macros;
MacroSegmentSelection *_actionIndex;
QComboBox *_actions;
std::shared_ptr<MacroActionMacro> _entryData;
private:
void SetWidgetVisibility();
MacroSelection *_macros;
MacroSegmentSelection *_actionIndex;
QComboBox *_actions;
MacroSelection *_conditionMacros;
QComboBox *_conditionBehaviors;
QComboBox *_actionTypes;
QCheckBox *_skipWhenPaused;
QHBoxLayout *_entryLayout;
QHBoxLayout *_conditionLayout;
std::shared_ptr<MacroActionMacro> _entryData;
bool _loading = true;
};