From a18ca7764abbe24b601885ef06fcc98f0b7ed10b Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Thu, 18 Aug 2016 14:53:00 +0200 Subject: options: factor out connector out of bundle --- options/bundle.cpp | 7 +++++ options/bundle.hpp | 13 +++++++--- options/connector.cpp | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++ options/connector.hpp | 42 ++++++++++++++++++++++++++++++ options/value.hpp | 16 +++++++++--- 5 files changed, 143 insertions(+), 6 deletions(-) create mode 100644 options/connector.cpp create mode 100644 options/connector.hpp 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 #include #include #include +#include #include #include @@ -13,7 +17,6 @@ #include -#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& 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& values = (*it).second; + values.push_back(val); + } + else + { + std::vector 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 +#include +#include +#include +#include + +#include "export.hpp" + +namespace options { + +class base_value; + +namespace detail { + +class OPENTRACK_OPTIONS_EXPORT connector +{ + friend class ::options::base_value; + + std::map> 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 @@ -17,7 +19,7 @@ template<> struct value_type_traits { using type = const QString&; }; template<> struct value_type_traits { using type = const slider_value&; }; template struct value_type_traits> { - using type = const QList::type>::type>&; + using type = const QList&; }; template using value_type_t = typename value_type_traits::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>(datum)); } void store(float datum) @@ -77,6 +81,7 @@ public slots: OPENTRACK_DEFINE_SLOT(const QList&) public slots: virtual void reload() = 0; + virtual void bundle_value_changed() const = 0; }; namespace detail { @@ -159,6 +164,11 @@ public: *this = static_cast(*this); } + void bundle_value_changed() const override + { + emit valueChanged(static_cast>(get())); + } + private: t def; }; -- cgit v1.2.3