65 lines
2.1 KiB
C++
65 lines
2.1 KiB
C++
#pragma once
|
|
|
|
#include <string>
|
|
#include <shared_mutex>
|
|
#include <fstream>
|
|
#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_<region_pos> &pos);
|
|
~FileRegion();
|
|
|
|
template<typename D>
|
|
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<char> &out);
|
|
void write(const region_chunk_pos &pos, const zstd::write_ctx& ctx, const std::string_view &in, const std::optional<Voxel>& average);
|
|
|
|
private:
|
|
struct to_save {
|
|
region_chunk_pos pos;
|
|
std::unique_ptr<std::vector<char>> data;
|
|
std::optional<Voxel> average;
|
|
};
|
|
void save(std::optional<to_save> 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<Voxel>& a, uint16_t s, std::streampos o):
|
|
average(a), size(s), offset(o) { }
|
|
std::optional<Voxel> average;
|
|
uint16_t size;
|
|
std::streampos offset;
|
|
};
|
|
robin_hood::unordered_map<region_chunk_pos, node> index;
|
|
|
|
void load();
|
|
};
|
|
} |