mirror of
https://github.com/WarmUpTill/SceneSwitcher.git
synced 2026-03-21 17:34:57 -05:00
Refactor DurationModifier to enable testing
This commit is contained in:
parent
d4025214e5
commit
f9730b1bc2
|
|
@ -165,6 +165,8 @@ target_sources(
|
|||
lib/utils/double-slider.hpp
|
||||
lib/utils/duration-control.cpp
|
||||
lib/utils/duration-control.hpp
|
||||
lib/utils/duration-modifier.cpp
|
||||
lib/utils/duration-modifier.hpp
|
||||
lib/utils/duration.cpp
|
||||
lib/utils/duration.hpp
|
||||
lib/utils/export-symbol-helper.hpp
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
#include "macro-condition.hpp"
|
||||
#include "macro-condition-factory.hpp"
|
||||
#include "filter-combo-box.hpp"
|
||||
#include "duration-control.hpp"
|
||||
|
||||
#include <memory>
|
||||
|
||||
|
|
|
|||
|
|
@ -2,69 +2,6 @@
|
|||
|
||||
namespace advss {
|
||||
|
||||
void DurationModifier::Save(obs_data_t *obj, const char *condName,
|
||||
const char *duration) const
|
||||
{
|
||||
obs_data_set_int(obj, condName, static_cast<int>(_type));
|
||||
_dur.Save(obj, duration);
|
||||
}
|
||||
|
||||
void DurationModifier::Load(obs_data_t *obj, const char *condName,
|
||||
const char *duration)
|
||||
{
|
||||
// For backwards compatibility 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, duration)) {
|
||||
obs_data_set_int(obj, condName, static_cast<int>(Type::MORE));
|
||||
}
|
||||
|
||||
_type = static_cast<Type>(obs_data_get_int(obj, condName));
|
||||
_dur.Load(obj, duration);
|
||||
|
||||
// TODO: remove this fallback
|
||||
if (obs_data_has_user_value(obj, "displayUnit")) {
|
||||
_dur.SetUnit(static_cast<Duration::Unit>(
|
||||
obs_data_get_int(obj, "displayUnit")));
|
||||
}
|
||||
}
|
||||
|
||||
bool DurationModifier::DurationReached()
|
||||
{
|
||||
switch (_type) {
|
||||
case DurationModifier::Type::NONE:
|
||||
return true;
|
||||
break;
|
||||
case DurationModifier::Type::MORE:
|
||||
return _dur.DurationReached();
|
||||
break;
|
||||
case DurationModifier::Type::EQUAL:
|
||||
if (_dur.DurationReached() && !_timeReached) {
|
||||
_timeReached = true;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case DurationModifier::Type::LESS:
|
||||
return !_dur.DurationReached();
|
||||
break;
|
||||
case DurationModifier::Type::WITHIN:
|
||||
if (_dur.IsReset()) {
|
||||
return false;
|
||||
}
|
||||
return !_dur.DurationReached();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void DurationModifier::Reset()
|
||||
{
|
||||
_timeReached = false;
|
||||
_dur.Reset();
|
||||
}
|
||||
|
||||
MacroCondition::MacroCondition(Macro *m, bool supportsVariableValue)
|
||||
: MacroSegment(m, supportsVariableValue)
|
||||
{
|
||||
|
|
@ -75,14 +12,7 @@ bool MacroCondition::Save(obs_data_t *obj) const
|
|||
MacroSegment::Save(obj);
|
||||
obs_data_set_string(obj, "id", GetId().c_str());
|
||||
_logic.Save(obj, "logic");
|
||||
|
||||
// To avoid conflicts with conditions which also use the Duration class
|
||||
// save the duration modifier in a separate obj
|
||||
auto durObj = obs_data_create();
|
||||
_duration.Save(durObj);
|
||||
obs_data_set_obj(obj, "durationModifier", durObj);
|
||||
obs_data_release(durObj);
|
||||
|
||||
_durationModifier.Save(obj);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -90,14 +20,7 @@ bool MacroCondition::Load(obs_data_t *obj)
|
|||
{
|
||||
MacroSegment::Load(obj);
|
||||
_logic.Load(obj, "logic");
|
||||
if (obs_data_has_user_value(obj, "durationModifier")) {
|
||||
auto durObj = obs_data_get_obj(obj, "durationModifier");
|
||||
_duration.Load(durObj);
|
||||
obs_data_release(durObj);
|
||||
} else {
|
||||
// For backwards compatibility
|
||||
_duration.Load(obj);
|
||||
}
|
||||
_durationModifier.Load(obj);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -124,44 +47,28 @@ void MacroCondition::ValidateLogicSelection(bool isRootCondition,
|
|||
|
||||
void MacroCondition::ResetDuration()
|
||||
{
|
||||
_duration.Reset();
|
||||
_durationModifier.ResetDuration();
|
||||
}
|
||||
|
||||
void MacroCondition::CheckDurationModifier(bool &val)
|
||||
bool MacroCondition::CheckDurationModifier(bool conditionValue)
|
||||
{
|
||||
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:
|
||||
val = val && _duration.DurationReached();
|
||||
return;
|
||||
case DurationModifier::Type::WITHIN:
|
||||
if (val) {
|
||||
_duration.SetTimeRemaining(
|
||||
_duration.GetDuration().Seconds());
|
||||
}
|
||||
val = val || _duration.DurationReached();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return _durationModifier.CheckConditionWithDurationModifier(
|
||||
conditionValue);
|
||||
}
|
||||
|
||||
DurationModifier MacroCondition::GetDurationModifier() const
|
||||
{
|
||||
return _durationModifier;
|
||||
}
|
||||
|
||||
void MacroCondition::SetDurationModifier(DurationModifier::Type m)
|
||||
{
|
||||
_duration.SetModifier(m);
|
||||
_durationModifier.SetModifier(m);
|
||||
}
|
||||
|
||||
void MacroCondition::SetDuration(const Duration &duration)
|
||||
{
|
||||
_duration.SetValue(duration);
|
||||
_durationModifier.SetDuration(duration);
|
||||
}
|
||||
|
||||
std::string_view MacroCondition::GetDefaultID()
|
||||
|
|
|
|||
|
|
@ -1,40 +1,11 @@
|
|||
#pragma once
|
||||
#include "macro-segment.hpp"
|
||||
#include "condition-logic.hpp"
|
||||
#include "duration-control.hpp"
|
||||
#include "duration-modifier.hpp"
|
||||
#include "macro-ref.hpp"
|
||||
|
||||
namespace advss {
|
||||
|
||||
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 *duration = "seconds") const;
|
||||
void Load(obs_data_t *obj, const char *condName = "time_constraint",
|
||||
const char *duration = "seconds");
|
||||
void SetModifier(Type cond) { _type = cond; }
|
||||
void SetTimeRemaining(const double &val) { _dur.SetTimeRemaining(val); }
|
||||
void SetValue(const Duration &value) { _dur = value; }
|
||||
Type GetType() { return _type; }
|
||||
Duration GetDuration() { return _dur; }
|
||||
bool DurationReached();
|
||||
void Reset();
|
||||
|
||||
private:
|
||||
Type _type = Type::NONE;
|
||||
Duration _dur;
|
||||
bool _timeReached = false;
|
||||
};
|
||||
|
||||
class EXPORT MacroCondition : public MacroSegment {
|
||||
public:
|
||||
MacroCondition(Macro *m, bool supportsVariableValue = false);
|
||||
|
|
@ -42,20 +13,24 @@ public:
|
|||
virtual bool CheckCondition() = 0;
|
||||
virtual bool Save(obs_data_t *obj) const = 0;
|
||||
virtual bool Load(obs_data_t *obj) = 0;
|
||||
|
||||
Logic::Type GetLogicType() const { return _logic.GetType(); }
|
||||
void SetLogicType(const Logic::Type &logic) { _logic.SetType(logic); }
|
||||
|
||||
void ValidateLogicSelection(bool isRootCondition, const char *context);
|
||||
void ResetDuration();
|
||||
void CheckDurationModifier(bool &val);
|
||||
DurationModifier GetDurationModifier() { return _duration; }
|
||||
|
||||
DurationModifier GetDurationModifier() const;
|
||||
void SetDurationModifier(DurationModifier::Type m);
|
||||
void SetDuration(const Duration &duration);
|
||||
|
||||
void ResetDuration();
|
||||
bool CheckDurationModifier(bool conditionValue);
|
||||
|
||||
static std::string_view GetDefaultID();
|
||||
|
||||
private:
|
||||
Logic _logic = Logic(Logic::Type::ROOT_NONE);
|
||||
DurationModifier _duration;
|
||||
DurationModifier _durationModifier;
|
||||
};
|
||||
|
||||
class EXPORT MacroRefCondition : virtual public MacroCondition {
|
||||
|
|
|
|||
|
|
@ -138,7 +138,8 @@ bool Macro::CeckMatch(bool ignorePause)
|
|||
}
|
||||
|
||||
bool conditionMatched = checkCondition(condition);
|
||||
condition->CheckDurationModifier(conditionMatched);
|
||||
conditionMatched =
|
||||
condition->CheckDurationModifier(conditionMatched);
|
||||
|
||||
const auto logicType = condition->GetLogicType();
|
||||
if (logicType == Logic::Type::NONE) {
|
||||
|
|
|
|||
110
lib/utils/duration-modifier.cpp
Normal file
110
lib/utils/duration-modifier.cpp
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
#include "duration-modifier.hpp"
|
||||
|
||||
namespace advss {
|
||||
|
||||
void DurationModifier::Save(obs_data_t *obj, const char *name,
|
||||
const char *duration) const
|
||||
{
|
||||
auto data = obs_data_create();
|
||||
obs_data_set_int(data, name, static_cast<int>(_type));
|
||||
_duration.Save(data, duration);
|
||||
obs_data_set_obj(obj, "durationModifier", data);
|
||||
obs_data_release(data);
|
||||
}
|
||||
|
||||
void DurationModifier::Load(obs_data_t *obj, const char *name,
|
||||
const char *duration)
|
||||
{
|
||||
obs_data_t *data = nullptr;
|
||||
if (obs_data_has_user_value(obj, "durationModifier")) {
|
||||
data = obs_data_get_obj(obj, "durationModifier");
|
||||
} else {
|
||||
// For backwards compatibility
|
||||
obs_data_addref(obj);
|
||||
data = obj;
|
||||
}
|
||||
|
||||
// For backwards compatibility check if duration value exist without
|
||||
// time constraint condition - if so assume DurationCondition::MORE
|
||||
if (!obs_data_has_user_value(data, name) &&
|
||||
obs_data_has_user_value(data, duration)) {
|
||||
obs_data_set_int(data, name, static_cast<int>(Type::MORE));
|
||||
}
|
||||
|
||||
_type = static_cast<Type>(obs_data_get_int(data, name));
|
||||
_duration.Load(data, duration);
|
||||
|
||||
// TODO: remove this fallback
|
||||
if (obs_data_has_user_value(data, "displayUnit")) {
|
||||
_duration.SetUnit(static_cast<Duration::Unit>(
|
||||
obs_data_get_int(data, "displayUnit")));
|
||||
}
|
||||
|
||||
obs_data_release(data);
|
||||
}
|
||||
|
||||
void DurationModifier::SetTimeRemaining(double seconds)
|
||||
{
|
||||
_duration.SetTimeRemaining(seconds);
|
||||
}
|
||||
|
||||
bool DurationModifier::DurationReached()
|
||||
{
|
||||
switch (_type) {
|
||||
case DurationModifier::Type::NONE:
|
||||
return true;
|
||||
case DurationModifier::Type::MORE:
|
||||
return _duration.DurationReached();
|
||||
case DurationModifier::Type::EQUAL:
|
||||
if (_duration.DurationReached() && !_durationWasReached) {
|
||||
_durationWasReached = true;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case DurationModifier::Type::LESS:
|
||||
return !_duration.DurationReached();
|
||||
case DurationModifier::Type::WITHIN:
|
||||
if (_duration.IsReset()) {
|
||||
return false;
|
||||
}
|
||||
return !_duration.DurationReached();
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void DurationModifier::ResetDuration()
|
||||
{
|
||||
_durationWasReached = false;
|
||||
_duration.Reset();
|
||||
}
|
||||
|
||||
bool DurationModifier::CheckConditionWithDurationModifier(bool conditionValue)
|
||||
{
|
||||
if (_type != DurationModifier::Type::WITHIN && !conditionValue) {
|
||||
ResetDuration();
|
||||
}
|
||||
if (_type == DurationModifier::Type::WITHIN && conditionValue) {
|
||||
ResetDuration();
|
||||
}
|
||||
|
||||
switch (_type) {
|
||||
case DurationModifier::Type::NONE:
|
||||
case DurationModifier::Type::MORE:
|
||||
case DurationModifier::Type::EQUAL:
|
||||
case DurationModifier::Type::LESS:
|
||||
return conditionValue && DurationReached();
|
||||
case DurationModifier::Type::WITHIN:
|
||||
if (conditionValue) {
|
||||
SetTimeRemaining(_duration.Seconds());
|
||||
}
|
||||
return conditionValue || DurationReached();
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return conditionValue;
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
31
lib/utils/duration-modifier.hpp
Normal file
31
lib/utils/duration-modifier.hpp
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
#pragma once
|
||||
#include "duration.hpp"
|
||||
|
||||
namespace advss {
|
||||
|
||||
class DurationModifier {
|
||||
public:
|
||||
enum class Type { NONE, MORE, EQUAL, LESS, WITHIN };
|
||||
|
||||
void Save(obs_data_t *obj, const char *name = "time_constraint",
|
||||
const char *duration = "seconds") const;
|
||||
void Load(obs_data_t *obj, const char *name = "time_constraint",
|
||||
const char *duration = "seconds");
|
||||
void SetModifier(Type type) { _type = type; }
|
||||
void SetDuration(const Duration &duration) { _duration = duration; }
|
||||
Type GetType() const { return _type; }
|
||||
Duration GetDuration() const { return _duration; }
|
||||
void ResetDuration();
|
||||
|
||||
bool CheckConditionWithDurationModifier(bool conditionValue);
|
||||
|
||||
private:
|
||||
void SetTimeRemaining(double seconds);
|
||||
bool DurationReached();
|
||||
|
||||
Type _type = Type::NONE;
|
||||
Duration _duration;
|
||||
bool _durationWasReached = false;
|
||||
};
|
||||
|
||||
} // namespace advss
|
||||
|
|
@ -101,7 +101,7 @@ double Duration::TimeRemaining() const
|
|||
|
||||
void Duration::SetTimeRemaining(double remaining)
|
||||
{
|
||||
long long msPassed = (Seconds() - remaining) * 1000;
|
||||
long long msPassed = (long long)((Seconds() - remaining) * 1000);
|
||||
_startTime = std::chrono::high_resolution_clock::now() -
|
||||
std::chrono::milliseconds(msPassed);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user