made user settings access thread-safe

openmw-38
Marc Zinnschlag 9 years ago
parent ecbd68a19b
commit 591564566c

@ -2,6 +2,7 @@
#include "boolsetting.hpp" #include "boolsetting.hpp"
#include <QCheckBox> #include <QCheckBox>
#include <QMutexLocker>
#include <components/settings/settings.hpp> #include <components/settings/settings.hpp>
@ -9,8 +10,8 @@
#include "state.hpp" #include "state.hpp"
CSMPrefs::BoolSetting::BoolSetting (Category *parent, Settings::Manager *values, CSMPrefs::BoolSetting::BoolSetting (Category *parent, Settings::Manager *values,
const std::string& key, const std::string& label, bool default_) QMutex *mutex, const std::string& key, const std::string& label, bool default_)
: Setting (parent, values, key, label), mDefault (default_) : Setting (parent, values, mutex, key, label), mDefault (default_)
{} {}
CSMPrefs::BoolSetting& CSMPrefs::BoolSetting::setTooltip (const std::string& tooltip) CSMPrefs::BoolSetting& CSMPrefs::BoolSetting::setTooltip (const std::string& tooltip)
@ -37,6 +38,10 @@ std::pair<QWidget *, QWidget *> CSMPrefs::BoolSetting::makeWidgets (QWidget *par
void CSMPrefs::BoolSetting::valueChanged (int value) void CSMPrefs::BoolSetting::valueChanged (int value)
{ {
{
QMutexLocker lock (getMutex());
getValues().setBool (getKey(), getParent()->getKey(), value); getValues().setBool (getKey(), getParent()->getKey(), value);
}
getParent()->getState()->update (*this); getParent()->getState()->update (*this);
} }

@ -15,7 +15,7 @@ namespace CSMPrefs
public: public:
BoolSetting (Category *parent, Settings::Manager *values, BoolSetting (Category *parent, Settings::Manager *values,
const std::string& key, const std::string& label, bool default_); QMutex *mutex, const std::string& key, const std::string& label, bool default_);
BoolSetting& setTooltip (const std::string& tooltip); BoolSetting& setTooltip (const std::string& tooltip);

@ -1,9 +1,8 @@
#include "coloursetting.hpp" #include "coloursetting.hpp"
#include <limits>
#include <QLabel> #include <QLabel>
#include <QMutexLocker>
#include <components/settings/settings.hpp> #include <components/settings/settings.hpp>
@ -13,8 +12,8 @@
#include "state.hpp" #include "state.hpp"
CSMPrefs::ColourSetting::ColourSetting (Category *parent, Settings::Manager *values, CSMPrefs::ColourSetting::ColourSetting (Category *parent, Settings::Manager *values,
const std::string& key, const std::string& label, QColor default_) QMutex *mutex, const std::string& key, const std::string& label, QColor default_)
: Setting (parent, values, key, label), mDefault (default_) : Setting (parent, values, mutex, key, label), mDefault (default_)
{} {}
CSMPrefs::ColourSetting& CSMPrefs::ColourSetting::setTooltip (const std::string& tooltip) CSMPrefs::ColourSetting& CSMPrefs::ColourSetting::setTooltip (const std::string& tooltip)
@ -44,6 +43,10 @@ std::pair<QWidget *, QWidget *> CSMPrefs::ColourSetting::makeWidgets (QWidget *p
void CSMPrefs::ColourSetting::valueChanged() void CSMPrefs::ColourSetting::valueChanged()
{ {
CSVWidget::ColorEditor& widget = dynamic_cast<CSVWidget::ColorEditor&> (*sender()); CSVWidget::ColorEditor& widget = dynamic_cast<CSVWidget::ColorEditor&> (*sender());
{
QMutexLocker lock (getMutex());
getValues().setString (getKey(), getParent()->getKey(), widget.color().name().toUtf8().data()); getValues().setString (getKey(), getParent()->getKey(), widget.color().name().toUtf8().data());
}
getParent()->getState()->update (*this); getParent()->getState()->update (*this);
} }

@ -17,7 +17,8 @@ namespace CSMPrefs
public: public:
ColourSetting (Category *parent, Settings::Manager *values, ColourSetting (Category *parent, Settings::Manager *values,
const std::string& key, const std::string& label, QColor default_); QMutex *mutex, const std::string& key, const std::string& label,
QColor default_);
ColourSetting& setTooltip (const std::string& tooltip); ColourSetting& setTooltip (const std::string& tooltip);

@ -5,6 +5,7 @@
#include <QLabel> #include <QLabel>
#include <QDoubleSpinBox> #include <QDoubleSpinBox>
#include <QMutexLocker>
#include <components/settings/settings.hpp> #include <components/settings/settings.hpp>
@ -12,8 +13,9 @@
#include "state.hpp" #include "state.hpp"
CSMPrefs::DoubleSetting::DoubleSetting (Category *parent, Settings::Manager *values, CSMPrefs::DoubleSetting::DoubleSetting (Category *parent, Settings::Manager *values,
const std::string& key, const std::string& label, double default_) QMutex *mutex, const std::string& key, const std::string& label, double default_)
: Setting (parent, values, key, label), mMin (0), mMax (std::numeric_limits<double>::max()), : Setting (parent, values, mutex, key, label),
mMin (0), mMax (std::numeric_limits<double>::max()),
mDefault (default_) mDefault (default_)
{} {}
@ -64,6 +66,10 @@ std::pair<QWidget *, QWidget *> CSMPrefs::DoubleSetting::makeWidgets (QWidget *p
void CSMPrefs::DoubleSetting::valueChanged (double value) void CSMPrefs::DoubleSetting::valueChanged (double value)
{ {
{
QMutexLocker lock (getMutex());
getValues().setFloat (getKey(), getParent()->getKey(), value); getValues().setFloat (getKey(), getParent()->getKey(), value);
}
getParent()->getState()->update (*this); getParent()->getState()->update (*this);
} }

@ -17,7 +17,8 @@ namespace CSMPrefs
public: public:
DoubleSetting (Category *parent, Settings::Manager *values, DoubleSetting (Category *parent, Settings::Manager *values,
const std::string& key, const std::string& label, double default_); QMutex *mutex, const std::string& key, const std::string& label,
double default_);
// defaults to [0, std::numeric_limits<double>::max()] // defaults to [0, std::numeric_limits<double>::max()]
DoubleSetting& setRange (double min, double max); DoubleSetting& setRange (double min, double max);

@ -3,6 +3,7 @@
#include <QLabel> #include <QLabel>
#include <QComboBox> #include <QComboBox>
#include <QMutexLocker>
#include <components/settings/settings.hpp> #include <components/settings/settings.hpp>
@ -39,8 +40,8 @@ CSMPrefs::EnumValues& CSMPrefs::EnumValues::add (const std::string& value, const
CSMPrefs::EnumSetting::EnumSetting (Category *parent, Settings::Manager *values, CSMPrefs::EnumSetting::EnumSetting (Category *parent, Settings::Manager *values,
const std::string& key, const std::string& label, const EnumValue& default_) QMutex *mutex, const std::string& key, const std::string& label, const EnumValue& default_)
: Setting (parent, values, key, label), mDefault (default_) : Setting (parent, values, mutex, key, label), mDefault (default_)
{} {}
CSMPrefs::EnumSetting& CSMPrefs::EnumSetting::setTooltip (const std::string& tooltip) CSMPrefs::EnumSetting& CSMPrefs::EnumSetting::setTooltip (const std::string& tooltip)
@ -102,6 +103,10 @@ std::pair<QWidget *, QWidget *> CSMPrefs::EnumSetting::makeWidgets (QWidget *par
void CSMPrefs::EnumSetting::valueChanged (int value) void CSMPrefs::EnumSetting::valueChanged (int value)
{ {
{
QMutexLocker lock (getMutex());
getValues().setString (getKey(), getParent()->getKey(), mValues.mValues.at (value).mValue); getValues().setString (getKey(), getParent()->getKey(), mValues.mValues.at (value).mValue);
}
getParent()->getState()->update (*this); getParent()->getState()->update (*this);
} }

@ -39,7 +39,8 @@ namespace CSMPrefs
public: public:
EnumSetting (Category *parent, Settings::Manager *values, EnumSetting (Category *parent, Settings::Manager *values,
const std::string& key, const std::string& label, const EnumValue& default_); QMutex *mutex, const std::string& key, const std::string& label,
const EnumValue& default_);
EnumSetting& setTooltip (const std::string& tooltip); EnumSetting& setTooltip (const std::string& tooltip);

@ -5,6 +5,7 @@
#include <QLabel> #include <QLabel>
#include <QSpinBox> #include <QSpinBox>
#include <QMutexLocker>
#include <components/settings/settings.hpp> #include <components/settings/settings.hpp>
@ -12,8 +13,8 @@
#include "state.hpp" #include "state.hpp"
CSMPrefs::IntSetting::IntSetting (Category *parent, Settings::Manager *values, CSMPrefs::IntSetting::IntSetting (Category *parent, Settings::Manager *values,
const std::string& key, const std::string& label, int default_) QMutex *mutex, const std::string& key, const std::string& label, int default_)
: Setting (parent, values, key, label), mMin (0), mMax (std::numeric_limits<int>::max()), : Setting (parent, values, mutex, key, label), mMin (0), mMax (std::numeric_limits<int>::max()),
mDefault (default_) mDefault (default_)
{} {}
@ -64,6 +65,10 @@ std::pair<QWidget *, QWidget *> CSMPrefs::IntSetting::makeWidgets (QWidget *pare
void CSMPrefs::IntSetting::valueChanged (int value) void CSMPrefs::IntSetting::valueChanged (int value)
{ {
{
QMutexLocker lock (getMutex());
getValues().setInt (getKey(), getParent()->getKey(), value); getValues().setInt (getKey(), getParent()->getKey(), value);
}
getParent()->getState()->update (*this); getParent()->getState()->update (*this);
} }

@ -17,7 +17,7 @@ namespace CSMPrefs
public: public:
IntSetting (Category *parent, Settings::Manager *values, IntSetting (Category *parent, Settings::Manager *values,
const std::string& key, const std::string& label, int default_); QMutex *mutex, const std::string& key, const std::string& label, int default_);
// defaults to [0, std::numeric_limits<int>::max()] // defaults to [0, std::numeric_limits<int>::max()]
IntSetting& setRange (int min, int max); IntSetting& setRange (int min, int max);

@ -2,6 +2,7 @@
#include "setting.hpp" #include "setting.hpp"
#include <QColor> #include <QColor>
#include <QMutexLocker>
#include "category.hpp" #include "category.hpp"
#include "state.hpp" #include "state.hpp"
@ -11,9 +12,15 @@ Settings::Manager& CSMPrefs::Setting::getValues()
return *mValues; return *mValues;
} }
CSMPrefs::Setting::Setting (Category *parent, Settings::Manager *values, QMutex *CSMPrefs::Setting::getMutex()
{
return mMutex;
}
CSMPrefs::Setting::Setting (Category *parent, Settings::Manager *values, QMutex *mutex,
const std::string& key, const std::string& label) const std::string& key, const std::string& label)
: QObject (parent->getState()), mParent (parent), mValues (values), mKey (key), mLabel (label) : QObject (parent->getState()), mParent (parent), mValues (values), mMutex (mutex), mKey (key),
mLabel (label)
{} {}
CSMPrefs::Setting:: ~Setting() {} CSMPrefs::Setting:: ~Setting() {}
@ -40,26 +47,31 @@ const std::string& CSMPrefs::Setting::getLabel() const
int CSMPrefs::Setting::toInt() const int CSMPrefs::Setting::toInt() const
{ {
QMutexLocker lock (mMutex);
return mValues->getInt (mKey, mParent->getKey()); return mValues->getInt (mKey, mParent->getKey());
} }
double CSMPrefs::Setting::toDouble() const double CSMPrefs::Setting::toDouble() const
{ {
QMutexLocker lock (mMutex);
return mValues->getFloat (mKey, mParent->getKey()); return mValues->getFloat (mKey, mParent->getKey());
} }
std::string CSMPrefs::Setting::toString() const std::string CSMPrefs::Setting::toString() const
{ {
QMutexLocker lock (mMutex);
return mValues->getString (mKey, mParent->getKey()); return mValues->getString (mKey, mParent->getKey());
} }
bool CSMPrefs::Setting::isTrue() const bool CSMPrefs::Setting::isTrue() const
{ {
QMutexLocker lock (mMutex);
return mValues->getBool (mKey, mParent->getKey()); return mValues->getBool (mKey, mParent->getKey());
} }
QColor CSMPrefs::Setting::toColor() const QColor CSMPrefs::Setting::toColor() const
{ {
QMutexLocker lock (mMutex);
return QColor (QString::fromUtf8 (toString().c_str())); return QColor (QString::fromUtf8 (toString().c_str()));
} }

@ -8,6 +8,7 @@
class QWidget; class QWidget;
class QColor; class QColor;
class QMutex;
namespace Settings namespace Settings
{ {
@ -24,6 +25,7 @@ namespace CSMPrefs
Category *mParent; Category *mParent;
Settings::Manager *mValues; Settings::Manager *mValues;
QMutex *mMutex;
std::string mKey; std::string mKey;
std::string mLabel; std::string mLabel;
@ -31,9 +33,11 @@ namespace CSMPrefs
Settings::Manager& getValues(); Settings::Manager& getValues();
QMutex *getMutex();
public: public:
Setting (Category *parent, Settings::Manager *values, const std::string& key, const std::string& label); Setting (Category *parent, Settings::Manager *values, QMutex *mutex, const std::string& key, const std::string& label);
virtual ~Setting(); virtual ~Setting();

@ -220,7 +220,8 @@ CSMPrefs::IntSetting& CSMPrefs::State::declareInt (const std::string& key,
default_ = mSettings.getInt (key, mCurrentCategory->second.getKey()); default_ = mSettings.getInt (key, mCurrentCategory->second.getKey());
CSMPrefs::IntSetting *setting = CSMPrefs::IntSetting *setting =
new CSMPrefs::IntSetting (&mCurrentCategory->second, &mSettings, key, label, default_); new CSMPrefs::IntSetting (&mCurrentCategory->second, &mSettings, &mMutex, key, label,
default_);
mCurrentCategory->second.addSetting (setting); mCurrentCategory->second.addSetting (setting);
@ -240,7 +241,8 @@ CSMPrefs::DoubleSetting& CSMPrefs::State::declareDouble (const std::string& key,
default_ = mSettings.getFloat (key, mCurrentCategory->second.getKey()); default_ = mSettings.getFloat (key, mCurrentCategory->second.getKey());
CSMPrefs::DoubleSetting *setting = CSMPrefs::DoubleSetting *setting =
new CSMPrefs::DoubleSetting (&mCurrentCategory->second, &mSettings, key, label, default_); new CSMPrefs::DoubleSetting (&mCurrentCategory->second, &mSettings, &mMutex,
key, label, default_);
mCurrentCategory->second.addSetting (setting); mCurrentCategory->second.addSetting (setting);
@ -258,7 +260,8 @@ CSMPrefs::BoolSetting& CSMPrefs::State::declareBool (const std::string& key,
default_ = mSettings.getBool (key, mCurrentCategory->second.getKey()); default_ = mSettings.getBool (key, mCurrentCategory->second.getKey());
CSMPrefs::BoolSetting *setting = CSMPrefs::BoolSetting *setting =
new CSMPrefs::BoolSetting (&mCurrentCategory->second, &mSettings, key, label, default_); new CSMPrefs::BoolSetting (&mCurrentCategory->second, &mSettings, &mMutex, key, label,
default_);
mCurrentCategory->second.addSetting (setting); mCurrentCategory->second.addSetting (setting);
@ -276,7 +279,8 @@ CSMPrefs::EnumSetting& CSMPrefs::State::declareEnum (const std::string& key,
default_.mValue = mSettings.getString (key, mCurrentCategory->second.getKey()); default_.mValue = mSettings.getString (key, mCurrentCategory->second.getKey());
CSMPrefs::EnumSetting *setting = CSMPrefs::EnumSetting *setting =
new CSMPrefs::EnumSetting (&mCurrentCategory->second, &mSettings, key, label, default_); new CSMPrefs::EnumSetting (&mCurrentCategory->second, &mSettings, &mMutex, key, label,
default_);
mCurrentCategory->second.addSetting (setting); mCurrentCategory->second.addSetting (setting);
@ -294,7 +298,8 @@ CSMPrefs::ColourSetting& CSMPrefs::State::declareColour (const std::string& key,
default_.setNamedColor (QString::fromUtf8 (mSettings.getString (key, mCurrentCategory->second.getKey()).c_str())); default_.setNamedColor (QString::fromUtf8 (mSettings.getString (key, mCurrentCategory->second.getKey()).c_str()));
CSMPrefs::ColourSetting *setting = CSMPrefs::ColourSetting *setting =
new CSMPrefs::ColourSetting (&mCurrentCategory->second, &mSettings, key, label, default_); new CSMPrefs::ColourSetting (&mCurrentCategory->second, &mSettings, &mMutex, key, label,
default_);
mCurrentCategory->second.addSetting (setting); mCurrentCategory->second.addSetting (setting);
@ -307,7 +312,7 @@ void CSMPrefs::State::declareSeparator()
throw std::logic_error ("no category for setting"); throw std::logic_error ("no category for setting");
CSMPrefs::Setting *setting = CSMPrefs::Setting *setting =
new CSMPrefs::Setting (&mCurrentCategory->second, &mSettings, "", ""); new CSMPrefs::Setting (&mCurrentCategory->second, &mSettings, &mMutex, "", "");
mCurrentCategory->second.addSetting (setting); mCurrentCategory->second.addSetting (setting);
} }

@ -5,6 +5,7 @@
#include <string> #include <string>
#include <QObject> #include <QObject>
#include <QMutex>
#ifndef Q_MOC_RUN #ifndef Q_MOC_RUN
#include <components/files/configurationmanager.hpp> #include <components/files/configurationmanager.hpp>
@ -25,6 +26,10 @@ namespace CSMPrefs
class BoolSetting; class BoolSetting;
class ColourSetting; class ColourSetting;
/// \brief User settings state
///
/// \note Access to the user settings is thread-safe once all declarations and loading has
/// been completed.
class State : public QObject class State : public QObject
{ {
Q_OBJECT Q_OBJECT
@ -43,6 +48,7 @@ namespace CSMPrefs
Settings::Manager mSettings; Settings::Manager mSettings;
Collection mCategories; Collection mCategories;
Iterator mCurrentCategory; Iterator mCurrentCategory;
QMutex mMutex;
// not implemented // not implemented
State (const State&); State (const State&);

Loading…
Cancel
Save