+
+class BlockLookup {
+
+public:
+ // resolve chunk/position from oob coordinates
+ BlockLookup(Chunk *c, const Chunk::Pos &p);
+
+ // resolve chunk/position from ib coordinates and direction
+ BlockLookup(Chunk *c, const Chunk::Pos &p, Block::Face dir);
+
+ // check if lookup was successful
+ operator bool() const { return chunk; }
+
+ // only valid if lookup was successful
+ Chunk &GetChunk() const { return *chunk; }
+ const Chunk::Pos &GetBlockPos() const { return pos; }
+ const Block &GetBlock() const { return GetChunk().BlockAt(GetBlockPos()); }
+ const BlockType &GetType() const { return GetChunk().Type(GetBlock()); }
+ int GetLight() const { return GetChunk().GetLight(GetBlockPos()); }
+
+private:
+ Chunk *chunk;
+ Chunk::Pos pos;
+
+};
+
+
+class Generator;
+
+class ChunkLoader {
+
+public:
+ struct Config {
+ int load_dist = 6;
+ int unload_dist = 8;
+ };
+
+ ChunkLoader(const Config &, const BlockTypeRegistry &, const Generator &);
+
+ void Generate(const Chunk::Pos &from, const Chunk::Pos &to);
+ void GenerateSurrounding(const Chunk::Pos &);
+
+ std::list<Chunk> &Loaded() { return loaded; }
+
+ Chunk *Loaded(const Chunk::Pos &);
+ bool Queued(const Chunk::Pos &);
+ bool Known(const Chunk::Pos &);
+ Chunk &ForceLoad(const Chunk::Pos &);
+
+ void Rebase(const Chunk::Pos &);
+ void Update();
+
+private:
+ Chunk &Generate(const Chunk::Pos &pos);
+ void Insert(Chunk &);
+ void Remove(Chunk &);
+
+private:
+ Chunk::Pos base;
+
+ const BlockTypeRegistry ®
+ const Generator &gen;
+
+ std::list<Chunk> loaded;
+ std::list<Chunk::Pos> to_generate;
+ std::list<Chunk> to_free;
+
+ int load_dist;
+ int unload_dist;
+
+};
+