]> git.lizzy.rs Git - minetest.git/blobdiff - src/util/areastore.cpp
Add sound to press event of some formspecs elements (#10402)
[minetest.git] / src / util / areastore.cpp
index 58f08a8c2e22918cdce829b1a45c5340177054fe..cea526336b66b8d5ec1e16e9baf2833c8bbbc2bd 100644 (file)
@@ -58,43 +58,62 @@ const Area *AreaStore::getArea(u32 id) const
 {
        AreaMap::const_iterator it = areas_map.find(id);
        if (it == areas_map.end())
-               return NULL;
+               return nullptr;
        return &it->second;
 }
 
 void AreaStore::serialize(std::ostream &os) const
 {
+       // WARNING:
+       // Before 5.1.0-dev: version != 0 throws SerializationError
+       // After 5.1.0-dev:  version >= 5 throws SerializationError
+       // Forwards-compatibility is assumed before version 5.
+
        writeU8(os, 0); // Serialisation version
 
        // TODO: Compression?
        writeU16(os, areas_map.size());
-       for (AreaMap::const_iterator it = areas_map.begin();
-                       it != areas_map.end(); ++it) {
-               const Area &a = it->second;
+       for (const auto &it : areas_map) {
+               const Area &a = it.second;
                writeV3S16(os, a.minedge);
                writeV3S16(os, a.maxedge);
                writeU16(os, a.data.size());
                os.write(a.data.data(), a.data.size());
        }
+
+       // Serialize IDs
+       for (const auto &it : areas_map)
+               writeU32(os, it.second.id);
 }
 
 void AreaStore::deserialize(std::istream &is)
 {
        u8 ver = readU8(is);
-       if (ver != 0)
+       // Assume forwards-compatibility before version 5
+       if (ver >= 5)
                throw SerializationError("Unknown AreaStore "
                                "serialization version!");
 
        u16 num_areas = readU16(is);
+       std::vector<Area> areas;
        for (u32 i = 0; i < num_areas; ++i) {
-               Area a;
+               Area a(U32_MAX);
                a.minedge = readV3S16(is);
                a.maxedge = readV3S16(is);
                u16 data_len = readU16(is);
                char *data = new char[data_len];
                is.read(data, data_len);
                a.data = std::string(data, data_len);
-               insertArea(&a);
+               areas.emplace_back(a);
+               delete [] data;
+       }
+
+       bool read_ids = is.good(); // EOF for old formats
+
+       for (auto &area : areas) {
+               if (read_ids)
+                       area.id = readU32(is);
+               insertArea(&area);
        }
 }
 
@@ -105,6 +124,19 @@ void AreaStore::invalidateCache()
        }
 }
 
+u32 AreaStore::getNextId() const
+{
+       u32 free_id = 0;
+       for (const auto &area : areas_map) {
+               if (area.first > free_id)
+                       return free_id; // Found gap
+
+               free_id = area.first + 1;
+       }
+       // End of map
+       return free_id;
+}
+
 void AreaStore::setCacheParams(bool enabled, u8 block_radius, size_t limit)
 {
        m_cache_enabled = enabled;
@@ -192,10 +224,9 @@ bool VectorAreaStore::removeArea(u32 id)
 
 void VectorAreaStore::getAreasForPosImpl(std::vector<Area *> *result, v3s16 pos)
 {
-       for (size_t i = 0; i < m_areas.size(); ++i) {
-               Area *b = m_areas[i];
-               if (AST_CONTAINS_PT(b, pos)) {
-                       result->push_back(b);
+       for (Area *area : m_areas) {
+               if (AST_CONTAINS_PT(area, pos)) {
+                       result->push_back(area);
                }
        }
 }
@@ -203,11 +234,10 @@ void VectorAreaStore::getAreasForPosImpl(std::vector<Area *> *result, v3s16 pos)
 void VectorAreaStore::getAreasInArea(std::vector<Area *> *result,
                v3s16 minedge, v3s16 maxedge, bool accept_overlap)
 {
-       for (size_t i = 0; i < m_areas.size(); ++i) {
-               Area *b = m_areas[i];
-               if (accept_overlap ? AST_AREAS_OVERLAP(minedge, maxedge, b) :
-                               AST_CONTAINS_AREA(minedge, maxedge, b)) {
-                       result->push_back(b);
+       for (Area *area : m_areas) {
+               if (accept_overlap ? AST_AREAS_OVERLAP(minedge, maxedge, area) :
+                               AST_CONTAINS_AREA(minedge, maxedge, area)) {
+                       result->push_back(area);
                }
        }
 }
@@ -238,7 +268,7 @@ bool SpatialAreaStore::insertArea(Area *a)
        if (!areas_map.insert(std::make_pair(a->id, *a)).second)
                // ID is not unique
                return false;
-       m_tree->insertData(0, NULL, get_spatial_region(a->minedge, a->maxedge), a->id);
+       m_tree->insertData(0, nullptr, get_spatial_region(a->minedge, a->maxedge), a->id);
        invalidateCache();
        return true;
 }