]> git.lizzy.rs Git - minetest.git/blob - src/nodemetadata.cpp
Replace instances of std::map<std::string, std::string> with StringMap
[minetest.git] / src / nodemetadata.cpp
1 /*
2 Minetest
3 Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #include "nodemetadata.h"
21 #include "exceptions.h"
22 #include "gamedef.h"
23 #include "inventory.h"
24 #include "log.h"
25 #include "util/serialize.h"
26 #include "constants.h" // MAP_BLOCKSIZE
27 #include <sstream>
28
29 /*
30         NodeMetadata
31 */
32
33 NodeMetadata::NodeMetadata(IGameDef *gamedef):
34         m_stringvars(),
35         m_inventory(new Inventory(gamedef->idef()))
36 {
37 }
38
39 NodeMetadata::~NodeMetadata()
40 {
41         delete m_inventory;
42 }
43
44 void NodeMetadata::serialize(std::ostream &os) const
45 {
46         int num_vars = m_stringvars.size();
47         writeU32(os, num_vars);
48         for (StringMap::const_iterator
49                         it = m_stringvars.begin();
50                         it != m_stringvars.end(); ++it) {
51                 os << serializeString(it->first);
52                 os << serializeLongString(it->second);
53         }
54
55         m_inventory->serialize(os);
56 }
57
58 void NodeMetadata::deSerialize(std::istream &is)
59 {
60         m_stringvars.clear();
61         int num_vars = readU32(is);
62         for(int i=0; i<num_vars; i++){
63                 std::string name = deSerializeString(is);
64                 std::string var = deSerializeLongString(is);
65                 m_stringvars[name] = var;
66         }
67
68         m_inventory->deSerialize(is);
69 }
70
71 void NodeMetadata::clear()
72 {
73         m_stringvars.clear();
74         m_inventory->clear();
75 }
76
77 /*
78         NodeMetadataList
79 */
80
81 void NodeMetadataList::serialize(std::ostream &os) const
82 {
83         /*
84                 Version 0 is a placeholder for "nothing to see here; go away."
85         */
86
87         if(m_data.empty()){
88                 writeU8(os, 0); // version
89                 return;
90         }
91
92         writeU8(os, 1); // version
93
94         u16 count = m_data.size();
95         writeU16(os, count);
96
97         for(std::map<v3s16, NodeMetadata*>::const_iterator
98                         i = m_data.begin();
99                         i != m_data.end(); i++)
100         {
101                 v3s16 p = i->first;
102                 NodeMetadata *data = i->second;
103
104                 u16 p16 = p.Z*MAP_BLOCKSIZE*MAP_BLOCKSIZE + p.Y*MAP_BLOCKSIZE + p.X;
105                 writeU16(os, p16);
106
107                 data->serialize(os);
108         }
109 }
110
111 void NodeMetadataList::deSerialize(std::istream &is, IGameDef *gamedef)
112 {
113         clear();
114
115         u8 version = readU8(is);
116
117         if(version == 0){
118                 // Nothing
119                 return;
120         }
121
122         if(version != 1){
123                 infostream<<__FUNCTION_NAME<<": version "<<version<<" not supported"
124                                 <<std::endl;
125                 throw SerializationError("NodeMetadataList::deSerialize");
126         }
127
128         u16 count = readU16(is);
129
130         for(u16 i=0; i<count; i++)
131         {
132                 u16 p16 = readU16(is);
133
134                 v3s16 p;
135                 p.Z = p16 / MAP_BLOCKSIZE / MAP_BLOCKSIZE;
136                 p16 &= MAP_BLOCKSIZE * MAP_BLOCKSIZE - 1;
137                 p.Y = p16 / MAP_BLOCKSIZE;
138                 p16 &= MAP_BLOCKSIZE - 1;
139                 p.X = p16;
140
141                 if(m_data.find(p) != m_data.end())
142                 {
143                         infostream<<"WARNING: NodeMetadataList::deSerialize(): "
144                                         <<"already set data at position"
145                                         <<"("<<p.X<<","<<p.Y<<","<<p.Z<<"): Ignoring."
146                                         <<std::endl;
147                         continue;
148                 }
149
150                 NodeMetadata *data = new NodeMetadata(gamedef);
151                 data->deSerialize(is);
152                 m_data[p] = data;
153         }
154 }
155
156 NodeMetadataList::~NodeMetadataList()
157 {
158         clear();
159 }
160
161 std::vector<v3s16> NodeMetadataList::getAllKeys()
162 {
163         std::vector<v3s16> keys;
164
165         std::map<v3s16, NodeMetadata *>::const_iterator it;
166         for (it = m_data.begin(); it != m_data.end(); ++it)
167                 keys.push_back(it->first);
168
169         return keys;
170 }
171
172 NodeMetadata *NodeMetadataList::get(v3s16 p)
173 {
174         std::map<v3s16, NodeMetadata *>::const_iterator n = m_data.find(p);
175         if (n == m_data.end())
176                 return NULL;
177         return n->second;
178 }
179
180 void NodeMetadataList::remove(v3s16 p)
181 {
182         NodeMetadata *olddata = get(p);
183         if (olddata) {
184                 delete olddata;
185                 m_data.erase(p);
186         }
187 }
188
189 void NodeMetadataList::set(v3s16 p, NodeMetadata *d)
190 {
191         remove(p);
192         m_data.insert(std::make_pair(p, d));
193 }
194
195 void NodeMetadataList::clear()
196 {
197         std::map<v3s16, NodeMetadata*>::iterator it;
198         for (it = m_data.begin(); it != m_data.end(); ++it) {
199                 delete it->second;
200         }
201         m_data.clear();
202 }
203
204 std::string NodeMetadata::getString(const std::string &name,
205         unsigned short recursion) const
206 {
207         StringMap::const_iterator it = m_stringvars.find(name);
208         if (it == m_stringvars.end())
209                 return "";
210
211         return resolveString(it->second, recursion);
212 }
213
214 void NodeMetadata::setString(const std::string &name, const std::string &var)
215 {
216         if (var.empty()) {
217                 m_stringvars.erase(name);
218         } else {
219                 m_stringvars[name] = var;
220         }
221 }
222
223 std::string NodeMetadata::resolveString(const std::string &str,
224         unsigned short recursion) const
225 {
226         if (recursion > 1) {
227                 return str;
228         }
229         if (str.substr(0, 2) == "${" && str[str.length() - 1] == '}') {
230                 return getString(str.substr(2, str.length() - 3), recursion + 1);
231         }
232         return str;
233 }
234