GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/resources/db/mapdb.cpp Lines: 5 108 4.6 %
Date: 2018-09-20 Branches: 2 176 1.1 %

Line Branch Exec Source
1
/*
2
 *  The ManaPlus Client
3
 *  Copyright (C) 2008  Aethyra Development Team
4
 *  Copyright (C) 2011-2018  The ManaPlus Developers
5
 *
6
 *  This file is part of The ManaPlus Client.
7
 *
8
 *  This program is free software; you can redistribute it and/or modify
9
 *  it under the terms of the GNU General Public License as published by
10
 *  the Free Software Foundation; either version 2 of the License, or
11
 *  any later version.
12
 *
13
 *  This program is distributed in the hope that it will be useful,
14
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 *  GNU General Public License for more details.
17
 *
18
 *  You should have received a copy of the GNU General Public License
19
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
 */
21
22
#include "resources/db/mapdb.h"
23
24
#include "configuration.h"
25
#include "logger.h"
26
27
#include "resources/beingcommon.h"
28
29
#include "debug.h"
30
31
namespace
32
{
33
    bool mLoaded = false;
34
1
    MapDB::Maps mMaps;
35
1
    MapDB::MapInfos mInfos;
36
1
    MapDB::Atlases mAtlases;
37
1
    std::set<std::string> mEmptyTilesets;
38
}  // namespace
39
40
namespace MapDB
41
{
42
    void readMap(XmlNodePtrConst node);
43
    void readAtlas(XmlNodePtrConst node);
44
}  // namespace MapDB
45
46
void MapDB::load()
47
{
48
    if (mLoaded)
49
        unload();
50
51
    logger->log1("Initializing maps database...");
52
    loadRemapXmlFile(paths.getStringValue("mapsRemapFile"),
53
        SkipError_true);
54
    loadRemapXmlFile(paths.getStringValue("mapsRemapPatchFile"),
55
        SkipError_true);
56
    loadXmlDir("mapsRemapPatchDir", loadRemapXmlFile);
57
58
    loadInfo(paths.getStringValue("mapsFile"), SkipError_false);
59
    loadInfo(paths.getStringValue("mapsPatchFile"), SkipError_true);
60
    loadXmlDir("mapsPatchDir", loadInfo);
61
    mLoaded = true;
62
}
63
64
void MapDB::loadRemapXmlFile(const std::string &fileName,
65
                             const SkipError skipError)
66
{
67
    XML::Document *const doc = new XML::Document(fileName,
68
        UseVirtFs_true,
69
        skipError);
70
71
    XmlNodeConstPtrConst root = doc->rootNode();
72
    if (root == nullptr)
73
    {
74
        delete doc;
75
        return;
76
    }
77
78
    for_each_xml_child_node(node, root)
79
    {
80
        if (xmlNameEqual(node, "map"))
81
        {
82
            const std::string name = XML::getProperty(node, "name", "");
83
            if (name.empty())
84
                continue;
85
86
            const std::string value = XML::getProperty(node, "value", "");
87
            if (value.empty())
88
                continue;
89
90
            mMaps[name] = value;
91
        }
92
        else if (xmlNameEqual(node, "include"))
93
        {
94
            const std::string name = XML::getProperty(node, "name", "");
95
            if (!name.empty())
96
                loadRemapXmlFile(name, skipError);
97
            continue;
98
        }
99
    }
100
101
    delete doc;
102
}
103
104
void MapDB::readMap(XmlNodePtrConst node)
105
{
106
    if (node == nullptr)
107
        return;
108
    const std::string map = XML::getProperty(node, "name", "");
109
    if (map.empty())
110
        return;
111
112
    for_each_xml_child_node(childNode, node)
113
    {
114
        if (xmlNameEqual(childNode, "atlas"))
115
        {
116
            const std::string atlas = XML::getProperty(childNode, "name", "");
117
            if (atlas.empty())
118
                continue;
119
            mInfos[map].atlas = atlas;
120
        }
121
    }
122
}
123
124
void MapDB::readAtlas(XmlNodePtrConst node)
125
{
126
    if (node == nullptr)
127
        return;
128
    const std::string atlas = XML::getProperty(node, "name", "");
129
    if (atlas.empty())
130
        return;
131
    for_each_xml_child_node(childNode, node)
132
    {
133
        if (xmlNameEqual(childNode, "file"))
134
        {
135
            const std::string file = XML::getProperty(childNode, "name", "");
136
            if (file.empty())
137
                continue;
138
            mAtlases[atlas].push_back(file);
139
        }
140
    }
141
    if (atlas == paths.getStringValue("emptyAtlasName"))
142
    {
143
        const StringVect *files = &mAtlases[atlas];
144
        FOR_EACHP (StringVectCIter, it, files)
145
        {
146
            mEmptyTilesets.insert(*it);
147
            logger->log("empty tileset: " + *it);
148
        }
149
    }
150
    else if (atlas != "all")
151
    {
152
        const AtlasCIter &allAtlas = mAtlases.find("all");
153
        if (allAtlas != mAtlases.end())
154
        {
155
            FOR_EACH (StringVectCIter, it, (*allAtlas).second)
156
                mAtlases[atlas].push_back(*it);
157
        }
158
    }
159
}
160
161
void MapDB::loadInfo(const std::string &fileName,
162
                     const SkipError skipError)
163
{
164
    XML::Document *doc = new XML::Document(fileName,
165
        UseVirtFs_true,
166
        skipError);
167
    XmlNodeConstPtrConst root = doc->rootNode();
168
    if (root == nullptr)
169
    {
170
        delete doc;
171
        return;
172
    }
173
174
    for_each_xml_child_node(node, root)
175
    {
176
        if (xmlNameEqual(node, "map"))
177
        {
178
            readMap(node);
179
        }
180
        else if (xmlNameEqual(node, "atlas"))
181
        {
182
            readAtlas(node);
183
        }
184
        else if (xmlNameEqual(node, "include"))
185
        {
186
            const std::string name = XML::getProperty(node, "name", "");
187
            if (!name.empty())
188
                loadInfo(name, skipError);
189
            continue;
190
        }
191
    }
192
    delete doc;
193
}
194
195
void MapDB::unload()
196
{
197
    logger->log1("Unloading map database...");
198
199
    mMaps.clear();
200
    mLoaded = false;
201
}
202
203
const std::string MapDB::getMapName(const std::string &name)
204
{
205
    const MapIterator it = mMaps.find(name);
206
207
    if (it != mMaps.end())
208
        return it->second;
209
    return name;
210
}
211
212
const MapInfo *MapDB::getMapAtlas(const std::string &name)
213
{
214
    const MapInfoIter it = mInfos.find(name);
215
    if (it == mInfos.end())
216
        return nullptr;
217
    MapInfo *const info = &(*it).second;
218
    const AtlasCIter it2 = mAtlases.find(info->atlas);
219
    if (it2 == mAtlases.end())
220
        return nullptr;
221
    info->files = &((*it2).second);
222
    return info;
223
}
224
225
const MapInfo *MapDB::getAtlas(const std::string &name)
226
{
227
    const AtlasCIter it = mAtlases.find(name);
228
    if (it == mAtlases.end())
229
        return nullptr;
230
231
    MapInfo *const info = new MapInfo;
232
    info->atlas = name;
233
    info->files = &(*it).second;
234
    return info;
235
}
236
237
bool MapDB::isEmptyTileset(const std::string &name)
238
{
239
    return mEmptyTilesets.find(name) != mEmptyTilesets.end();
240

3
}