diff --git a/src/files/WorldRegions.cpp b/src/files/WorldRegions.cpp index 24aaa694..44aa8449 100644 --- a/src/files/WorldRegions.cpp +++ b/src/files/WorldRegions.cpp @@ -199,13 +199,10 @@ ubyte* WorldRegions::getData( return nullptr; } -std::shared_ptr WorldRegions::useRegFile(glm::ivec3 coord) { +regfile_ptr WorldRegions::useRegFile(glm::ivec3 coord) { auto* file = openRegFiles[coord].get(); file->inUse = true; - return std::shared_ptr(file, [this](regfile* ptr) { - ptr->inUse = false; - regFilesCv.notify_one(); - }); + return regfile_ptr(file, ®FilesCv); } void WorldRegions::closeRegFile(glm::ivec3 coord) { @@ -214,7 +211,7 @@ void WorldRegions::closeRegFile(glm::ivec3 coord) { } // Marks regfile as used and unmarks when shared_ptr dies -std::shared_ptr WorldRegions::getRegFile(glm::ivec3 coord, bool create) { +regfile_ptr WorldRegions::getRegFile(glm::ivec3 coord, bool create) { { std::lock_guard lock(regFilesMutex); const auto found = openRegFiles.find(coord); @@ -231,7 +228,7 @@ std::shared_ptr WorldRegions::getRegFile(glm::ivec3 coord, bool create) return nullptr; } -std::shared_ptr WorldRegions::createRegFile(glm::ivec3 coord) { +regfile_ptr WorldRegions::createRegFile(glm::ivec3 coord) { fs::path file = layers[coord[2]].folder/getRegionFilename(coord[0], coord[1]); if (!fs::exists(file)) { return nullptr; @@ -275,6 +272,7 @@ void WorldRegions::writeRegion(int x, int z, int layer, WorldRegion* entry){ fetchChunks(entry, x, z, regfile.get()); std::lock_guard lock(regFilesMutex); + regfile.reset(); closeRegFile(regcoord); } diff --git a/src/files/WorldRegions.hpp b/src/files/WorldRegions.hpp index 39a2a6b3..7ad16037 100644 --- a/src/files/WorldRegions.hpp +++ b/src/files/WorldRegions.hpp @@ -77,6 +77,43 @@ struct RegionsLayer { std::mutex mutex; }; +class regfile_ptr { + regfile* file; + std::condition_variable* cv; +public: + regfile_ptr( + regfile* file, + std::condition_variable* cv + ) : file(file), cv(cv) {} + + regfile_ptr(const regfile_ptr&) = delete; + + regfile_ptr(std::nullptr_t) : file(nullptr), cv(nullptr) {} + + bool operator==(std::nullptr_t) const { + return file == nullptr; + } + bool operator!=(std::nullptr_t) const { + return file != nullptr; + } + operator bool() const { + return file != nullptr; + } + ~regfile_ptr() { + reset(); + } + regfile* get() { + return file; + } + void reset() { + if (file) { + file->inUse = false; + cv->notify_one(); + file = nullptr; + } + } +}; + class WorldRegions { fs::path directory; std::unordered_map> openRegFiles; @@ -110,10 +147,10 @@ class WorldRegions { ubyte* getData(int x, int z, int layer, uint32_t& size); - std::shared_ptr getRegFile(glm::ivec3 coord, bool create=true); + regfile_ptr getRegFile(glm::ivec3 coord, bool create=true); void closeRegFile(glm::ivec3 coord); - std::shared_ptr useRegFile(glm::ivec3 coord); - std::shared_ptr createRegFile(glm::ivec3 coord); + regfile_ptr useRegFile(glm::ivec3 coord); + regfile_ptr createRegFile(glm::ivec3 coord); fs::path getRegionFilename(int x, int y) const;