diff options
Diffstat (limited to 'src/World/World.cpp')
| -rw-r--r-- | src/World/World.cpp | 69 |
1 files changed, 54 insertions, 15 deletions
diff --git a/src/World/World.cpp b/src/World/World.cpp index 7d1b4ee..1782fd4 100644 --- a/src/World/World.cpp +++ b/src/World/World.cpp @@ -3,33 +3,55 @@ namespace MC::World { std::vector<World::ChunkData> World::get_visible_chunks(Vector<3> position) { + auto finished_chunks = load_finished_chunks_from_queue(); auto visible_chunks = get_visible_chunk_indices(position); - auto difference = visible_chunks; + auto updates = visible_chunks; for (auto index : m_visible_chunks) { - difference.erase(index); + updates.erase(index); + } + for (auto index : finished_chunks) { + updates.insert(index); } - if (!difference.empty()) { - for (auto new_index: difference) { - auto& data = get_or_generate(new_index); - if (!data.mesh.has_value()) { - auto mesh = data.chunk->mesh(); - data.mesh = GFX::Binder::load(mesh); - } - } + if (!updates.empty()) { + process_chunk_visibility_updates(updates); m_visible_chunks = visible_chunks; } std::vector<World::ChunkData> chunks{}; chunks.reserve(visible_chunks.size()); for (auto index : visible_chunks) { - chunks.push_back(get_or_generate(index)); + auto& data = get(index); + if (data.status == ChunkStatus::Done) { + chunks.push_back(data); + } } return chunks; } +void World::process_chunk_visibility_updates(std::unordered_set<ChunkIndex>& new_chunks) { + for (auto new_index: new_chunks) { + auto& data = get(new_index); + switch (data.status) { + case ChunkStatus::Empty: + request_generation(new_index); + data.status = ChunkStatus::InFlight; + break; + case ChunkStatus::InFlight: + // Continue waiting... + break; + case ChunkStatus::Done: + if (!data.mesh.has_value()) { + auto mesh = data.chunk.value().mesh(); + data.mesh = GFX::Binder::load(mesh); + } + break; + } + } +} + std::unordered_set<ChunkIndex> World::get_visible_chunk_indices(Vector<3> position) const { int32_t center_x = std::round(position.x() / Chunk::Width); int32_t center_y = std::round(position.z() / Chunk::Width); @@ -47,11 +69,29 @@ std::unordered_set<ChunkIndex> World::get_visible_chunk_indices(Vector<3> positi return indices; } -World::ChunkData& World::get_or_generate(ChunkIndex index) { +std::unordered_set<ChunkIndex> World::load_finished_chunks_from_queue() { + std::unordered_set<ChunkIndex> indices; + auto results = m_queue.done(); + for (auto& result : results) { + auto& data = get(result.id); + data.chunk = {result.res}; + data.status = ChunkStatus::Done; + indices.insert(result.id); + } + + return indices; +} + +void World::request_generation(ChunkIndex index) { + m_queue.add(index, [=]() { + return m_generator.generate(index.x, index.y); + }); +} + +World::ChunkData& World::get(ChunkIndex index) { auto entry = m_chunks.find(index); if (entry == m_chunks.end()) { - auto chunk = m_generator.generate(index.x, index.y); - ChunkData data{index, std::make_shared<Chunk>(chunk)}; + ChunkData data{index, ChunkStatus::Empty}; m_chunks.insert({index, data}); return m_chunks.at(index); @@ -60,5 +100,4 @@ World::ChunkData& World::get_or_generate(ChunkIndex index) { return entry->second; } - } \ No newline at end of file |
