~aleteoryx/muditaos

ref: 0eb652a5152de6bdf77c897a787d037d6e6b43d4 muditaos/module-services/service-db/agents/settings/Settings.cpp -rw-r--r-- 4.4 KiB
0eb652a5 — Kuba Kleczkowski [MOS-792] Added VoLTE setting in db 3 years ago
                                                                                
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include <service-db/Settings.hpp>
#include <service-db/SettingsCache.hpp>

#include <memory>
#include <stdexcept>
#include <utility>
#include <vector>

#if defined(DEBUG_SETTINGS_DB) and DEBUG_SETTINGS_DB == 1
#include <log/log.hpp>
#define log_debug(...) LOG_DEBUG(__VA_ARGS__);
#else
#define log_debug(...)
#endif

namespace settings
{
    Settings::~Settings()
    {
        deinit();
    }

    void Settings::init(const service::ServiceProxy &interface)
    {
        this->interface = SettingsProxy(interface);
        this->interface.init([this](const EntryPath &p, const std::string &v) { this->handleVariableChanged(p, v); });
        if (not interface.isValid()) {
            throw std::invalid_argument("need the interface!");
        }
    }

    void Settings::deinit()
    {
        if (interface.isValid()) {
            interface.deinit();
            for (const auto &callbacks : cbValues) {
                log_debug("[Settings::unregisterValueChange] %s", callbacks.first.to_string().c_str());
                interface.unregisterValueChange(callbacks.first);
            }
        }
        cbValues.clear();
    }

    void Settings::handleVariableChanged(const EntryPath &path, const std::string &value)
    {
        log_debug("handleVariableChanged: (key=%s)", path.to_string().c_str());
        if (auto callbacks = cbValues.find(path); std::end(cbValues) != callbacks) {
            // we cant get by const ref here - as user can remove this callback from cbValues map which would cause use
            // after free
            auto [cb, cbWithName] = callbacks->second;
            if (nullptr != cb) {
                cb(value);
            }
            if (nullptr != cbWithName) {
                cbWithName(path.variable, value);
            }
        }
    }

    void Settings::registerValueChange(const std::string &variableName, ValueChangedCallback cb, SettingsScope scope)
    {
        auto path = EntryPath{.service = interface.ownerName(), .variable = variableName, .scope = scope};

        if (auto callbacks = cbValues.find(path);
            std::end(cbValues) != callbacks && nullptr != callbacks->second.first) {
            log_debug("Callback function on value change (%s) already exists, rewriting", path.to_string().c_str());
        }
        cbValues[path].first = std::move(cb);
        interface.registerValueChange(std::move(path));
    }

    void Settings::registerValueChange(const std::string &variableName,
                                       ValueChangedCallbackWithName cb,
                                       SettingsScope scope)
    {
        auto path = EntryPath{.service = interface.ownerName(), .variable = variableName, .scope = scope};

        if (auto callbacks = cbValues.find(path); cbValues.end() != callbacks && nullptr != callbacks->second.second) {
            log_debug("Callback function on value change (%s) already exists, rewriting", path.to_string().c_str());
        }
        cbValues[path].second = std::move(cb);
        interface.registerValueChange(std::move(path));
    }

    void Settings::unregisterValueChange(const std::string &variableName, SettingsScope scope)
    {
        auto path = EntryPath{.service = interface.ownerName(), .variable = variableName, .scope = scope};

        if (auto callbacks = cbValues.find(path); cbValues.end() != callbacks) {
            log_debug("[Settings::unregisterValueChange] %s", path.to_string().c_str());
            cbValues.erase(callbacks);
        }
        interface.unregisterValueChange(std::move(path));
    }

    void Settings::setValue(const std::string &variableName, const std::string &variableValue, SettingsScope scope)
    {
        auto path = EntryPath{.service = interface.ownerName(), .variable = variableName, .scope = scope};
        interface.setValue(path, variableValue);
        getCache()->setValue(path, variableValue);
    }

    std::string Settings::getValue(const std::string &variableName, SettingsScope scope)
    {
        return getCache()->getValue({.service = interface.ownerName(), .variable = variableName, .scope = scope});
    }

    SettingsCache *Settings::getCache()
    {
        return SettingsCache::getInstance();
    }
    Settings::Settings(const service::ServiceProxy &interface)
    {
        init(interface);
    }

} // namespace settings