mirror of
https://github.com/WarmUpTill/SceneSwitcher.git
synced 2026-06-18 06:40:31 -05:00
Rework time restriction to support "within" duration modifier
Also renamed duration constraint to duration modifier
This commit is contained in:
parent
92b6a057f6
commit
8da1e3ad40
|
|
@ -129,7 +129,7 @@ AdvSceneSwitcher.condition.file.entry.line3="{{useRegex}} {{checkModificationDat
|
|||
AdvSceneSwitcher.condition.media="Media"
|
||||
AdvSceneSwitcher.condition.media.anyOnScene="Any media source on"
|
||||
AdvSceneSwitcher.condition.media.allOnScene="All media sources on"
|
||||
AdvSceneSwitcher.condition.media.matchOnChange="Only match on change (Note: This option will be removed in a future version - please use time constraints instead)"
|
||||
AdvSceneSwitcher.condition.media.matchOnChange="Only match on change (Note: This option will be removed in a future version - please use duration modifiers instead)"
|
||||
AdvSceneSwitcher.condition.media.inconsistencyInfo="Unfortunately not all media source types behave the same (e.g. Media Source vs. VLC Video Source \"Stopped\" state).\nSo please experiment what works for your setup!"
|
||||
AdvSceneSwitcher.condition.media.entry="{{mediaSources}}{{scenes}} state is {{states}} and {{timeRestrictions}} {{time}}"
|
||||
AdvSceneSwitcher.condition.video="Video"
|
||||
|
|
@ -763,7 +763,8 @@ AdvSceneSwitcher.unit.milliseconds="milliseconds"
|
|||
AdvSceneSwitcher.unit.secends="seconds"
|
||||
AdvSceneSwitcher.unit.minutes="minutes"
|
||||
AdvSceneSwitcher.unit.hours="hours"
|
||||
AdvSceneSwitcher.duration.condition.none="No time constraint"
|
||||
AdvSceneSwitcher.duration.condition.none="No duration modifier"
|
||||
AdvSceneSwitcher.duration.condition.more="For at least"
|
||||
AdvSceneSwitcher.duration.condition.equal="For exactly"
|
||||
AdvSceneSwitcher.duration.condition.less="For at most"
|
||||
AdvSceneSwitcher.duration.condition.within="Within the last"
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ void Duration::Load(obs_data_t *obj, const char *secondsName,
|
|||
|
||||
bool Duration::DurationReached()
|
||||
{
|
||||
if (_startTime.time_since_epoch().count() == 0) {
|
||||
if (IsReset()) {
|
||||
_startTime = std::chrono::high_resolution_clock::now();
|
||||
}
|
||||
|
||||
|
|
@ -32,9 +32,14 @@ bool Duration::DurationReached()
|
|||
return runTime.count() >= seconds * 1000;
|
||||
}
|
||||
|
||||
bool Duration::IsReset()
|
||||
{
|
||||
return _startTime.time_since_epoch().count() == 0;
|
||||
}
|
||||
|
||||
double Duration::TimeRemaining()
|
||||
{
|
||||
if (_startTime.time_since_epoch().count() == 0) {
|
||||
if (IsReset()) {
|
||||
return seconds;
|
||||
}
|
||||
auto runTime = std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ public:
|
|||
const char *unitName = "displayUnit");
|
||||
|
||||
bool DurationReached();
|
||||
bool IsReset();
|
||||
double TimeRemaining();
|
||||
void SetTimeRemaining(double);
|
||||
void Reset();
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ struct MacroConditionInfo {
|
|||
TCreateMethod _createFunc = nullptr;
|
||||
TCreateWidgetMethod _createWidgetFunc = nullptr;
|
||||
std::string _name;
|
||||
bool _useDurationConstraint = true;
|
||||
bool _useDurationModifier = true;
|
||||
};
|
||||
|
||||
class MacroConditionFactory {
|
||||
|
|
@ -24,27 +24,27 @@ public:
|
|||
static auto GetConditionTypes() { return _methods; }
|
||||
static std::string GetConditionName(const std::string &);
|
||||
static std::string GetIdByName(const QString &name);
|
||||
static bool UsesDurationConstraint(const std::string &id);
|
||||
static bool UsesDurationModifier(const std::string &id);
|
||||
|
||||
private:
|
||||
static std::map<std::string, MacroConditionInfo> _methods;
|
||||
};
|
||||
|
||||
class DurationConstraintEdit : public QWidget {
|
||||
class DurationModifierEdit : public QWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
DurationConstraintEdit(QWidget *parent = nullptr);
|
||||
void SetValue(DurationConstraint &value);
|
||||
DurationModifierEdit(QWidget *parent = nullptr);
|
||||
void SetValue(DurationModifier &value);
|
||||
void SetUnit(DurationUnit u);
|
||||
void SetDuration(const Duration &d);
|
||||
|
||||
private slots:
|
||||
void _ConditionChanged(int value);
|
||||
void _ModifierChanged(int value);
|
||||
void ToggleClicked();
|
||||
signals:
|
||||
void DurationChanged(double value);
|
||||
void UnitChanged(DurationUnit u);
|
||||
void ConditionChanged(DurationCondition value);
|
||||
void ModifierChanged(DurationModifier::Type value);
|
||||
|
||||
private:
|
||||
void Collapse(bool collapse);
|
||||
|
|
@ -70,7 +70,7 @@ private slots:
|
|||
void LogicSelectionChanged(int idx);
|
||||
void ConditionSelectionChanged(const QString &text);
|
||||
void DurationChanged(double seconds);
|
||||
void DurationConditionChanged(DurationCondition cond);
|
||||
void DurationModifierChanged(DurationModifier::Type m);
|
||||
void DurationUnitChanged(DurationUnit unit);
|
||||
|
||||
private:
|
||||
|
|
@ -79,7 +79,7 @@ private:
|
|||
|
||||
QComboBox *_logicSelection;
|
||||
QComboBox *_conditionSelection;
|
||||
DurationConstraintEdit *_dur;
|
||||
DurationModifierEdit *_dur;
|
||||
|
||||
std::shared_ptr<MacroCondition> *_entryData;
|
||||
bool _isRoot = true;
|
||||
|
|
|
|||
|
|
@ -27,32 +27,34 @@ struct LogicTypeInfo {
|
|||
std::string _name;
|
||||
};
|
||||
|
||||
enum class DurationCondition {
|
||||
NONE,
|
||||
MORE,
|
||||
EQUAL,
|
||||
LESS,
|
||||
};
|
||||
|
||||
class DurationConstraint {
|
||||
class DurationModifier {
|
||||
public:
|
||||
enum class Type {
|
||||
NONE,
|
||||
MORE,
|
||||
EQUAL,
|
||||
LESS,
|
||||
WITHIN, // Condition will remain true for a set a amount of time
|
||||
// regardless of current state
|
||||
};
|
||||
|
||||
void Save(obs_data_t *obj, const char *condName = "time_constraint",
|
||||
const char *secondsName = "seconds",
|
||||
const char *unitName = "displayUnit");
|
||||
void Load(obs_data_t *obj, const char *condName = "time_constraint",
|
||||
const char *secondsName = "seconds",
|
||||
const char *unitName = "displayUnit");
|
||||
void SetCondition(DurationCondition cond) { _type = cond; }
|
||||
void SetDuration(const Duration &dur) { _dur = dur; }
|
||||
void SetModifier(Type cond) { _type = cond; }
|
||||
void SetTimeRemaining(const double &val) { _dur.SetTimeRemaining(val); }
|
||||
void SetValue(double value) { _dur.seconds = value; }
|
||||
void SetUnit(DurationUnit u) { _dur.displayUnit = u; }
|
||||
DurationCondition GetCondition() { return _type; }
|
||||
Type GetType() { return _type; }
|
||||
Duration GetDuration() { return _dur; }
|
||||
bool DurationReached();
|
||||
void Reset();
|
||||
|
||||
private:
|
||||
DurationCondition _type = DurationCondition::NONE;
|
||||
Type _type = Type::NONE;
|
||||
Duration _dur;
|
||||
bool _timeReached = false;
|
||||
};
|
||||
|
|
@ -66,18 +68,16 @@ public:
|
|||
LogicType GetLogicType() { return _logic; }
|
||||
void SetLogicType(LogicType logic) { _logic = logic; }
|
||||
static const std::map<LogicType, LogicTypeInfo> logicTypes;
|
||||
|
||||
bool DurationReached() { return _duration.DurationReached(); }
|
||||
void ResetDuration() { _duration.Reset(); }
|
||||
DurationConstraint GetDurationConstraint() { return _duration; }
|
||||
void SetDurationConstraint(const DurationConstraint &dur);
|
||||
void SetDurationCondition(DurationCondition cond);
|
||||
void ResetDuration();
|
||||
void CheckDurationModifier(bool &val);
|
||||
DurationModifier GetDurationModifier() { return _duration; }
|
||||
void SetDurationModifier(DurationModifier::Type m);
|
||||
void SetDurationUnit(DurationUnit u);
|
||||
void SetDuration(double seconds);
|
||||
|
||||
private:
|
||||
LogicType _logic = LogicType::ROOT_NONE;
|
||||
DurationConstraint _duration;
|
||||
DurationModifier _duration;
|
||||
};
|
||||
|
||||
class MacroRefCondition : public MacroCondition {
|
||||
|
|
|
|||
|
|
@ -53,10 +53,10 @@ std::string MacroConditionFactory::GetIdByName(const QString &name)
|
|||
return "";
|
||||
}
|
||||
|
||||
bool MacroConditionFactory::UsesDurationConstraint(const std::string &id)
|
||||
bool MacroConditionFactory::UsesDurationModifier(const std::string &id)
|
||||
{
|
||||
if (auto it = _methods.find(id); it != _methods.end()) {
|
||||
return it->second._useDurationConstraint;
|
||||
return it->second._useDurationModifier;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
@ -97,7 +97,7 @@ static inline void populateConditionSelection(QComboBox *list)
|
|||
list->model()->sort(0);
|
||||
}
|
||||
|
||||
static void populateDurationConstraintTypes(QComboBox *list)
|
||||
static void populateDurationModifierTypes(QComboBox *list)
|
||||
{
|
||||
list->addItem(
|
||||
obs_module_text("AdvSceneSwitcher.duration.condition.none"));
|
||||
|
|
@ -107,9 +107,11 @@ static void populateDurationConstraintTypes(QComboBox *list)
|
|||
obs_module_text("AdvSceneSwitcher.duration.condition.equal"));
|
||||
list->addItem(
|
||||
obs_module_text("AdvSceneSwitcher.duration.condition.less"));
|
||||
list->addItem(
|
||||
obs_module_text("AdvSceneSwitcher.duration.condition.within"));
|
||||
}
|
||||
|
||||
DurationConstraintEdit::DurationConstraintEdit(QWidget *parent)
|
||||
DurationModifierEdit::DurationModifierEdit(QWidget *parent)
|
||||
{
|
||||
_condition = new QComboBox(parent);
|
||||
_duration = new DurationSelection(parent);
|
||||
|
|
@ -117,13 +119,13 @@ DurationConstraintEdit::DurationConstraintEdit(QWidget *parent)
|
|||
_toggle->setMaximumSize(22, 22);
|
||||
_toggle->setIcon(
|
||||
QIcon(QString::fromStdString(getDataFilePath("res/time.svg"))));
|
||||
populateDurationConstraintTypes(_condition);
|
||||
populateDurationModifierTypes(_condition);
|
||||
QWidget::connect(_condition, SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(_ConditionChanged(int)));
|
||||
SLOT(_ModifierChanged(int)));
|
||||
QObject::connect(_duration, &DurationSelection::DurationChanged, this,
|
||||
&DurationConstraintEdit::DurationChanged);
|
||||
&DurationModifierEdit::DurationChanged);
|
||||
QObject::connect(_duration, &DurationSelection::UnitChanged, this,
|
||||
&DurationConstraintEdit::UnitChanged);
|
||||
&DurationModifierEdit::UnitChanged);
|
||||
QWidget::connect(_toggle, SIGNAL(clicked()), this,
|
||||
SLOT(ToggleClicked()));
|
||||
|
||||
|
|
@ -137,36 +139,36 @@ DurationConstraintEdit::DurationConstraintEdit(QWidget *parent)
|
|||
Collapse(true);
|
||||
}
|
||||
|
||||
void DurationConstraintEdit::SetValue(DurationConstraint &value)
|
||||
void DurationModifierEdit::SetValue(DurationModifier &value)
|
||||
{
|
||||
_duration->SetDuration(value.GetDuration());
|
||||
_condition->setCurrentIndex(static_cast<int>(value.GetCondition()));
|
||||
_duration->setVisible(value.GetCondition() != DurationCondition::NONE);
|
||||
_condition->setCurrentIndex(static_cast<int>(value.GetType()));
|
||||
_duration->setVisible(value.GetType() != DurationModifier::Type::NONE);
|
||||
}
|
||||
|
||||
void DurationConstraintEdit::SetUnit(DurationUnit u)
|
||||
void DurationModifierEdit::SetUnit(DurationUnit u)
|
||||
{
|
||||
_duration->SetUnit(u);
|
||||
}
|
||||
|
||||
void DurationConstraintEdit::SetDuration(const Duration &d)
|
||||
void DurationModifierEdit::SetDuration(const Duration &d)
|
||||
{
|
||||
_duration->SetDuration(d);
|
||||
}
|
||||
|
||||
void DurationConstraintEdit::_ConditionChanged(int value)
|
||||
void DurationModifierEdit::_ModifierChanged(int value)
|
||||
{
|
||||
auto cond = static_cast<DurationCondition>(value);
|
||||
Collapse(cond == DurationCondition::NONE);
|
||||
emit ConditionChanged(cond);
|
||||
auto m = static_cast<DurationModifier::Type>(value);
|
||||
Collapse(m == DurationModifier::Type::NONE);
|
||||
emit ModifierChanged(m);
|
||||
}
|
||||
|
||||
void DurationConstraintEdit::ToggleClicked()
|
||||
void DurationModifierEdit::ToggleClicked()
|
||||
{
|
||||
Collapse(false);
|
||||
}
|
||||
|
||||
void DurationConstraintEdit::Collapse(bool collapse)
|
||||
void DurationModifierEdit::Collapse(bool collapse)
|
||||
{
|
||||
_toggle->setVisible(collapse);
|
||||
_duration->setVisible(!collapse);
|
||||
|
|
@ -180,7 +182,7 @@ MacroConditionEdit::MacroConditionEdit(
|
|||
parent),
|
||||
_logicSelection(new QComboBox()),
|
||||
_conditionSelection(new QComboBox()),
|
||||
_dur(new DurationConstraintEdit()),
|
||||
_dur(new DurationModifierEdit()),
|
||||
_entryData(entryData),
|
||||
_isRoot(root)
|
||||
{
|
||||
|
|
@ -193,9 +195,9 @@ MacroConditionEdit::MacroConditionEdit(
|
|||
SLOT(DurationChanged(double)));
|
||||
QWidget::connect(_dur, SIGNAL(UnitChanged(DurationUnit)), this,
|
||||
SLOT(DurationUnitChanged(DurationUnit)));
|
||||
QWidget::connect(_dur, SIGNAL(ConditionChanged(DurationCondition)),
|
||||
QWidget::connect(_dur, SIGNAL(ModifierChanged(DurationModifier::Type)),
|
||||
this,
|
||||
SLOT(DurationConditionChanged(DurationCondition)));
|
||||
SLOT(DurationModifierChanged(DurationModifier::Type)));
|
||||
QWidget::connect(window(), SIGNAL(HighlightConditionsChanged(bool)),
|
||||
this, SLOT(EnableHighlight(bool)));
|
||||
|
||||
|
|
@ -277,9 +279,9 @@ void MacroConditionEdit::UpdateEntryData(const std::string &id)
|
|||
SetLogicSelection();
|
||||
_section->SetContent(widget, (*_entryData)->GetCollapsed());
|
||||
|
||||
_dur->setVisible(MacroConditionFactory::UsesDurationConstraint(id));
|
||||
auto constraint = (*_entryData)->GetDurationConstraint();
|
||||
_dur->SetValue(constraint);
|
||||
_dur->setVisible(MacroConditionFactory::UsesDurationModifier(id));
|
||||
auto modifier = (*_entryData)->GetDurationModifier();
|
||||
_dur->SetValue(modifier);
|
||||
SetFocusPolicyOfWidgets();
|
||||
}
|
||||
|
||||
|
|
@ -298,7 +300,7 @@ void MacroConditionEdit::ConditionSelectionChanged(const QString &text)
|
|||
auto macro = _entryData->get()->GetMacro();
|
||||
std::string id = MacroConditionFactory::GetIdByName(text);
|
||||
|
||||
auto temp = DurationConstraint();
|
||||
auto temp = DurationModifier();
|
||||
_dur->SetValue(temp);
|
||||
HeaderInfoChanged("");
|
||||
{
|
||||
|
|
@ -314,7 +316,7 @@ void MacroConditionEdit::ConditionSelectionChanged(const QString &text)
|
|||
QWidget::connect(widget, SIGNAL(HeaderInfoChanged(const QString &)),
|
||||
this, SLOT(HeaderInfoChanged(const QString &)));
|
||||
_section->SetContent(widget);
|
||||
_dur->setVisible(MacroConditionFactory::UsesDurationConstraint(id));
|
||||
_dur->setVisible(MacroConditionFactory::UsesDurationModifier(id));
|
||||
SetFocusPolicyOfWidgets();
|
||||
}
|
||||
|
||||
|
|
@ -328,14 +330,14 @@ void MacroConditionEdit::DurationChanged(double seconds)
|
|||
(*_entryData)->SetDuration(seconds);
|
||||
}
|
||||
|
||||
void MacroConditionEdit::DurationConditionChanged(DurationCondition cond)
|
||||
void MacroConditionEdit::DurationModifierChanged(DurationModifier::Type m)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
(*_entryData)->SetDurationCondition(cond);
|
||||
(*_entryData)->SetDurationModifier(m);
|
||||
}
|
||||
|
||||
void MacroConditionEdit::DurationUnitChanged(DurationUnit unit)
|
||||
|
|
|
|||
|
|
@ -11,44 +11,49 @@ const std::map<LogicType, LogicTypeInfo> MacroCondition::logicTypes = {
|
|||
{LogicType::ROOT_NOT, {"AdvSceneSwitcher.logic.not"}},
|
||||
};
|
||||
|
||||
void DurationConstraint::Save(obs_data_t *obj, const char *condName,
|
||||
const char *secondsName, const char *unitName)
|
||||
void DurationModifier::Save(obs_data_t *obj, const char *condName,
|
||||
const char *secondsName, const char *unitName)
|
||||
{
|
||||
obs_data_set_int(obj, condName, static_cast<int>(_type));
|
||||
_dur.Save(obj, secondsName, unitName);
|
||||
}
|
||||
|
||||
void DurationConstraint::Load(obs_data_t *obj, const char *condName,
|
||||
const char *secondsName, const char *unitName)
|
||||
void DurationModifier::Load(obs_data_t *obj, const char *condName,
|
||||
const char *secondsName, const char *unitName)
|
||||
{
|
||||
// For backwards compatability check if duration value exist without
|
||||
// time constraint condition - if so assume DurationCondition::MORE
|
||||
if (!obs_data_has_user_value(obj, condName) &&
|
||||
obs_data_has_user_value(obj, secondsName)) {
|
||||
obs_data_set_int(obj, condName,
|
||||
static_cast<int>(DurationCondition::MORE));
|
||||
obs_data_set_int(obj, condName, static_cast<int>(Type::MORE));
|
||||
}
|
||||
|
||||
_type = static_cast<DurationCondition>(obs_data_get_int(obj, condName));
|
||||
_type = static_cast<Type>(obs_data_get_int(obj, condName));
|
||||
_dur.Load(obj, secondsName, unitName);
|
||||
}
|
||||
|
||||
bool DurationConstraint::DurationReached()
|
||||
bool DurationModifier::DurationReached()
|
||||
{
|
||||
switch (_type) {
|
||||
case DurationCondition::NONE:
|
||||
case DurationModifier::Type::NONE:
|
||||
return true;
|
||||
break;
|
||||
case DurationCondition::MORE:
|
||||
case DurationModifier::Type::MORE:
|
||||
return _dur.DurationReached();
|
||||
break;
|
||||
case DurationCondition::EQUAL:
|
||||
case DurationModifier::Type::EQUAL:
|
||||
if (_dur.DurationReached() && !_timeReached) {
|
||||
_timeReached = true;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case DurationCondition::LESS:
|
||||
case DurationModifier::Type::LESS:
|
||||
return !_dur.DurationReached();
|
||||
break;
|
||||
case DurationModifier::Type::WITHIN:
|
||||
if (_dur.IsReset()) {
|
||||
return false;
|
||||
}
|
||||
return !_dur.DurationReached();
|
||||
break;
|
||||
default:
|
||||
|
|
@ -57,7 +62,7 @@ bool DurationConstraint::DurationReached()
|
|||
return false;
|
||||
}
|
||||
|
||||
void DurationConstraint::Reset()
|
||||
void DurationModifier::Reset()
|
||||
{
|
||||
_timeReached = false;
|
||||
_dur.Reset();
|
||||
|
|
@ -80,14 +85,44 @@ bool MacroCondition::Load(obs_data_t *obj)
|
|||
return true;
|
||||
}
|
||||
|
||||
void MacroCondition::SetDurationConstraint(const DurationConstraint &dur)
|
||||
void MacroCondition::ResetDuration()
|
||||
{
|
||||
_duration = dur;
|
||||
_duration.Reset();
|
||||
}
|
||||
|
||||
void MacroCondition::SetDurationCondition(DurationCondition cond)
|
||||
void MacroCondition::CheckDurationModifier(bool &val)
|
||||
{
|
||||
_duration.SetCondition(cond);
|
||||
if (_duration.GetType() != DurationModifier::Type::WITHIN && !val) {
|
||||
_duration.Reset();
|
||||
}
|
||||
if (_duration.GetType() == DurationModifier::Type::WITHIN && val) {
|
||||
_duration.Reset();
|
||||
}
|
||||
switch (_duration.GetType()) {
|
||||
case DurationModifier::Type::NONE:
|
||||
case DurationModifier::Type::MORE:
|
||||
case DurationModifier::Type::EQUAL:
|
||||
case DurationModifier::Type::LESS:
|
||||
if (!val) {
|
||||
_duration.Reset();
|
||||
}
|
||||
val = val && _duration.DurationReached();
|
||||
return;
|
||||
case DurationModifier::Type::WITHIN:
|
||||
if (val) {
|
||||
_duration.SetTimeRemaining(
|
||||
_duration.GetDuration().seconds);
|
||||
}
|
||||
val = val || _duration.DurationReached();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void MacroCondition::SetDurationModifier(DurationModifier::Type m)
|
||||
{
|
||||
_duration.SetModifier(m);
|
||||
}
|
||||
|
||||
void MacroCondition::SetDurationUnit(DurationUnit u)
|
||||
|
|
|
|||
|
|
@ -43,10 +43,7 @@ bool Macro::CeckMatch()
|
|||
ms.count(), c->GetId().c_str(), Name().c_str());
|
||||
}
|
||||
|
||||
if (!cond) {
|
||||
c->ResetDuration();
|
||||
}
|
||||
cond = cond && c->DurationReached();
|
||||
c->CheckDurationModifier(cond);
|
||||
|
||||
switch (c->GetLogicType()) {
|
||||
case LogicType::NONE:
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user