summaryrefslogtreecommitdiffhomepage
path: root/options/base-value.hpp
blob: b094d693c2a64b52749a2fd5ce03278b049652ad (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#pragma once

#include "bundle.hpp"
#include "slider.hpp"
#include "connector.hpp"

#include "export.hpp"
#include "compat/meta.hpp"

#include <QObject>
#include <QString>
#include <QList>
#include <QPointF>
#include <QVariant>

#include <typeindex>

#define OPENTRACK_DEFINE_SLOT(t) void setValue(t datum) { store(datum); }
#define OPENTRACK_DEFINE_SIGNAL(t) void valueChanged(t) const

namespace options {

class OTR_OPTIONS_EXPORT base_value : public QObject
{
    Q_OBJECT

    friend class detail::connector;

    using comparator = bool(*)(const QVariant& val1, const QVariant& val2);
    template<typename t>
    using signal_sig = void(base_value::*)(cv_qualified<t>) const;

public:
    bundle get_bundle() { return b; }
    QString name() const { return self_name; }
    base_value(bundle b, const QString& name, comparator cmp, std::type_index type_idx);
    ~base_value() override;

    // MSVC has ODR problems in 15.4
    // no C++17 "constexpr inline" for data declarations in MSVC
    template<typename t>
    constexpr static auto value_changed()
    {
        return static_cast<signal_sig<t>>(&base_value::valueChanged);
    }

    void notify() const;

signals:
    OPENTRACK_DEFINE_SIGNAL(double);
    OPENTRACK_DEFINE_SIGNAL(float);
    OPENTRACK_DEFINE_SIGNAL(int);
    OPENTRACK_DEFINE_SIGNAL(bool);
    OPENTRACK_DEFINE_SIGNAL(const QString&);
    OPENTRACK_DEFINE_SIGNAL(const slider_value&);
    OPENTRACK_DEFINE_SIGNAL(const QPointF&);
    OPENTRACK_DEFINE_SIGNAL(const QVariant&);

    OPENTRACK_DEFINE_SIGNAL(const QList<double>&);
    OPENTRACK_DEFINE_SIGNAL(const QList<float>&);
    OPENTRACK_DEFINE_SIGNAL(const QList<int>&);
    OPENTRACK_DEFINE_SIGNAL(const QList<bool>&);
    OPENTRACK_DEFINE_SIGNAL(const QList<QString>&);
    OPENTRACK_DEFINE_SIGNAL(const QList<slider_value>&);
    OPENTRACK_DEFINE_SIGNAL(const QList<QPointF>&);
protected:
    bundle b;
    QString self_name;
    comparator cmp;
    std::type_index type_index;

    void store(const QVariant& datum);

    template<typename t>
    void store(const t& datum)
    {
        b->store_kv(self_name, QVariant::fromValue(datum));
    }

public slots:
    OPENTRACK_DEFINE_SLOT(double)
    OPENTRACK_DEFINE_SLOT(int)
    OPENTRACK_DEFINE_SLOT(bool)
    OPENTRACK_DEFINE_SLOT(const QString&)
    OPENTRACK_DEFINE_SLOT(const slider_value&)
    OPENTRACK_DEFINE_SLOT(const QPointF&)
    OPENTRACK_DEFINE_SLOT(const QVariant&)

    OPENTRACK_DEFINE_SLOT(const QList<double>&)
    OPENTRACK_DEFINE_SLOT(const QList<float>&)
    OPENTRACK_DEFINE_SLOT(const QList<int>&)
    OPENTRACK_DEFINE_SLOT(const QList<bool>&)
    OPENTRACK_DEFINE_SLOT(const QList<QString>&)
    OPENTRACK_DEFINE_SLOT(const QList<slider_value>&)
    OPENTRACK_DEFINE_SLOT(const QList<QPointF>&)

    virtual void reload() = 0;
    virtual void bundle_value_changed() const = 0;
    virtual void set_to_default() = 0;

    friend void ::options::detail::set_base_value_to_default(base_value* val);
};

} //ns options