Move string and number variables to separate files

This commit is contained in:
WarmUpTill
2023-03-11 14:14:16 +01:00
committed by WarmUpTill
parent 8874eb2b1c
commit b932af1c97
7 changed files with 240 additions and 96 deletions

View File

@@ -286,8 +286,12 @@ target_sources(
src/utils/variable.hpp
src/utils/variable-line-edit.cpp
src/utils/variable-line-edit.hpp
src/utils/variable-number.tpp
src/utils/variable-number.hpp
src/utils/variable-spinbox.cpp
src/utils/variable-spinbox.hpp
src/utils/variable-string.cpp
src/utils/variable-string.hpp
src/utils/variable-text-edit.cpp
src/utils/variable-text-edit.hpp
src/utils/volume-control.cpp

View File

@@ -0,0 +1,35 @@
#pragma once
#include "variable.hpp"
#include <obs.hpp>
template<typename T> class NumberVariable {
public:
NumberVariable() = default;
NumberVariable(T);
void Save(obs_data_t *obj, const char *name) const;
void Load(obs_data_t *obj, const char *name);
T GetValue() const;
T GetFixedValue() const { return _value; }
void SetValue(T val) { _value = val; }
void SetValue(const std::weak_ptr<Variable> &var) { _variable = var; }
operator T() const;
enum class Type { FIXED_VALUE, VARIABLE };
Type GetType() const { return _type; }
bool IsFixedType() const { return _type == Type::FIXED_VALUE; }
std::weak_ptr<Variable> GetVariable() const { return _variable; }
private:
Type _type = Type::FIXED_VALUE;
T _value = {};
std::weak_ptr<Variable> _variable;
friend class GenericVaraiableSpinbox;
friend class VariableSpinBox;
friend class VariableDoubleSpinBox;
};
#include "variable-number.tpp"

View File

@@ -0,0 +1,66 @@
template class NumberVariable<int>;
template class NumberVariable<double>;
template<typename T>
inline NumberVariable<T>::NumberVariable(T value) : _value(value)
{
}
template<typename T>
void NumberVariable<T>::Save(obs_data_t *obj, const char *name) const
{
auto data = obs_data_create();
if constexpr (std::is_same<T, int>::value) {
obs_data_set_int(data, "value", _value);
} else if constexpr (std::is_same<T, double>::value) {
obs_data_set_double(data, "value", _value);
} else {
assert(false);
}
auto var = _variable.lock();
if (var) {
obs_data_set_string(data, "variable", var->Name().c_str());
}
obs_data_set_int(data, "type", static_cast<int>(_type));
obs_data_set_obj(obj, name, data);
obs_data_release(data);
}
template<typename T>
void NumberVariable<T>::Load(obs_data_t *obj, const char *name)
{
auto data = obs_data_get_obj(obj, name);
if constexpr (std::is_same<T, int>::value) {
_value = obs_data_get_int(data, "value");
} else if constexpr (std::is_same<T, double>::value) {
_value = obs_data_get_double(data, "value");
} else {
assert(false);
}
auto variableName = obs_data_get_string(data, "variable");
_variable = GetWeakVariableByName(variableName);
_type = static_cast<Type>(obs_data_get_int(data, "type"));
obs_data_release(data);
}
template<typename T> T NumberVariable<T>::GetValue() const
{
if (_type == Type::VARIABLE) {
auto var = _variable.lock();
if (!var) {
return {};
}
double value;
if (!var->DoubleValue(value)) {
return 0.0;
}
return value;
}
return _value;
}
template<typename T> NumberVariable<T>::operator T() const
{
return GetValue();
}

View File

@@ -0,0 +1,73 @@
#include "variable-string.hpp"
#include <switcher-data-structs.hpp>
#include <utility.hpp>
void StringVariable::Resolve()
{
if (switcher->variables.empty()) {
_resolvedValue = _value;
return;
}
if (_lastResolve == GetLastVariableChangeTime()) {
return;
}
_resolvedValue = SubstitueVariables(_value);
_lastResolve = GetLastVariableChangeTime();
}
StringVariable::operator std::string()
{
Resolve();
return _resolvedValue;
}
StringVariable::operator QVariant() const
{
return QVariant::fromValue<StringVariable>(*this);
}
void StringVariable::operator=(std::string value)
{
_value = value;
_lastResolve = {};
}
void StringVariable::operator=(const char *value)
{
_value = value;
_lastResolve = {};
}
void StringVariable::Load(obs_data_t *obj, const char *name)
{
_value = obs_data_get_string(obj, name);
Resolve();
}
void StringVariable::Save(obs_data_t *obj, const char *name) const
{
obs_data_set_string(obj, name, _value.c_str());
}
const char *StringVariable::c_str()
{
Resolve();
return _resolvedValue.c_str();
}
const char *StringVariable::c_str() const
{
// Just assume that the value was previously resolved already
return _resolvedValue.c_str();
}
std::string SubstitueVariables(std::string str)
{
for (const auto &v : switcher->variables) {
const auto &variable = std::dynamic_pointer_cast<Variable>(v);
const std::string pattern = "${" + variable->Name() + "}";
replaceAll(str, pattern, variable->Value());
}
return str;
}

View File

@@ -0,0 +1,37 @@
#pragma once
#include "variable.hpp"
#include <string>
#include <obs.hpp>
// Helper class which automatically resovles variables contained in strings
// when reading its value as a std::string
class StringVariable {
public:
StringVariable() : _value(""){};
StringVariable(std::string str) : _value(std::move(str)){};
StringVariable(const char *str) : _value(str){};
operator std::string();
operator QVariant() const;
void operator=(std::string);
void operator=(const char *value);
const char *c_str();
const char *c_str() const;
const std::string &UnresolvedValue() const { return _value; }
void Load(obs_data_t *obj, const char *name);
void Save(obs_data_t *obj, const char *name) const;
private:
void Resolve();
std::string _value = "";
std::string _resolvedValue = "";
std::chrono::high_resolution_clock::time_point _lastResolve{};
};
Q_DECLARE_METATYPE(StringVariable);
std::string SubstitueVariables(std::string str);

View File

@@ -4,9 +4,14 @@
#include <switcher-data-structs.hpp>
// Keep track of the last time a variable was changed to save some work when
// when resolving strings containing variables
// when resolving strings containing variables, etc.
static std::chrono::high_resolution_clock::time_point lastVariableChange{};
std::chrono::high_resolution_clock::time_point GetLastVariableChangeTime()
{
return lastVariableChange;
}
Variable::Variable() : Item()
{
lastVariableChange = std::chrono::high_resolution_clock::now();
@@ -102,73 +107,13 @@ QStringList GetVariablesNameList()
return list;
}
void VariableResolvingString::Resolve()
std::string GetWeakVariableName(std::weak_ptr<Variable> var_)
{
if (switcher->variables.empty()) {
_resolvedValue = _value;
return;
auto var = var_.lock();
if (!var) {
return "invalid variable selection";
}
if (_lastResolve == lastVariableChange) {
return;
}
_resolvedValue = SubstitueVariables(_value);
_lastResolve = lastVariableChange;
}
VariableResolvingString::operator std::string()
{
Resolve();
return _resolvedValue;
}
VariableResolvingString::operator QVariant() const
{
return QVariant::fromValue<VariableResolvingString>(*this);
}
void VariableResolvingString::operator=(std::string value)
{
_value = value;
_lastResolve = {};
}
void VariableResolvingString::operator=(const char *value)
{
_value = value;
_lastResolve = {};
}
void VariableResolvingString::Load(obs_data_t *obj, const char *name)
{
_value = obs_data_get_string(obj, name);
Resolve();
}
void VariableResolvingString::Save(obs_data_t *obj, const char *name) const
{
obs_data_set_string(obj, name, _value.c_str());
}
const char *VariableResolvingString::c_str()
{
Resolve();
return _resolvedValue.c_str();
}
const char *VariableResolvingString::c_str() const
{
// Just assume that the value was previously resolved already
return _resolvedValue.c_str();
}
std::string SubstitueVariables(std::string str)
{
for (const auto &v : switcher->variables) {
const auto &variable = std::dynamic_pointer_cast<Variable>(v);
const std::string pattern = "${" + variable->Name() + "}";
replaceAll(str, pattern, variable->Value());
}
return str;
return var->Name();
}
void SwitcherData::saveVariables(obs_data_t *obj)
@@ -329,3 +274,14 @@ void VariableSelection::SetVariable(const std::string &variable)
_selection->setCurrentIndex(0);
}
}
void VariableSelection::SetVariable(const std::weak_ptr<Variable> &variable_)
{
const QSignalBlocker blocker(_selection);
auto var = variable_.lock();
if (var) {
SetVariable(var->Name());
} else {
_selection->setCurrentIndex(0);
}
}

View File

@@ -39,41 +39,13 @@ private:
friend VariableSettingsDialog;
};
// Helper class which automatically resovles variables contained in strings
// when reading its value as a std::string
class VariableResolvingString {
public:
VariableResolvingString() : _value(""){};
VariableResolvingString(std::string str) : _value(std::move(str)){};
VariableResolvingString(const char *str) : _value(str){};
operator std::string();
operator QVariant() const;
void operator=(std::string);
void operator=(const char *value);
const char *c_str();
const char *c_str() const;
const std::string &UnresolvedValue() const { return _value; }
void Load(obs_data_t *obj, const char *name);
void Save(obs_data_t *obj, const char *name) const;
private:
void Resolve();
std::string _value = "";
std::string _resolvedValue = "";
std::chrono::high_resolution_clock::time_point _lastResolve{};
};
Q_DECLARE_METATYPE(VariableResolvingString);
Variable *GetVariableByName(const std::string &name);
Variable *GetVariableByQString(const QString &name);
std::weak_ptr<Variable> GetWeakVariableByName(const std::string &name);
std::weak_ptr<Variable> GetWeakVariableByQString(const QString &name);
QStringList GetVariablesNameList();
std::string SubstitueVariables(std::string str);
std::string GetWeakVariableName(std::weak_ptr<Variable>);
std::chrono::high_resolution_clock::time_point GetLastVariableChangeTime();
class VariableSettingsDialog : public ItemSettingsDialog {
Q_OBJECT
@@ -97,4 +69,5 @@ class VariableSelection : public ItemSelection {
public:
VariableSelection(QWidget *parent = 0);
void SetVariable(const std::string &);
void SetVariable(const std::weak_ptr<Variable> &);
};