void CNodeDefManager::removeNode(const std::string &name) { // Pre-condition assert(name != ""); // Erase name from name ID mapping content_t id = CONTENT_IGNORE; if (m_name_id_mapping.getId(name, id)) { m_name_id_mapping.eraseName(name); m_name_id_mapping_with_aliases.erase(name); } // Erase node content from all groups it belongs to for (std::unordered_map<std::string, std::vector<content_t>>::iterator iter_groups = m_group_to_items.begin(); iter_groups != m_group_to_items.end();) { std::vector<content_t> &items = iter_groups->second; items.erase(std::remove(items.begin(), items.end(), id), items.end()); // Check if group is empty if (items.empty()) m_group_to_items.erase(iter_groups++); else ++iter_groups; } }
void CNodeDefManager::removeNode(const std::string &name) { // Pre-condition assert(name != ""); // Erase name from name ID mapping content_t id = CONTENT_IGNORE; if (m_name_id_mapping.getId(name, id)) { m_name_id_mapping.eraseName(name); m_name_id_mapping_with_aliases.erase(name); } // Erase node content from all groups it belongs to for (UNORDERED_MAP<std::string, GroupItems>::iterator iter_groups = m_group_to_items.begin(); iter_groups != m_group_to_items.end();) { GroupItems &items = iter_groups->second; for (GroupItems::iterator iter_groupitems = items.begin(); iter_groupitems != items.end();) { if (iter_groupitems->first == id) items.erase(iter_groupitems++); else iter_groupitems++; } // Check if group is empty if (items.size() == 0) m_group_to_items.erase(iter_groups++); else iter_groups++; } }
// IWritableNodeDefManager content_t CNodeDefManager::set(const std::string &name, const ContentFeatures &def) { // Pre-conditions if (name == "") return CONTENT_IGNORE; if (name != def.name) return CONTENT_IGNORE; // Don't allow redefining ignore (but allow air and unknown) if (name == "ignore") { infostream << "NodeDefManager: WARNING: Ignoring " "CONTENT_IGNORE redefinition"<<std::endl; return CONTENT_IGNORE; } content_t id = CONTENT_IGNORE; if (!m_name_id_mapping.getId(name, id)) { // ignore aliases // Get new id id = allocateId(); if (id == CONTENT_IGNORE) { infostream << "NodeDefManager: WARNING: Absolute " "limit reached" << std::endl; return CONTENT_IGNORE; } if (id == CONTENT_IGNORE) return CONTENT_IGNORE; addNameIdMapping(id, name); } m_content_features[id] = def; verbosestream << "NodeDefManager: registering content id \"" << id << "\": name=\"" << def.name << "\""<<std::endl; // Add this content to the list of all groups it belongs to // FIXME: This should remove a node from groups it no longer // belongs to when a node is re-registered for (ItemGroupList::const_iterator i = def.groups.begin(); i != def.groups.end(); ++i) { std::string group_name = i->first; std::map<std::string, GroupItems>::iterator j = m_group_to_items.find(group_name); if (j == m_group_to_items.end()) { m_group_to_items[group_name].push_back( std::make_pair(id, i->second)); } else { GroupItems &items = j->second; items.push_back(std::make_pair(id, i->second)); } } return id; }
void CNodeDefManager::updateAliases(IItemDefManager *idef) { std::set<std::string> all; idef->getAll(all); m_name_id_mapping_with_aliases.clear(); for (const std::string &name : all) { const std::string &convert_to = idef->getAlias(name); content_t id; if (m_name_id_mapping.getId(convert_to, id)) { m_name_id_mapping_with_aliases.insert( std::make_pair(name, id)); } } }
void CNodeDefManager::updateAliases(IItemDefManager *idef) { std::set<std::string> all = idef->getAll(); m_name_id_mapping_with_aliases.clear(); for (std::set<std::string>::iterator i = all.begin(); i != all.end(); ++i) { std::string name = *i; std::string convert_to = idef->getAlias(name); content_t id; if (m_name_id_mapping.getId(convert_to, id)) { m_name_id_mapping_with_aliases.insert( std::make_pair(name, id)); } } }
void CNodeDefManager::deSerialize(std::istream &is) { clear(); int version = readU8(is); if (version != 1) throw SerializationError("unsupported NodeDefinitionManager version"); u16 count = readU16(is); std::istringstream is2(deSerializeLongString(is), std::ios::binary); ContentFeatures f; for (u16 n = 0; n < count; n++) { u16 i = readU16(is2); // Read it from the string wrapper std::string wrapper = deSerializeString(is2); std::istringstream wrapper_is(wrapper, std::ios::binary); f.deSerialize(wrapper_is); // Check error conditions if (i == CONTENT_IGNORE || i == CONTENT_AIR || i == CONTENT_UNKNOWN) { warningstream << "NodeDefManager::deSerialize(): " "not changing builtin node " << i << std::endl; continue; } if (f.name.empty()) { warningstream << "NodeDefManager::deSerialize(): " "received empty name" << std::endl; continue; } // Ignore aliases u16 existing_id; if (m_name_id_mapping.getId(f.name, existing_id) && i != existing_id) { warningstream << "NodeDefManager::deSerialize(): " "already defined with different ID: " << f.name << std::endl; continue; } // All is ok, add node definition with the requested ID if (i >= m_content_features.size()) m_content_features.resize((u32)(i) + 1); m_content_features[i] = f; addNameIdMapping(i, f.name); verbosestream << "deserialized " << f.name << std::endl; getNodeBoxUnion(f.selection_box, f, &m_selection_box_union); fixSelectionBoxIntUnion(); } }
void CNodeDefManager::msgpack_unpack(msgpack::object o) { clear(); std::map<int, ContentFeatures> unpacked_features; o.convert(&unpacked_features); for (std::map<int, ContentFeatures>::iterator it = unpacked_features.begin(); it != unpacked_features.end(); ++it) { unsigned int i = it->first; ContentFeatures f = it->second; if(i == CONTENT_IGNORE || i == CONTENT_AIR || i == CONTENT_UNKNOWN){ infostream<<"NodeDefManager::deSerialize(): WARNING: " <<"not changing builtin node "<<i <<std::endl; continue; } if(f.name == ""){ infostream<<"NodeDefManager::deSerialize(): WARNING: " <<"received empty name"<<std::endl; continue; } u16 existing_id; bool found = m_name_id_mapping.getId(f.name, existing_id); // ignore aliases if(found && i != existing_id){ infostream<<"NodeDefManager::deSerialize(): WARNING: " <<"already defined with different ID: " <<f.name<<std::endl; continue; } // All is ok, add node definition with the requested ID if(i >= m_content_features.size()) m_content_features.resize((u32)(i) + 1); m_content_features[i] = f; addNameIdMapping(i, f.name); verbosestream<<"deserialized "<<f.name<<std::endl; } }
// IWritableNodeDefManager content_t CNodeDefManager::set(const std::string &name, const ContentFeatures &def) { // Pre-conditions assert(name != ""); assert(name == def.name); // Don't allow redefining ignore (but allow air and unknown) if (name == "ignore") { warningstream << "NodeDefManager: Ignoring " "CONTENT_IGNORE redefinition"<<std::endl; return CONTENT_IGNORE; } content_t id = CONTENT_IGNORE; if (!m_name_id_mapping.getId(name, id)) { // ignore aliases // Get new id id = allocateId(); if (id == CONTENT_IGNORE) { warningstream << "NodeDefManager: Absolute " "limit reached" << std::endl; return CONTENT_IGNORE; } assert(id != CONTENT_IGNORE); addNameIdMapping(id, name); } m_content_features[id] = def; verbosestream << "NodeDefManager: registering content id \"" << id << "\": name=\"" << def.name << "\""<<std::endl; getNodeBoxUnion(def.selection_box, def, &m_selection_box_union); fixSelectionBoxIntUnion(); // Add this content to the list of all groups it belongs to // FIXME: This should remove a node from groups it no longer // belongs to when a node is re-registered for (const auto &group : def.groups) { const std::string &group_name = group.first; m_group_to_items[group_name].push_back(id); } return id; }