summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--options/bundle.cpp7
-rw-r--r--options/bundle.hpp13
-rw-r--r--options/connector.cpp71
-rw-r--r--options/connector.hpp42
-rw-r--r--options/value.hpp16
5 files changed, 143 insertions, 6 deletions
diff --git a/options/bundle.cpp b/options/bundle.cpp
index fa1a214c..a080bb77 100644
--- a/options/bundle.cpp
+++ b/options/bundle.cpp
@@ -1,4 +1,7 @@
#include "bundle.hpp"
+#include "value.hpp"
+
+using options::base_value;
namespace options
{
@@ -20,6 +23,8 @@ void bundle::reload()
QMutexLocker l(&mtx);
saved = group(group_name);
transient = saved;
+
+ connector::notify_all_values();
}
emit reloading();
}
@@ -29,6 +34,8 @@ void bundle::store_kv(const QString& name, const QVariant& datum)
QMutexLocker l(&mtx);
transient.put(name, datum);
+
+ connector::notify_values(name);
}
bool bundle::contains(const QString &name) const
diff --git a/options/bundle.hpp b/options/bundle.hpp
index 0283c911..841df273 100644
--- a/options/bundle.hpp
+++ b/options/bundle.hpp
@@ -1,9 +1,13 @@
#pragma once
+#include "group.hpp"
+#include "connector.hpp"
+
#include <memory>
#include <tuple>
#include <map>
#include <memory>
+#include <vector>
#include <QObject>
#include <QString>
@@ -13,7 +17,6 @@
#include <QDebug>
-#include "group.hpp"
#include "compat/util.hpp"
#include "export.hpp"
@@ -21,21 +24,25 @@ namespace options {
namespace detail {
-class OPENTRACK_OPTIONS_EXPORT bundle final : public QObject
+class OPENTRACK_OPTIONS_EXPORT bundle final : public QObject, public virtual connector
{
Q_OBJECT
-protected:
+private:
QMutex mtx;
const QString group_name;
group saved;
group transient;
+
bundle(const bundle&) = delete;
bundle& operator=(const bundle&) = delete;
+ QMutex* get_mtx() override { return &mtx; }
+
signals:
void reloading();
void saving() const;
public:
bundle(const QString& group_name);
+ ~bundle() override {}
QString name() { return group_name; }
void reload();
void store_kv(const QString& name, const QVariant& datum);
diff --git a/options/connector.cpp b/options/connector.cpp
new file mode 100644
index 00000000..4ba532d4
--- /dev/null
+++ b/options/connector.cpp
@@ -0,0 +1,71 @@
+#include "connector.hpp"
+#include "value.hpp"
+
+namespace options {
+namespace detail {
+
+connector::~connector() {}
+
+void connector::on_bundle_destructed(const QString& name, const base_value* val)
+{
+ QMutexLocker l(get_mtx());
+
+ auto it = connected_values.find(name);
+ if (it != connected_values.end())
+ {
+ std::vector<const base_value*>& values = (*it).second;
+ for (auto it = values.begin(); it != values.end(); )
+ {
+ if (*it == val)
+ {
+ values.erase(it);
+ break;
+ }
+ }
+ }
+}
+
+void connector::on_bundle_created(const QString& name, const base_value* val)
+{
+ QMutexLocker l(get_mtx());
+ auto it = connected_values.find(name);
+
+ if (it != connected_values.end())
+ {
+ std::vector<const base_value*>& values = (*it).second;
+ values.push_back(val);
+ }
+ else
+ {
+ std::vector<const base_value*> vec;
+ vec.push_back(val);
+ connected_values[name] = vec;
+ }
+}
+
+void connector::notify_values(const QString& name) const
+{
+ auto it = connected_values.find(name);
+ if (it != connected_values.end())
+ {
+ for (const base_value* val : (*it).second)
+ {
+ val->bundle_value_changed();
+ }
+ }
+}
+
+void connector::notify_all_values() const
+{
+ for (auto& pair : connected_values)
+ for (const base_value* val : pair.second)
+ val->bundle_value_changed();
+}
+
+connector::connector()
+{
+}
+
+}
+
+}
diff --git a/options/connector.hpp b/options/connector.hpp
new file mode 100644
index 00000000..dea9fd0f
--- /dev/null
+++ b/options/connector.hpp
@@ -0,0 +1,42 @@
+#pragma once
+
+#include <map>
+#include <vector>
+#include <QString>
+#include <QMutex>
+#include <QMutexLocker>
+
+#include "export.hpp"
+
+namespace options {
+
+class base_value;
+
+namespace detail {
+
+class OPENTRACK_OPTIONS_EXPORT connector
+{
+ friend class ::options::base_value;
+
+ std::map<QString, std::vector<const base_value*>> connected_values;
+
+ void on_bundle_destructed(const QString& name, const base_value* val);
+ void on_bundle_created(const QString& name, const base_value* val);
+
+protected:
+ void notify_values(const QString& name) const;
+ void notify_all_values() const;
+ virtual QMutex* get_mtx() = 0;
+
+public:
+ connector();
+ virtual ~connector();
+
+ connector(const connector&) = default;
+ connector& operator=(const connector&) = default;
+ connector(connector&&) = default;
+ connector& operator=(connector&&) = default;
+};
+
+}
+}
diff --git a/options/value.hpp b/options/value.hpp
index d09924c5..4d067af1 100644
--- a/options/value.hpp
+++ b/options/value.hpp
@@ -1,5 +1,7 @@
#pragma once
+#include "connector.hpp"
+
#include "bundle.hpp"
#include "slider.hpp"
#include <type_traits>
@@ -17,7 +19,7 @@ template<> struct value_type_traits<QString> { using type = const QString&; };
template<> struct value_type_traits<slider_value> { using type = const slider_value&; };
template<typename u> struct value_type_traits<QList<u>>
{
- using type = const QList<typename std::remove_const<typename std::remove_reference<u>::type>::type>&;
+ using type = const QList<u>&;
};
template<typename t> using value_type_t = typename value_type_traits<t>::type;
}
@@ -27,7 +29,10 @@ class OPENTRACK_OPTIONS_EXPORT base_value : public QObject
Q_OBJECT
public:
QString name() const { return self_name; }
- base_value(bundle b, const QString& name) : b(b), self_name(name) {}
+ base_value(bundle b, const QString& name) : b(b), self_name(name)
+ {
+ b->on_bundle_created(name, this);
+ }
signals:
OPENTRACK_DEFINE_SIGNAL(double);
OPENTRACK_DEFINE_SIGNAL(float);
@@ -52,7 +57,6 @@ protected:
void store(const t& datum)
{
b->store_kv(self_name, QVariant::fromValue(datum));
- emit valueChanged(static_cast<detail::value_type_t<t>>(datum));
}
void store(float datum)
@@ -77,6 +81,7 @@ public slots:
OPENTRACK_DEFINE_SLOT(const QList<QPointF>&)
public slots:
virtual void reload() = 0;
+ virtual void bundle_value_changed() const = 0;
};
namespace detail {
@@ -159,6 +164,11 @@ public:
*this = static_cast<t>(*this);
}
+ void bundle_value_changed() const override
+ {
+ emit valueChanged(static_cast<detail::value_type_t<t>>(get()));
+ }
+
private:
t def;
};