propertyvisitors.cpp 3.92 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
#include "propertyvisitors.hpp"

#include <QJsonArray>

PropertySaverVisitor::PropertySaverVisitor()
{
    // create the top level json object
    push_object();
}

11
QJsonObject PropertySaverVisitor::save()
12
{
13
    return current().toJsonObject();
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
}

QVariant &PropertySaverVisitor::current()
{
    assert(!m_current_hierarchy.empty());
    return m_current_hierarchy.top();
}

void PropertySaverVisitor::save_value(Property &prop, const QJsonValue &val)
{
    if (current().canConvert<QJsonArray>())
    {
        QJsonArray arr = current().toJsonArray();
        arr.append(val);
        current() = arr;
    }
    else
    {
        QJsonObject obj = current().toJsonObject();
33
        obj[QString::fromStdString(prop.identifier())] = val;
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
        current() = obj;
    }
}

void PropertySaverVisitor::push_object()
{
    m_current_hierarchy.push(QJsonObject{});
}

void PropertySaverVisitor::push_array()
{
    m_current_hierarchy.push(QJsonArray{});
}

QJsonValue PropertySaverVisitor::pop_value()
{
    QJsonValue val;
    if (current().canConvert<QJsonArray>())
        val = QJsonValue(current().toJsonArray());
    else
        val = QJsonValue(current().toJsonObject());

    m_current_hierarchy.pop();
    return val;
}

void PropertySaverVisitor::visit(StringProperty &prop)
{
    save_value(prop, QJsonValue(QString::fromStdString(prop.str)));
}

void PropertySaverVisitor::visit(IntegerProperty &prop)
{
    save_value(prop, QJsonValue(prop.val));
}

void PropertySaverVisitor::visit(CoordinateProperty &prop)
{
    QJsonArray arr;
73
    arr.append(prop.c.x); arr.append(prop.c.y);
74
75
76
77
78
79
80
81
82
83
84
85
86
87
    save_value(prop, QJsonValue(arr));
}

void PropertySaverVisitor::visit(PropertyList &list)
{
    push_array();

    for (const auto& ptr : list.contents)
        ptr->accept(*this);

    QJsonValue array = pop_value();
    save_value(list, array);
}

88
PropertyLoaderVisitor::PropertyLoaderVisitor(const QJsonObject& root)
89
{
90
    m_current_hierarchy.push(root);
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
121
122
}

QJsonValue &PropertyLoaderVisitor::current()
{
    assert(!m_current_hierarchy.empty());
    return m_current_hierarchy.top();
}

void PropertyLoaderVisitor::enter_value(const QJsonValue &value)
{
    m_current_hierarchy.push(value);
}

QJsonValue PropertyLoaderVisitor::exit_value()
{
    QJsonValue val = m_current_hierarchy.top();
    m_current_hierarchy.pop();
    return val;
}

QJsonValue PropertyLoaderVisitor::fetch_value(Property &prop)
{
    // in the case of an array, fetch the front value
    if (current().isArray())
    {
        QJsonArray arr = current().toArray();
        QJsonValue val = arr.first();
        arr.pop_front();
        current() = arr;
        return val;
    }
    else
123
        return current().toObject().value(prop.identifier().c_str());
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
}

void PropertyLoaderVisitor::visit(StringProperty &prop)
{
    QJsonValue val = fetch_value(prop);
    if (val.isString())
    {
        prop.str = val.toString().toStdString();
    }
}

void PropertyLoaderVisitor::visit(IntegerProperty &prop)
{
    QJsonValue val = fetch_value(prop);
    if (val.isDouble())
    {
        prop.val = val.toInt();
        if (prop.val > prop.prop_max || prop.val < prop.prop_min)
        {
143
            throw PropertyVisitorException("Invalid property value");
144
145
146
147
148
149
150
151
152
        }
    }
}

void PropertyLoaderVisitor::visit(CoordinateProperty &prop)
{
    QJsonValue val = fetch_value(prop);
    if (val.isArray() && val.toArray().size() == 2)
    {
153
154
        prop.c.x = val.toArray()[0].toInt();
        prop.c.y = val.toArray()[1].toInt();
155
156
157
158
159
160
161
162
163
164
165
166
    }
}


void PropertyLoaderVisitor::visit(PropertyList &prop)
{
    QJsonValue val = fetch_value(prop);
    if (val.isArray())
    {
        enter_value(val);

        if (!prop.dynamic && val.toArray().size() != (int)prop.contents.size())
167
            throw PropertyVisitorException("Invalid array size");
168
169
170
171
172
173
174
175
176
177
178

        prop.clear();
        for (int i = 0; i < val.toArray().size(); ++i)
        {
            Property& back = prop.push_back();
            back.accept(*this);
        }

        exit_value();
    }
}