diff options
| author | Stanislaw Halik <sthalik@misaki.pl> | 2016-08-18 14:53:00 +0200 | 
|---|---|---|
| committer | Stanislaw Halik <sthalik@misaki.pl> | 2016-08-18 17:05:13 +0200 | 
| commit | a18ca7764abbe24b601885ef06fcc98f0b7ed10b (patch) | |
| tree | 1381ca22c6b2e68f5e43f0443435863eb3578c77 /options | |
| parent | 132a1925340bcd75a88f831a3487044736dccb4a (diff) | |
options: factor out connector out of bundle
Diffstat (limited to 'options')
| -rw-r--r-- | options/bundle.cpp | 7 | ||||
| -rw-r--r-- | options/bundle.hpp | 13 | ||||
| -rw-r--r-- | options/connector.cpp | 71 | ||||
| -rw-r--r-- | options/connector.hpp | 42 | ||||
| -rw-r--r-- | options/value.hpp | 16 | 
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;  };  | 
