summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--facetracknoir/options.h131
1 files changed, 83 insertions, 48 deletions
diff --git a/facetracknoir/options.h b/facetracknoir/options.h
index de445e69..b55d2bf0 100644
--- a/facetracknoir/options.h
+++ b/facetracknoir/options.h
@@ -10,6 +10,7 @@
#include <memory>
#include <tuple>
#include <map>
+#include <string>
#include <QObject>
#include <QSettings>
@@ -34,6 +35,7 @@
namespace options {
template<typename k, typename v>
using map = std::map<k, v>;
+ using std::string;
template<typename t>
// don't elide usages of the function, qvariant default implicit
@@ -73,8 +75,8 @@ namespace options {
// snapshot of qsettings group at given time
class group {
private:
- map<QString, QVariant> map;
- QString name;
+ map<string, QVariant> map;
+ string name;
static const QString ini_pathname()
{
QSettings settings(group::org);
@@ -82,12 +84,17 @@ namespace options {
QCoreApplication::applicationDirPath() + "/settings/default.ini" ).toString();
}
public:
- group(const QString& name) : name(name)
+ group(const string& name) : name(name)
{
QSettings conf(ini_pathname(), QSettings::IniFormat);
- conf.beginGroup(name);
- for (auto& k : conf.childKeys())
- map[k] = conf.value(k);
+ auto q_name = QString::fromStdString(name);
+ conf.beginGroup(q_name);
+ for (auto& k_ : conf.childKeys())
+ {
+ auto tmp = k_.toUtf8();
+ string k(tmp);
+ map[k] = conf.value(k_);
+ }
conf.endGroup();
}
static constexpr const char* org = "opentrack";
@@ -95,24 +102,28 @@ namespace options {
void save()
{
QSettings s(ini_pathname(), QSettings::IniFormat);
- s.beginGroup(name);
+ auto q_name = QString::fromStdString(name);
+ s.beginGroup(q_name);
for (auto& i : map)
- s.setValue(i.first, i.second);
+ {
+ auto k = QString::fromStdString(i.first);
+ s.setValue(k, i.second);
+ }
s.endGroup();
}
template<typename t>
- t get(const QString& k)
+ t get(const string& k)
{
return qcruft_to_t<t>(map[k]);
}
- void put(const QString& s, const QVariant& d)
+ void put(const string& s, const QVariant& d)
{
map[s] = d;
}
- bool contains(const QString& s)
+ bool contains(const string& s)
{
return map.count(s) != 0;
}
@@ -122,14 +133,14 @@ namespace options {
Q_OBJECT
protected:
QMutex mtx;
- const QString group_name;
+ const string group_name;
group saved;
group transient;
bool modified;
impl_bundle(const impl_bundle&) = delete;
impl_bundle& operator=(const impl_bundle&) = delete;
public:
- impl_bundle(const QString& group_name) :
+ impl_bundle(const string& group_name) :
mtx(QMutex::Recursive),
group_name(group_name),
saved(group_name),
@@ -138,7 +149,7 @@ namespace options {
{
}
- QString name() { return group_name; }
+ string name() { return group_name; }
void reload() {
QMutexLocker l(&mtx);
@@ -147,30 +158,26 @@ namespace options {
modified = false;
}
- bool store_kv(const QString& name, const QVariant& datum)
+ bool store_kv(const string& name, const QVariant& datum)
{
QMutexLocker l(&mtx);
auto old = transient.get<QVariant>(name);
if (!transient.contains(name) || datum != old)
{
- if (!modified)
- qDebug() << "bundle" << (intptr_t)static_cast<void*>(this) <<
- "modified as per" << name << old << "->" << datum;
-
modified = true;
transient.put(name, datum);
return true;
}
return false;
}
- bool contains(const QString& name)
+ bool contains(const string& name)
{
QMutexLocker l(&mtx);
return transient.contains(name);
}
template<typename t>
- t get(const QString& name)
+ t get(const string& name)
{
QMutexLocker l(&mtx);
return transient.get<t>(name);
@@ -190,53 +197,72 @@ namespace options {
};
class opt_bundle;
- using pbundle = std::shared_ptr<opt_bundle>;
- namespace {
- using tt = std::tuple<int, pbundle>;
+ namespace
+ {
+ template<typename k, typename v, typename cnt = int>
+ struct opt_singleton
+ {
+ public:
+ using pbundle = std::shared_ptr<v>;
+ using tt = std::tuple<cnt, pbundle>;
+ private:
+ QMutex implsgl_mtx;
+ map<k, tt> implsgl_data;
+ public:
+ opt_singleton() : implsgl_mtx(QMutex::Recursive) {}
+
+ pbundle bundle(const k& key)
+ {
+ QMutexLocker l(&implsgl_mtx);
+
+ if (implsgl_data.count(key) != 0)
+ return std::get<1>(implsgl_data[key]);
+
+ auto shr = std::make_shared<v>(key);
+ implsgl_data[key] = tt(cnt(1), shr);
+ return shr;
+ }
+
+ void bundle_decf(const k& key)
+ {
+ QMutexLocker l(&implsgl_mtx);
+
+ if (--std::get<0>(implsgl_data[key]) == 0)
+ implsgl_data.erase(key);
+ }
+
+ ~opt_singleton() { implsgl_data.clear(); }
+ };
- QMutex implsgl_mtx(QMutex::Recursive);
- map<QString, tt> implsgl_bundles;
+ using pbundle = std::shared_ptr<opt_bundle>;
+ using t_fact = opt_singleton<string, opt_bundle>;
+ static t_fact* opt_factory = new t_fact;
}
+
+ static inline t_fact::pbundle bundle(const string name) { return opt_factory->bundle(name); }
class opt_bundle : public impl_bundle
{
public:
opt_bundle() : impl_bundle("i-have-no-name") {}
- opt_bundle(const QString& group_name) : impl_bundle(group_name) {}
+ opt_bundle(const string& group_name) : impl_bundle(group_name) {}
~opt_bundle()
{
- QMutexLocker l(&implsgl_mtx);
-
- if (--std::get<0>(implsgl_bundles[this->group_name]) == 0)
- {
- qDebug() << "bundle" << this->group_name << "not used anymore";
- implsgl_bundles.erase(this->group_name);
- }
+ opt_factory->bundle_decf(this->group_name);
}
};
-
- inline pbundle bundle(const QString& group) {
- QMutexLocker l(&implsgl_mtx);
-
- if (implsgl_bundles.count(group) != 0)
- return std::get<1>(implsgl_bundles[group]);
-
- auto shr = std::make_shared<opt_bundle>(group);
- implsgl_bundles[group] = tt(1,shr);
- return shr;
- }
class base_value : public QObject {
Q_OBJECT
#define DEFINE_SLOT(t) void setValue(t datum) { store(datum); }
#define DEFINE_SIGNAL(t) void valueChanged(const t&)
public:
- base_value(pbundle b, const QString& name) : b(b), self_name(name), reentrancy_count(0) {}
+ base_value(pbundle b, const string& name) : b(b), self_name(name), reentrancy_count(0) {}
protected:
pbundle b;
- QString self_name;
+ string self_name;
template<typename t>
void store(const t& datum)
@@ -260,6 +286,12 @@ namespace options {
DEFINE_SIGNAL(bool);
DEFINE_SIGNAL(QString);
};
+
+ static inline string string_from_qstring(const QString& datum)
+ {
+ auto tmp = datum.toUtf8();
+ return string(tmp.constData());
+ }
template<typename t>
class value : public base_value {
@@ -271,11 +303,14 @@ namespace options {
}
static constexpr const Qt::ConnectionType DIRECT_CONNTYPE = Qt::DirectConnection;
static constexpr const Qt::ConnectionType SAFE_CONNTYPE = Qt::BlockingQueuedConnection;
- value(pbundle b, const QString& name, t def) : base_value(b, name)
+ value(pbundle b, const string& name, t def) : base_value(b, name)
{
if (!b->contains(name) || b->get<QVariant>(name).type() == QVariant::Invalid)
*this = def;
}
+ value(pbundle b, const QString& name, t def) : value(b, string_from_qstring(name), def) {}
+ value(pbundle b, const char* name, t def) : value(b, string(name), def) {}
+
operator t()
{
return b->get<t>(self_name);