X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fnodemetadata.cpp;h=b84ffc8cbc2f9230534259fd7cc5670603303097;hb=7ec0e3df35a11b66b48eababf0123170f2453a50;hp=410b4e2ea78bcb12cf89020dba9451aeb2336312;hpb=8b8ef8acc0cc0b59e231d55e7857f629fee27e66;p=dragonfireclient.git diff --git a/src/nodemetadata.cpp b/src/nodemetadata.cpp index 410b4e2ea..b84ffc8cb 100644 --- a/src/nodemetadata.cpp +++ b/src/nodemetadata.cpp @@ -1,266 +1,260 @@ /* -Minetest-c55 -Copyright (C) 2010-2011 celeron55, Perttu Ahola +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. +GNU Lesser General Public License for more details. -You should have received a copy of the GNU General Public License along +You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "nodemetadata.h" -#include "utility.h" -#include "mapnode.h" #include "exceptions.h" +#include "gamedef.h" #include "inventory.h" -#include -#include "content_mapnode.h" #include "log.h" +#include "util/serialize.h" +#include "util/basic_macros.h" +#include "constants.h" // MAP_BLOCKSIZE +#include /* NodeMetadata */ -NodeMetadata::NodeMetadata(IGameDef *gamedef): - m_gamedef(gamedef) -{ -} +NodeMetadata::NodeMetadata(IItemDefManager *item_def_mgr): + m_inventory(new Inventory(item_def_mgr)) +{} NodeMetadata::~NodeMetadata() { + delete m_inventory; } -NodeMetadata* NodeMetadata::create(const std::string &name, IGameDef *gamedef) +void NodeMetadata::serialize(std::ostream &os, u8 version, bool disk) const { - // Find factory function - core::map::Node *n; - n = m_names.find(name); - if(n == NULL) - { - // If factory is not found, just return. - errorstream<<"WARNING: NodeMetadata: No factory for name=\"" - <getValue(); - NodeMetadata *meta = (*f2)(gamedef); - return meta; - } - catch(SerializationError &e) - { - errorstream<<"NodeMetadata: SerializationError " - <<"while creating name=\""<= 2) + writeU8(os, (priv) ? 1 : 0); } + + m_inventory->serialize(os); } -NodeMetadata* NodeMetadata::deSerialize(std::istream &is, IGameDef *gamedef) +void NodeMetadata::deSerialize(std::istream &is, u8 version) { - // Read id - u8 buf[2]; - is.read((char*)buf, 2); - s16 id = readS16(buf); - - // Read data - std::string data = deSerializeString(is); - - // Find factory function - core::map::Node *n; - n = m_types.find(id); - if(n == NULL) - { - // If factory is not found, just return. - infostream<<"WARNING: NodeMetadata: No factory for typeId=" - <getValue(); - NodeMetadata *meta = (*f)(iss, gamedef); - return meta; - } - catch(SerializationError &e) - { - infostream<<"WARNING: NodeMetadata: ignoring SerializationError"<= 2) { + if (readU8(is) == 1) + markPrivate(name, true); + } } + + m_inventory->deSerialize(is); } -void NodeMetadata::serialize(std::ostream &os) +void NodeMetadata::clear() { - u8 buf[2]; - writeU16(buf, typeId()); - os.write((char*)buf, 2); - - std::ostringstream oss(std::ios_base::binary); - serializeBody(oss); - os<clear(); } -void NodeMetadata::registerType(u16 id, const std::string &name, Factory f, - Factory2 f2) +bool NodeMetadata::empty() const { - { // typeId - core::map::Node *n; - n = m_types.find(id); - if(!n) - m_types.insert(id, f); - } - { // typeName - core::map::Node *n; - n = m_names.find(name); - if(!n) - m_names.insert(name, f2); + return Metadata::empty() && m_inventory->getLists().empty(); +} + + +void NodeMetadata::markPrivate(const std::string &name, bool set) +{ + if (set) + m_privatevars.insert(name); + else + m_privatevars.erase(name); +} + +int NodeMetadata::countNonPrivate() const +{ + // m_privatevars can contain names not actually present + // DON'T: return m_stringvars.size() - m_privatevars.size(); + int n = 0; + for (const auto &sv : m_stringvars) { + if (!isPrivate(sv.first)) + n++; } + return n; } /* NodeMetadataList */ -void NodeMetadataList::serialize(std::ostream &os) +void NodeMetadataList::serialize(std::ostream &os, u8 blockver, bool disk, + bool absolute_pos) const { - u8 buf[6]; - - u16 version = 1; - writeU16(buf, version); - os.write((char*)buf, 2); - - u16 count = m_data.size(); - writeU16(buf, count); - os.write((char*)buf, 2); - - for(core::map::Iterator - i = m_data.getIterator(); - i.atEnd()==false; i++) - { - v3s16 p = i.getNode()->getKey(); - NodeMetadata *data = i.getNode()->getValue(); - - u16 p16 = p.Z*MAP_BLOCKSIZE*MAP_BLOCKSIZE + p.Y*MAP_BLOCKSIZE + p.X; - writeU16(buf, p16); - os.write((char*)buf, 2); - - data->serialize(os); + /* + Version 0 is a placeholder for "nothing to see here; go away." + */ + + u16 count = countNonEmpty(); + if (count == 0) { + writeU8(os, 0); // version + return; + } + + u8 version = (blockver > 27) ? 2 : 1; + writeU8(os, version); + writeU16(os, count); + + for (NodeMetadataMap::const_iterator + i = m_data.begin(); + i != m_data.end(); ++i) { + v3s16 p = i->first; + NodeMetadata *data = i->second; + if (data->empty()) + continue; + + if (absolute_pos) { + writeS16(os, p.X); + writeS16(os, p.Y); + writeS16(os, p.Z); + } else { + // Serialize positions within a mapblock + u16 p16 = (p.Z * MAP_BLOCKSIZE + p.Y) * MAP_BLOCKSIZE + p.X; + writeU16(os, p16); + } + data->serialize(os, version, disk); } - } -void NodeMetadataList::deSerialize(std::istream &is, IGameDef *gamedef) + +void NodeMetadataList::deSerialize(std::istream &is, + IItemDefManager *item_def_mgr, bool absolute_pos) { - m_data.clear(); + clear(); - u8 buf[6]; - - is.read((char*)buf, 2); - u16 version = readU16(buf); + u8 version = readU8(is); - if(version > 1) - { - infostream<<__FUNCTION_NAME<<": version "< 2) { + std::string err_str = std::string(FUNCTION_NAME) + + ": version " + itos(version) + " not supported"; + infostream << err_str << std::endl; + throw SerializationError(err_str); + } + + u16 count = readU16(is); + + for (u16 i = 0; i < count; i++) { + v3s16 p; + if (absolute_pos) { + p.X = readS16(is); + p.Y = readS16(is); + p.Z = readS16(is); + } else { + u16 p16 = readU16(is); + p.X = p16 & (MAP_BLOCKSIZE - 1); + p16 /= MAP_BLOCKSIZE; + p.Y = p16 & (MAP_BLOCKSIZE - 1); + p16 /= MAP_BLOCKSIZE; + p.Z = p16; + } + if (m_data.find(p) != m_data.end()) { + warningstream << "NodeMetadataList::deSerialize(): " + << "already set data at position " << PP(p) + << ": Ignoring." << std::endl; continue; } - m_data.insert(p, data); + NodeMetadata *data = new NodeMetadata(item_def_mgr); + data->deSerialize(is, version); + m_data[p] = data; } } - + NodeMetadataList::~NodeMetadataList() { - for(core::map::Iterator - i = m_data.getIterator(); - i.atEnd()==false; i++) - { - delete i.getNode()->getValue(); - } + clear(); +} + +std::vector NodeMetadataList::getAllKeys() +{ + std::vector keys; + + NodeMetadataMap::const_iterator it; + for (it = m_data.begin(); it != m_data.end(); ++it) + keys.push_back(it->first); + + return keys; } -NodeMetadata* NodeMetadataList::get(v3s16 p) +NodeMetadata *NodeMetadataList::get(v3s16 p) { - core::map::Node *n; - n = m_data.find(p); - if(n == NULL) + NodeMetadataMap::const_iterator n = m_data.find(p); + if (n == m_data.end()) return NULL; - return n->getValue(); + return n->second; } void NodeMetadataList::remove(v3s16 p) { NodeMetadata *olddata = get(p); - if(olddata) - { - delete olddata; - m_data.remove(p); + if (olddata) { + if (m_is_metadata_owner) + delete olddata; + m_data.erase(p); } } void NodeMetadataList::set(v3s16 p, NodeMetadata *d) { remove(p); - m_data.insert(p, d); + m_data.insert(std::make_pair(p, d)); } -bool NodeMetadataList::step(float dtime) +void NodeMetadataList::clear() { - bool something_changed = false; - for(core::map::Iterator - i = m_data.getIterator(); - i.atEnd()==false; i++) - { - v3s16 p = i.getNode()->getKey(); - NodeMetadata *meta = i.getNode()->getValue(); - bool changed = meta->step(dtime); - if(changed) - something_changed = true; + if (m_is_metadata_owner) { + NodeMetadataMap::const_iterator it; + for (it = m_data.begin(); it != m_data.end(); ++it) + delete it->second; } - return something_changed; + m_data.clear(); } +int NodeMetadataList::countNonEmpty() const +{ + int n = 0; + NodeMetadataMap::const_iterator it; + for (it = m_data.begin(); it != m_data.end(); ++it) { + if (!it->second->empty()) + n++; + } + return n; +}