FactGroup.cc 5.23 KB
Newer Older
1 2
/****************************************************************************
 *
3
 * (c) 2009-2020 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
4 5 6 7 8 9
 *
 * QGroundControl is licensed according to the terms in the file
 * COPYING.md in the root of the source code directory.
 *
 ****************************************************************************/

Don Gagne's avatar
Don Gagne committed
10 11 12 13 14 15 16 17 18

#include "FactGroup.h"
#include "JsonHelper.h"

#include <QJsonDocument>
#include <QJsonParseError>
#include <QJsonArray>
#include <QDebug>
#include <QFile>
19
#include <QQmlEngine>
Don Gagne's avatar
Don Gagne committed
20

21
FactGroup::FactGroup(int updateRateMsecs, const QString& metaDataFile, QObject* parent, bool ignoreCamelCase)
Don Gagne's avatar
Don Gagne committed
22 23
    : QObject(parent)
    , _updateRateMSecs(updateRateMsecs)
24
    , _ignoreCamelCase(ignoreCamelCase)
25 26 27
{
    _setupTimer();
    _nameToFactMetaDataMap = FactMetaData::createMapFromJsonFile(metaDataFile, this);
28
    QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership);
29 30
}

31
FactGroup::FactGroup(int updateRateMsecs, QObject* parent, bool ignoreCamelCase)
32 33
    : QObject(parent)
    , _updateRateMSecs(updateRateMsecs)
34
    , _ignoreCamelCase(ignoreCamelCase)
35 36
{
    _setupTimer();
37
    QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership);
38 39
}

40
void FactGroup::_loadFromJsonArray(const QJsonArray jsonArray)
41
{
42 43
    QMap<QString, QString> defineMap;
    _nameToFactMetaDataMap = FactMetaData::createMapFromJsonArray(jsonArray, defineMap, this);
44 45 46
}

void FactGroup::_setupTimer()
Don Gagne's avatar
Don Gagne committed
47 48 49 50
{
    if (_updateRateMSecs > 0) {
        connect(&_updateTimer, &QTimer::timeout, this, &FactGroup::_updateAllValues);
        _updateTimer.setSingleShot(false);
51 52
        _updateTimer.setInterval(_updateRateMSecs);
        _updateTimer.start();
Don Gagne's avatar
Don Gagne committed
53 54 55
    }
}

56
bool FactGroup::factExists(const QString& name)
Don Gagne's avatar
Don Gagne committed
57
{
58 59 60 61 62 63 64 65 66 67 68 69
    if (name.contains(".")) {
        QStringList parts = name.split(".");
        if (parts.count() != 2) {
            qWarning() << "Only single level of hierarchy supported";
            return false;
        }

        FactGroup * factGroup = getFactGroup(parts[0]);
        if (!factGroup) {
            qWarning() << "Unknown FactGroup" << parts[0];
            return false;
        }
70

71 72 73 74 75 76 77 78 79 80
        return factGroup->factExists(parts[1]);
    }

    QString camelCaseName = _ignoreCamelCase ? name : _camelCase(name);

    return _nameToFactMap.contains(camelCaseName);
}

Fact* FactGroup::getFact(const QString& name)
{
81 82 83 84
    if (name.contains(".")) {
        QStringList parts = name.split(".");
        if (parts.count() != 2) {
            qWarning() << "Only single level of hierarchy supported";
85
            return nullptr;
86 87 88 89 90
        }

        FactGroup * factGroup = getFactGroup(parts[0]);
        if (!factGroup) {
            qWarning() << "Unknown FactGroup" << parts[0];
91
            return nullptr;
92 93 94 95 96
        }

        return factGroup->getFact(parts[1]);
    }

97 98 99 100 101
    Fact*   fact =          nullptr;
    QString camelCaseName = _ignoreCamelCase ? name : _camelCase(name);

    if (_nameToFactMap.contains(camelCaseName)) {
        fact = _nameToFactMap[camelCaseName];
102
        QQmlEngine::setObjectOwnership(fact, QQmlEngine::CppOwnership);
Don Gagne's avatar
Don Gagne committed
103
    } else {
104
        qWarning() << "Unknown Fact" << camelCaseName;
Don Gagne's avatar
Don Gagne committed
105 106
    }

107
    return fact;
Don Gagne's avatar
Don Gagne committed
108 109 110 111
}

FactGroup* FactGroup::getFactGroup(const QString& name)
{
112 113
    FactGroup*  factGroup = nullptr;
    QString     camelCaseName = _ignoreCamelCase ? name : _camelCase(name);
114

115 116
    if (_nameToFactGroupMap.contains(camelCaseName)) {
        factGroup = _nameToFactGroupMap[camelCaseName];
117
        QQmlEngine::setObjectOwnership(factGroup, QQmlEngine::CppOwnership);
Don Gagne's avatar
Don Gagne committed
118
    } else {
119
        qWarning() << "Unknown FactGroup" << camelCaseName;
Don Gagne's avatar
Don Gagne committed
120 121
    }

122
    return factGroup;
Don Gagne's avatar
Don Gagne committed
123 124 125 126 127 128 129 130 131 132 133
}

void FactGroup::_addFact(Fact* fact, const QString& name)
{
    if (_nameToFactMap.contains(name)) {
        qWarning() << "Duplicate Fact" << name;
        return;
    }

    fact->setSendValueChangedSignals(_updateRateMSecs == 0);
    if (_nameToFactMetaDataMap.contains(name)) {
134
        fact->setMetaData(_nameToFactMetaDataMap[name], true /* setDefaultFromMetaData */);
Don Gagne's avatar
Don Gagne committed
135 136
    }
    _nameToFactMap[name] = fact;
137
    _factNames.append(name);
138 139

    emit factNamesChanged();
Don Gagne's avatar
Don Gagne committed
140 141 142 143 144 145 146 147 148 149
}

void FactGroup::_addFactGroup(FactGroup* factGroup, const QString& name)
{
    if (_nameToFactGroupMap.contains(name)) {
        qWarning() << "Duplicate FactGroup" << name;
        return;
    }

    _nameToFactGroupMap[name] = factGroup;
150 151

    emit factGroupNamesChanged();
Don Gagne's avatar
Don Gagne committed
152 153 154 155
}

void FactGroup::_updateAllValues(void)
{
156
    for(Fact* fact: _nameToFactMap) {
Don Gagne's avatar
Don Gagne committed
157 158 159
        fact->sendDeferredValueChangedSignal();
    }
}
160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194

void FactGroup::setLiveUpdates(bool liveUpdates)
{
    if (_updateTimer.interval() == 0) {
        return;
    }

    if (liveUpdates) {
        _updateTimer.stop();
    } else {
        _updateTimer.start();
    }
    for(Fact* fact: _nameToFactMap) {
        fact->setSendValueChangedSignals(liveUpdates);
    }
}


QString FactGroup::_camelCase(const QString& text)
{
    return text[0].toLower() + text.right(text.length() - 1);
}

void FactGroup::handleMessage(Vehicle* /* vehicle */, mavlink_message_t& /* message */)
{
    // Default implementation does nothing
}

void FactGroup::_setTelemetryAvailable (bool telemetryAvailable)
{
    if (telemetryAvailable != _telemetryAvailable) {
        _telemetryAvailable = telemetryAvailable;
        emit telemetryAvailableChanged(_telemetryAvailable);
    }
}