3 Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
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.
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.
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.
20 #include "nodemetadata.h"
21 #include "exceptions.h"
23 #include "inventory.h"
25 #include "util/serialize.h"
26 #include "util/basic_macros.h"
27 #include "constants.h" // MAP_BLOCKSIZE
34 NodeMetadata::NodeMetadata(IItemDefManager
*item_def_mgr
):
35 m_inventory(new Inventory(item_def_mgr
))
38 NodeMetadata::~NodeMetadata()
43 void NodeMetadata::serialize(std::ostream
&os
, u8 version
, bool disk
) const
45 int num_vars
= disk
? m_stringvars
.size() : countNonPrivate();
46 writeU32(os
, num_vars
);
47 for (const auto &sv
: m_stringvars
) {
48 bool priv
= isPrivate(sv
.first
);
52 os
<< serializeString16(sv
.first
);
53 os
<< serializeString32(sv
.second
);
55 writeU8(os
, (priv
) ? 1 : 0);
58 m_inventory
->serialize(os
);
61 void NodeMetadata::deSerialize(std::istream
&is
, u8 version
)
64 int num_vars
= readU32(is
);
65 for(int i
=0; i
<num_vars
; i
++){
66 std::string name
= deSerializeString16(is
);
67 std::string var
= deSerializeString32(is
);
68 m_stringvars
[name
] = var
;
71 markPrivate(name
, true);
75 m_inventory
->deSerialize(is
);
78 void NodeMetadata::clear()
81 m_privatevars
.clear();
85 bool NodeMetadata::empty() const
87 return Metadata::empty() && m_inventory
->getLists().empty();
91 void NodeMetadata::markPrivate(const std::string
&name
, bool set
)
94 m_privatevars
.insert(name
);
96 m_privatevars
.erase(name
);
99 int NodeMetadata::countNonPrivate() const
101 // m_privatevars can contain names not actually present
102 // DON'T: return m_stringvars.size() - m_privatevars.size();
104 for (const auto &sv
: m_stringvars
) {
105 if (!isPrivate(sv
.first
))
115 void NodeMetadataList::serialize(std::ostream
&os
, u8 blockver
, bool disk
,
116 bool absolute_pos
) const
119 Version 0 is a placeholder for "nothing to see here; go away."
122 u16 count
= countNonEmpty();
124 writeU8(os
, 0); // version
128 u8 version
= (blockver
> 27) ? 2 : 1;
129 writeU8(os
, version
);
132 for (NodeMetadataMap::const_iterator
134 i
!= m_data
.end(); ++i
) {
136 NodeMetadata
*data
= i
->second
;
145 // Serialize positions within a mapblock
146 u16 p16
= (p
.Z
* MAP_BLOCKSIZE
+ p
.Y
) * MAP_BLOCKSIZE
+ p
.X
;
149 data
->serialize(os
, version
, disk
);
153 void NodeMetadataList::deSerialize(std::istream
&is
,
154 IItemDefManager
*item_def_mgr
, bool absolute_pos
)
158 u8 version
= readU8(is
);
166 std::string err_str
= std::string(FUNCTION_NAME
)
167 + ": version " + itos(version
) + " not supported";
168 infostream
<< err_str
<< std::endl
;
169 throw SerializationError(err_str
);
172 u16 count
= readU16(is
);
174 for (u16 i
= 0; i
< count
; i
++) {
181 u16 p16
= readU16(is
);
182 p
.X
= p16
& (MAP_BLOCKSIZE
- 1);
183 p16
/= MAP_BLOCKSIZE
;
184 p
.Y
= p16
& (MAP_BLOCKSIZE
- 1);
185 p16
/= MAP_BLOCKSIZE
;
188 if (m_data
.find(p
) != m_data
.end()) {
189 warningstream
<< "NodeMetadataList::deSerialize(): "
190 << "already set data at position " << PP(p
)
191 << ": Ignoring." << std::endl
;
195 NodeMetadata
*data
= new NodeMetadata(item_def_mgr
);
196 data
->deSerialize(is
, version
);
201 NodeMetadataList::~NodeMetadataList()
206 std::vector
<v3s16
> NodeMetadataList::getAllKeys()
208 std::vector
<v3s16
> keys
;
210 NodeMetadataMap::const_iterator it
;
211 for (it
= m_data
.begin(); it
!= m_data
.end(); ++it
)
212 keys
.push_back(it
->first
);
217 NodeMetadata
*NodeMetadataList::get(v3s16 p
)
219 NodeMetadataMap::const_iterator n
= m_data
.find(p
);
220 if (n
== m_data
.end())
225 void NodeMetadataList::remove(v3s16 p
)
227 NodeMetadata
*olddata
= get(p
);
229 if (m_is_metadata_owner
)
235 void NodeMetadataList::set(v3s16 p
, NodeMetadata
*d
)
238 m_data
.insert(std::make_pair(p
, d
));
241 void NodeMetadataList::clear()
243 if (m_is_metadata_owner
) {
244 NodeMetadataMap::const_iterator it
;
245 for (it
= m_data
.begin(); it
!= m_data
.end(); ++it
)
251 int NodeMetadataList::countNonEmpty() const
254 NodeMetadataMap::const_iterator it
;
255 for (it
= m_data
.begin(); it
!= m_data
.end(); ++it
) {
256 if (!it
->second
->empty())