diff options
| author | Stanislaw Halik <sthalik@misaki.pl> | 2017-05-06 13:15:16 +0200 | 
|---|---|---|
| committer | Stanislaw Halik <sthalik@misaki.pl> | 2017-05-10 11:19:22 +0200 | 
| commit | 87c09c0ab5e1334e9877ee6fd7adeb1eb70d5929 (patch) | |
| tree | 3f407f9d0fc947427729913cf60e2e5f9b962ce0 /options | |
| parent | 604914db84d0468c6c8d04dfe6491e3c15b670f7 (diff) | |
options: don't create QSettings all the time
Update usages.
Diffstat (limited to 'options')
| -rw-r--r-- | options/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | options/bundle.cpp | 25 | ||||
| -rw-r--r-- | options/bundle.hpp | 3 | ||||
| -rw-r--r-- | options/group.cpp | 97 | ||||
| -rw-r--r-- | options/group.hpp | 35 | 
5 files changed, 115 insertions, 46 deletions
| diff --git a/options/CMakeLists.txt b/options/CMakeLists.txt index cbebeb87..0c4b53a5 100644 --- a/options/CMakeLists.txt +++ b/options/CMakeLists.txt @@ -2,3 +2,4 @@ otr_module(options NO-COMPAT BIN)  if(NOT WIN32 AND NOT APPLE)      target_link_libraries(opentrack-options rt)  endif() +target_link_libraries(opentrack-options opentrack-compat) diff --git a/options/bundle.cpp b/options/bundle.cpp index 4d44521f..c78df274 100644 --- a/options/bundle.cpp +++ b/options/bundle.cpp @@ -31,12 +31,12 @@ bundle::~bundle()  {  } -void bundle::reload(std::shared_ptr<QSettings> settings) +void bundle::reload()  {      if (group_name.size())      {          QMutexLocker l(&mtx); -        saved = group(group_name, settings); +        saved = group(group_name);          const bool has_changes = is_modified();          transient = saved; @@ -51,7 +51,12 @@ void bundle::reload(std::shared_ptr<QSettings> settings)  void bundle::set_all_to_default()  { +    QMutexLocker l(&mtx); +      forall([](const QString&, base_value* val) { set_base_value_to_default(val); }); + +    if (is_modified()) +        group::mark_ini_modified();  }  void bundle::store_kv(const QString& name, const QVariant& datum) @@ -72,10 +77,10 @@ bool bundle::contains(const QString &name) const      return transient.contains(name);  } -void bundle::save_deferred(QSettings& s) +void bundle::save()  {      if (QThread::currentThread() != qApp->thread()) -        qCritical() << "group::save - current thread not ui thread"; +        qDebug() << "group::save - current thread not ui thread";      if (group_name.size() == 0)          return; @@ -84,12 +89,13 @@ void bundle::save_deferred(QSettings& s)      {          QMutexLocker l(&mtx); +          if (is_modified())          {              //qDebug() << "bundle" << group_name << "changed, saving";              modified_ = true;              saved = transient; -            saved.save_deferred(s); +            saved.save();          }      } @@ -97,11 +103,6 @@ void bundle::save_deferred(QSettings& s)          emit saving();  } -void bundle::save() -{ -    save_deferred(*group::ini_file()); -} -  bool bundle::is_modified() const  {      QMutexLocker l(mtx); @@ -134,8 +135,6 @@ void bundler::after_profile_changed_()  {      QMutexLocker l(&implsgl_mtx); -    std::shared_ptr<QSettings> s = group::ini_file(); -      for (auto& kv : implsgl_data)      {          weak bundle = kv.second; @@ -143,7 +142,7 @@ void bundler::after_profile_changed_()          if (bundle_)          {              //qDebug() << "bundle: reverting" << kv.first << "due to profile change"; -            bundle_->reload(s); +            bundle_->reload();          }      }  } diff --git a/options/bundle.hpp b/options/bundle.hpp index f05999a7..63ee82d0 100644 --- a/options/bundle.hpp +++ b/options/bundle.hpp @@ -81,8 +81,7 @@ public:      }  public slots:      void save(); -    void reload(std::shared_ptr<QSettings> settings = group::ini_file()); -    void save_deferred(QSettings& s); +    void reload();      void set_all_to_default();  }; diff --git a/options/group.cpp b/options/group.cpp index 9a4bd912..028e3e48 100644 --- a/options/group.cpp +++ b/options/group.cpp @@ -8,46 +8,47 @@  #include "group.hpp"  #include "defs.hpp" + +#include "compat/timer.hpp" + +#include <cmath> +  #include <QStandardPaths>  #include <QDir> -  #include <QDebug>  namespace options { -group::group(const QString& name, std::shared_ptr<QSettings> conf) : name(name) +group::group(const QString& name) : name(name)  {      if (name == "")          return; -    conf->beginGroup(name); -    for (auto& k_ : conf->childKeys()) -    { -        auto tmp = k_.toUtf8(); -        QString k(tmp); -        kvs[k] = conf->value(k_); -    } -    conf->endGroup(); -} - -group::group(const QString& name) : group(name, ini_file()) -{ +    with_settings_object([&](QSettings& conf) { +        conf.beginGroup(name); +        for (auto& k_ : conf.childKeys()) +        { +            auto tmp = k_.toUtf8(); +            QString k(tmp); +            kvs[k] = conf.value(k_); +        } +        conf.endGroup(); +    });  }  void group::save() const  { -    save_deferred(*ini_file()); -} - -void group::save_deferred(QSettings& s) const -{      if (name == "")          return; -    s.beginGroup(name); -    for (auto& i : kvs) -        s.setValue(i.first, i.second); -    s.endGroup(); +    with_settings_object([&](QSettings& s) { +        s.beginGroup(name); +        for (auto& i : kvs) +            s.setValue(i.first, i.second); +        s.endGroup(); + +        mark_ini_modified(); +    });  }  void group::put(const QString &s, const QVariant &d) @@ -103,12 +104,52 @@ QStringList group::ini_list()      return list;  } -std::shared_ptr<QSettings> group::ini_file() +void group::mark_ini_modified() +{ +    QMutexLocker l(&cur_ini_mtx); +    ini_modifiedp = true; +} + +QString group::cur_ini_pathname; +std::shared_ptr<QSettings> group::cur_ini; +QMutex group::cur_ini_mtx(QMutex::Recursive); +int group::ini_refcount = 0; +bool group::ini_modifiedp = false; + +std::shared_ptr<QSettings> group::cur_settings_object()  { -    const auto pathname = ini_pathname(); -    if (pathname != "") -        return std::make_shared<QSettings>(ini_pathname(), QSettings::IniFormat); -    return std::make_shared<QSettings>(); +    const QString pathname = ini_pathname(); + +    if (pathname.isEmpty()) +        return std::make_shared<QSettings>(); + +    QMutexLocker l(&cur_ini_mtx); + +    if (pathname != cur_ini_pathname) +    { +        cur_ini = std::make_shared<QSettings>(pathname, QSettings::IniFormat); +        cur_ini_pathname = pathname; +    } + +    return cur_ini;  } +group::saver_::~saver_() +{ +    if (--ini_refcount == 0 && ini_modifiedp) +    { +        ini_modifiedp = false; +        static Timer t; +        const double tm = t.elapsed_seconds(); +        qDebug() << QStringLiteral("%1.%2").arg(int(tm)).arg(int(std::fmod(tm, 1.)*10)) +                 << "saving .ini file" << cur_ini_pathname; +        s.sync(); +    }  } + +group::saver_::saver_(QSettings& s, QMutex& mtx) : s(s), mtx(mtx), lck(&mtx) +{ +    ini_refcount++; +} + +} // ns options diff --git a/options/group.hpp b/options/group.hpp index e2a8058c..b0e13a6a 100644 --- a/options/group.hpp +++ b/options/group.hpp @@ -1,13 +1,16 @@  #pragma once  #include "export.hpp" +  #include "compat/util.hpp" +  #include <map>  #include <memory>  #include <QString>  #include <QList>  #include <QVariant>  #include <QSettings> +#include <QMutex>  namespace options { @@ -15,12 +18,27 @@ namespace options {  class OTR_OPTIONS_EXPORT group final  {      QString name; + +    static QString cur_ini_pathname; +    static std::shared_ptr<QSettings> cur_ini; +    static QMutex cur_ini_mtx; +    static int ini_refcount; +    static bool ini_modifiedp; +    struct OTR_OPTIONS_EXPORT saver_ final +    { +        QSettings& s; +        QMutex& mtx; +        QMutexLocker lck; + +        ~saver_(); +        saver_(QSettings& s, QMutex&); +    }; +    static std::shared_ptr<QSettings> cur_settings_object(); +  public:      std::map<QString, QVariant> kvs; -    group(const QString& name, mem<QSettings> s);      group(const QString& name);      void save() const; -    void save_deferred(QSettings& s) const;      void put(const QString& s, const QVariant& d);      bool contains(const QString& s) const;      static QString ini_directory(); @@ -28,9 +46,11 @@ public:      static QString ini_pathname();      static QString ini_combine(const QString& filename);      static QStringList ini_list(); -    static std::shared_ptr<QSettings> ini_file(); + +    static void mark_ini_modified();      template<typename t> +    OTR_NEVER_INLINE      t get(const QString& k) const      {          auto value = kvs.find(k); @@ -38,6 +58,15 @@ public:              return value->second.value<t>();          return t();      } + +    template<typename F> +    OTR_NEVER_INLINE +    static auto with_settings_object(F&& fun) +    { +        saver_ saver { *cur_settings_object(), cur_ini_mtx }; + +        return fun(static_cast<QSettings&>(saver.s)); +    }  };  } | 
