#pragma once #include #include #include #include "../../../core/world/forward.h" #include "../../../core/world/Voxel.hpp" #include "../../../core/data/mem.hpp" #include "../../../core/utils/zctx.hpp" #include "../../../core/data/math.hpp" namespace world::server { ///Group of chunks saved as a single file only pointer class FileRegion { public: FileRegion(const std::string& folderPath, const area_ &pos); ~FileRegion(); template void averages(D &out) { std::shared_lock lock(mutex); out.resize(index.size() * (sizeof(region_chunk_pos) + sizeof(Voxel))); data::in_view in((uint8_t*)out.data(), out.size()); for(const auto& r: index) { if (r.second.average.has_value()) { in.write((const uint8_t*)&r.first, sizeof(r.first)); in.write((const uint8_t*)&r.second.average.value(), sizeof(r.second.average.value())); } } out.resize(in.cur); } bool read(const region_chunk_pos &pos, const zstd::read_ctx& ctx, std::vector &out); void write(const region_chunk_pos &pos, const zstd::write_ctx& ctx, const std::string_view &in, const std::optional& average); private: struct to_save { region_chunk_pos pos; std::unique_ptr> data; std::optional average; }; void save(std::optional added); std::string path; //TODO: use tickets to remove unused regions enum Flags: unsigned char { ZERO = 0, HAS_AVERAGE = 1 << 0, EMPTY = 1 << 1 }; std::shared_mutex mutex; std::ifstream file; struct node { node(const std::optional& a, ushort s, std::streampos o): average(a), size(s), offset(o) { } std::optional average; ushort size; std::streampos offset; }; robin_hood::unordered_map index; void load(); }; }