Add option to set variable value based on condition or action

This commit is contained in:
WarmUpTill 2023-01-07 03:11:45 +01:00 committed by WarmUpTill
parent ee5038106a
commit df8e84dd09
4 changed files with 344 additions and 49 deletions

View File

@ -574,12 +574,18 @@ AdvSceneSwitcher.action.http.type.post="POST"
AdvSceneSwitcher.action.http.entry.line1="Send {{method}} to {{url}}"
AdvSceneSwitcher.action.http.entry.line2="Timeout: {{timeout}} seconds"
AdvSceneSwitcher.action.variable="Variable"
AdvSceneSwitcher.action.variable.type.set="Set"
AdvSceneSwitcher.action.variable.type.set="Set to fixed value"
AdvSceneSwitcher.action.variable.type.append="Append"
AdvSceneSwitcher.action.variable.type.appendVar="Append variable"
AdvSceneSwitcher.action.variable.type.increment="Increment"
AdvSceneSwitcher.action.variable.type.decrement="Decrement"
AdvSceneSwitcher.action.variable.entry="{{actions}}{{variables}}{{variables2}}{{strValue}}{{numValue}}"
AdvSceneSwitcher.action.variable.type.setActionValue="Set to action value"
AdvSceneSwitcher.action.variable.type.setConditionValue="Set to condition value"
AdvSceneSwitcher.action.variable.invalidSelection="Invalid selection!"
AdvSceneSwitcher.action.variable.actionNoVariableSupport="Getting variable values from %1 actions is not supported!"
AdvSceneSwitcher.action.variable.conditionNoVariableSupport="Getting variable values from %1 conditions is not supported!"
AdvSceneSwitcher.action.variable.currentSegmentValue="Current value:"
AdvSceneSwitcher.action.variable.entry="{{actions}}{{variables}}{{variables2}}{{strValue}}{{numValue}}{{segmentIndex}}"
; Transition Tab

View File

@ -542,7 +542,7 @@ AdvSceneSwitcher.action.variable.type.append="追加"
AdvSceneSwitcher.action.variable.type.appendVar="追加变量"
AdvSceneSwitcher.action.variable.type.increment="增加"
AdvSceneSwitcher.action.variable.type.decrement="减少"
AdvSceneSwitcher.action.variable.entry="{{actions}}{{variables}}{{variables2}}{{strValue}}{{numValue}}"
AdvSceneSwitcher.action.variable.entry="{{actions}}{{variables}}{{variables2}}{{strValue}}{{numValue}}{{segmentIndex}}"
; Transition Tab

View File

@ -1,5 +1,6 @@
#include "macro-action-variable.hpp"
#include "advanced-scene-switcher.hpp"
#include "macro-condition-edit.hpp"
#include "utility.hpp"
const std::string MacroActionVariable::id = "variable";
@ -9,8 +10,8 @@ bool MacroActionVariable::_registered = MacroActionFactory::Register(
{MacroActionVariable::Create, MacroActionVariableEdit::Create,
"AdvSceneSwitcher.action.variable"});
static std::map<MacroActionVariable::Type, std::string> waitTypes = {
{MacroActionVariable::Type::SET,
static std::map<MacroActionVariable::Type, std::string> actionTypes = {
{MacroActionVariable::Type::SET_FIXED_VALUE,
"AdvSceneSwitcher.action.variable.type.set"},
{MacroActionVariable::Type::APPEND,
"AdvSceneSwitcher.action.variable.type.append"},
@ -20,6 +21,10 @@ static std::map<MacroActionVariable::Type, std::string> waitTypes = {
"AdvSceneSwitcher.action.variable.type.increment"},
{MacroActionVariable::Type::DECREMENT,
"AdvSceneSwitcher.action.variable.type.decrement"},
{MacroActionVariable::Type::SET_CONDITION_VALUE,
"AdvSceneSwitcher.action.variable.type.setConditionValue"},
{MacroActionVariable::Type::SET_ACTION_VALUE,
"AdvSceneSwitcher.action.variable.type.setActionValue"},
};
static void apppend(Variable &var, const std::string &value)
@ -41,6 +46,11 @@ static void modifyNumValue(Variable &var, double val, const bool increment)
}
}
MacroActionVariable::~MacroActionVariable()
{
DecrementCurrentSegmentVariableRef();
}
bool MacroActionVariable::PerformAction()
{
auto var = GetVariableByName(_variableName);
@ -49,13 +59,13 @@ bool MacroActionVariable::PerformAction()
}
switch (_type) {
case MacroActionVariable::Type::SET:
case Type::SET_FIXED_VALUE:
var->SetValue(_strValue);
break;
case MacroActionVariable::Type::APPEND:
case Type::APPEND:
apppend(*var, _strValue);
break;
case MacroActionVariable::Type::APPEND_VAR: {
case Type::APPEND_VAR: {
auto var2 = GetVariableByName(_variable2Name);
if (!var2) {
return true;
@ -63,12 +73,28 @@ bool MacroActionVariable::PerformAction()
apppend(*var, var2->Value());
break;
}
case MacroActionVariable::Type::INCREMENT:
case Type::INCREMENT:
modifyNumValue(*var, _numValue, true);
break;
case MacroActionVariable::Type::DECREMENT:
case Type::DECREMENT:
modifyNumValue(*var, _numValue, false);
break;
case Type::SET_CONDITION_VALUE:
case Type::SET_ACTION_VALUE: {
auto m = GetMacro();
if (!m) {
return true;
}
if (GetSegmentIndexValue() == -1) {
return true;
}
auto segment = _macroSegment.lock();
if (!segment) {
return true;
}
var->SetValue(segment->GetVariableValue());
break;
}
}
return true;
@ -82,6 +108,7 @@ bool MacroActionVariable::Save(obs_data_t *obj) const
obs_data_set_string(obj, "strValue", _strValue.c_str());
obs_data_set_double(obj, "numValue", _numValue);
obs_data_set_int(obj, "condition", static_cast<int>(_type));
obs_data_set_int(obj, "segmentIdx", GetSegmentIndexValue());
return true;
}
@ -93,6 +120,13 @@ bool MacroActionVariable::Load(obs_data_t *obj)
_strValue = obs_data_get_string(obj, "strValue");
_numValue = obs_data_get_double(obj, "numValue");
_type = static_cast<Type>(obs_data_get_int(obj, "condition"));
_segmentIdxLoadValue = obs_data_get_int(obj, "segmentIdx");
return true;
}
bool MacroActionVariable::PostLoad()
{
SetSegmentIndexValue(_segmentIdxLoadValue);
return true;
}
@ -101,9 +135,82 @@ std::string MacroActionVariable::GetShortDesc() const
return _variableName;
}
void MacroActionVariable::SetSegmentIndexValue(int value)
{
DecrementCurrentSegmentVariableRef();
auto m = GetMacro();
if (!m) {
_macroSegment.reset();
return;
}
if (value < 0) {
_macroSegment.reset();
return;
}
std::shared_ptr<MacroSegment> segment;
if (_type == Type::SET_CONDITION_VALUE) {
if (value < m->Conditions().size()) {
segment = m->Conditions().at(value);
}
} else if (_type == Type::SET_ACTION_VALUE) {
if (value < m->Actions().size()) {
segment = m->Actions().at(value);
}
}
_macroSegment = segment;
if (segment) {
segment->IncrementVariableRef();
}
}
int MacroActionVariable::GetSegmentIndexValue() const
{
auto m = GetMacro();
if (!m) {
return -1;
}
auto segment = _macroSegment.lock();
if (!segment) {
return -1;
}
if (_type == Type::SET_CONDITION_VALUE) {
auto it = std::find(m->Conditions().begin(),
m->Conditions().end(), segment);
if (it != m->Conditions().end()) {
return std::distance(m->Conditions().begin(), it);
}
return -1;
} else if (_type == Type::SET_ACTION_VALUE) {
auto it = std::find(m->Actions().begin(), m->Actions().end(),
segment);
if (it != m->Actions().end()) {
return std::distance(m->Actions().begin(), it);
}
return -1;
}
return -1;
}
void MacroActionVariable::DecrementCurrentSegmentVariableRef()
{
auto segment = _macroSegment.lock();
if (!segment) {
return;
}
segment->DecrementVariableRef();
}
static inline void populateTypeSelection(QComboBox *list)
{
for (auto entry : waitTypes) {
for (auto entry : actionTypes) {
list->addItem(obs_module_text(entry.second.c_str()));
}
}
@ -115,10 +222,17 @@ MacroActionVariableEdit::MacroActionVariableEdit(
_variables2(new VariableSelection(this)),
_actions(new QComboBox()),
_strValue(new ResizingPlainTextEdit(this, 5, 1, 1)),
_numValue(new QDoubleSpinBox())
_numValue(new QDoubleSpinBox()),
_segmentIdx(new QSpinBox()),
_segmentValueStatus(new QLabel()),
_segmentValue(new ResizingPlainTextEdit(this))
{
_numValue->setMinimum(-9999999999);
_numValue->setMaximum(9999999999);
_segmentIdx->setMinimum(0);
_segmentIdx->setMaximum(99);
_segmentIdx->setSpecialValueText("-");
_segmentValue->setReadOnly(true);
populateTypeSelection(_actions);
QWidget::connect(_variables, SIGNAL(SelectionChanged(const QString &)),
@ -131,21 +245,36 @@ MacroActionVariableEdit::MacroActionVariableEdit(
SLOT(StrValueChanged()));
QWidget::connect(_numValue, SIGNAL(valueChanged(double)), this,
SLOT(NumValueChanged(double)));
QWidget::connect(_segmentIdx, SIGNAL(valueChanged(int)), this,
SLOT(SegmentIndexChanged(int)));
QWidget::connect(window(), SIGNAL(MacroSegmentOrderChanged()), this,
SLOT(MacroSegmentOrderChanged()));
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
{"{{variables}}", _variables}, {"{{variables2}}", _variables2},
{"{{actions}}", _actions}, {"{{strValue}}", _strValue},
{"{{variables}}", _variables},
{"{{variables2}}", _variables2},
{"{{actions}}", _actions},
{"{{strValue}}", _strValue},
{"{{numValue}}", _numValue},
{"{{segmentIndex}}", _segmentIdx},
};
auto mainLayout = new QHBoxLayout;
auto entryLayout = new QHBoxLayout;
placeWidgets(obs_module_text("AdvSceneSwitcher.action.variable.entry"),
mainLayout, widgetPlaceholders);
setLayout(mainLayout);
entryLayout, widgetPlaceholders);
auto layout = new QVBoxLayout;
layout->addLayout(entryLayout);
layout->addWidget(_segmentValueStatus);
layout->addWidget(_segmentValue);
setLayout(layout);
_entryData = entryData;
UpdateEntryData();
_loading = false;
connect(&_timer, SIGNAL(timeout()), this,
SLOT(UpdateSegmentVariableValue()));
_timer.start(1500);
}
void MacroActionVariableEdit::UpdateEntryData()
@ -159,6 +288,7 @@ void MacroActionVariableEdit::UpdateEntryData()
_actions->setCurrentIndex(static_cast<int>(_entryData->_type));
_strValue->setPlainText(QString::fromStdString(_entryData->_strValue));
_numValue->setValue(_entryData->_numValue);
_segmentIdx->setValue(_entryData->GetSegmentIndexValue() + 1);
SetWidgetVisibility();
}
@ -191,6 +321,12 @@ void MacroActionVariableEdit::ActionChanged(int value)
std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_type = static_cast<MacroActionVariable::Type>(value);
SetWidgetVisibility();
if (_entryData->_type == MacroActionVariable::Type::SET_ACTION_VALUE ||
_entryData->_type ==
MacroActionVariable::Type::SET_CONDITION_VALUE) {
MarkSelectedSegment();
}
}
void MacroActionVariableEdit::StrValueChanged()
@ -214,40 +350,175 @@ void MacroActionVariableEdit::NumValueChanged(double val)
_entryData->_numValue = val;
}
void MacroActionVariableEdit::SegmentIndexChanged(int val)
{
if (_loading || !_entryData) {
return;
}
std::lock_guard<std::mutex> lock(switcher->m);
_entryData->SetSegmentIndexValue(val - 1);
MarkSelectedSegment();
}
void MacroActionVariableEdit::SetSegmentValueError(const QString &text)
{
_segmentValueStatus->setText(text);
_segmentValue->setPlainText("");
_segmentValue->hide();
adjustSize();
updateGeometry();
}
void MacroActionVariableEdit::UpdateSegmentVariableValue()
{
if (!_entryData ||
!(_entryData->_type ==
MacroActionVariable::Type::SET_CONDITION_VALUE ||
_entryData->_type ==
MacroActionVariable::Type::SET_ACTION_VALUE)) {
return;
}
auto m = _entryData->GetMacro();
if (!m) {
return;
}
int index = _entryData->GetSegmentIndexValue();
if (index < 0) {
SetSegmentValueError(obs_module_text(
"AdvSceneSwitcher.action.variable.invalidSelection"));
const QSignalBlocker b(_segmentIdx);
_segmentIdx->setValue(index);
return;
}
std::shared_ptr<MacroSegment> segment;
if (_entryData->_type == MacroActionVariable::Type::SET_ACTION_VALUE) {
const auto &actions = m->Actions();
if (index < actions.size()) {
segment = actions.at(index);
}
} else if (_entryData->_type ==
MacroActionVariable::Type::SET_CONDITION_VALUE) {
const auto &conditions = m->Conditions();
if (index < conditions.size()) {
segment = conditions.at(index);
}
}
if (!segment) {
SetSegmentValueError(obs_module_text(
"AdvSceneSwitcher.action.variable.invalidSelection"));
return;
}
if (!segment->SupportsVariableValue()) {
std::string type;
QString fmt;
if (_entryData->_type ==
MacroActionVariable::Type::SET_ACTION_VALUE) {
type = MacroActionFactory::GetActionName(
segment->GetId());
fmt = QString(obs_module_text(
"AdvSceneSwitcher.action.variable.actionNoVariableSupport"));
} else if (_entryData->_type ==
MacroActionVariable::Type::SET_CONDITION_VALUE) {
type = MacroConditionFactory::GetConditionName(
segment->GetId());
fmt = QString(obs_module_text(
"AdvSceneSwitcher.action.variable.conditionNoVariableSupport"));
}
SetSegmentValueError(
fmt.arg(QString(obs_module_text(type.c_str()))));
return;
}
_segmentValueStatus->setText(obs_module_text(
"AdvSceneSwitcher.action.variable.currentSegmentValue"));
_segmentValue->show();
_segmentValue->setPlainText(
QString::fromStdString(segment->GetVariableValue()));
adjustSize();
updateGeometry();
}
void MacroActionVariableEdit::MacroSegmentOrderChanged()
{
const QSignalBlocker b(_segmentIdx);
_segmentIdx->setValue(_entryData->GetSegmentIndexValue() + 1);
}
void MacroActionVariableEdit::MarkSelectedSegment()
{
if (switcher->disableHints) {
return;
}
auto m = _entryData->GetMacro();
if (!m) {
return;
}
int index = _entryData->GetSegmentIndexValue();
if (index < 0) {
return;
}
if (_entryData->_type == MacroActionVariable::Type::SET_ACTION_VALUE) {
const auto &actions = m->Actions();
if (index >= actions.size()) {
return;
}
AdvSceneSwitcher::window->HighlightAction(
index, QColor(Qt::lightGray));
} else {
const auto &conditions = m->Conditions();
if (index >= conditions.size()) {
return;
}
AdvSceneSwitcher::window->HighlightCondition(
index, QColor(Qt::lightGray));
}
PulseWidget(_segmentIdx, QColor(Qt::lightGray), QColor(0, 0, 0, 0),
true);
}
void MacroActionVariableEdit::SetWidgetVisibility()
{
if (!_entryData) {
return;
}
auto type = _entryData->_type;
switch (type) {
case MacroActionVariable::Type::SET:
_variables2->hide();
_strValue->show();
_numValue->hide();
break;
case MacroActionVariable::Type::APPEND:
_variables2->hide();
_strValue->show();
_numValue->hide();
break;
case MacroActionVariable::Type::APPEND_VAR:
_variables2->show();
_strValue->hide();
_numValue->hide();
break;
case MacroActionVariable::Type::INCREMENT:
_variables2->hide();
_strValue->hide();
_numValue->show();
break;
case MacroActionVariable::Type::DECREMENT:
_variables2->hide();
_strValue->hide();
_numValue->show();
break;
}
_variables2->setVisible(_entryData->_type ==
MacroActionVariable::Type::APPEND_VAR);
_strValue->setVisible(
_entryData->_type ==
MacroActionVariable::Type::SET_FIXED_VALUE ||
_entryData->_type == MacroActionVariable::Type::APPEND);
_numValue->setVisible(
_entryData->_type == MacroActionVariable::Type::INCREMENT ||
_entryData->_type == MacroActionVariable::Type::DECREMENT);
_segmentValueStatus->setVisible(
_entryData->_type ==
MacroActionVariable::Type::SET_ACTION_VALUE ||
_entryData->_type ==
MacroActionVariable::Type::SET_CONDITION_VALUE);
_segmentValue->setVisible(
_entryData->_type ==
MacroActionVariable::Type::SET_ACTION_VALUE ||
_entryData->_type ==
MacroActionVariable::Type::SET_CONDITION_VALUE);
_segmentIdx->setVisible(
_entryData->_type ==
MacroActionVariable::Type::SET_ACTION_VALUE ||
_entryData->_type ==
MacroActionVariable::Type::SET_CONDITION_VALUE);
adjustSize();
updateGeometry();

View File

@ -6,32 +6,41 @@
class MacroActionVariable : public MacroAction {
public:
MacroActionVariable(Macro *m) : MacroAction(m) {}
~MacroActionVariable();
bool PerformAction();
bool Save(obs_data_t *obj) const;
bool Load(obs_data_t *obj);
bool PostLoad() override;
std::string GetShortDesc() const;
std::string GetId() const { return id; };
static std::shared_ptr<MacroAction> Create(Macro *m)
{
return std::make_shared<MacroActionVariable>(m);
}
void SetSegmentIndexValue(int);
int GetSegmentIndexValue() const;
enum class Type {
SET,
SET_FIXED_VALUE,
APPEND,
APPEND_VAR,
INCREMENT,
DECREMENT,
//...
SET_CONDITION_VALUE,
SET_ACTION_VALUE,
};
Type _type = Type::SET;
Type _type = Type::SET_FIXED_VALUE;
std::string _variableName = "";
std::string _variable2Name = "";
std::string _strValue = "";
double _numValue = 0;
private:
void DecrementCurrentSegmentVariableRef();
std::weak_ptr<MacroSegment> _macroSegment;
int _segmentIdxLoadValue = -1;
static bool _registered;
static const std::string id;
};
@ -58,6 +67,9 @@ private slots:
void ActionChanged(int);
void StrValueChanged();
void NumValueChanged(double);
void SegmentIndexChanged(int val);
void UpdateSegmentVariableValue();
void MacroSegmentOrderChanged();
signals:
void HeaderInfoChanged(const QString &);
@ -67,11 +79,17 @@ protected:
VariableSelection *_variables2;
QComboBox *_actions;
ResizingPlainTextEdit *_strValue;
QSpinBox *_segmentIdx;
QDoubleSpinBox *_numValue;
QLabel *_segmentValueStatus;
ResizingPlainTextEdit *_segmentValue;
std::shared_ptr<MacroActionVariable> _entryData;
private:
void MarkSelectedSegment();
void SetWidgetVisibility();
void SetSegmentValueError(const QString &);
QTimer _timer;
bool _loading = true;
};