diff options
| -rw-r--r-- | src/Compute/Queue.hpp | 18 | ||||
| -rw-r--r-- | src/Math/Vector.hpp | 4 | ||||
| -rw-r--r-- | src/World/ChunkIndex.hpp | 4 | ||||
| -rw-r--r-- | src/World/World.cpp | 23 | ||||
| -rw-r--r-- | src/World/World.hpp | 8 |
5 files changed, 34 insertions, 23 deletions
diff --git a/src/Compute/Queue.hpp b/src/Compute/Queue.hpp index 6aba1ab..53acc2d 100644 --- a/src/Compute/Queue.hpp +++ b/src/Compute/Queue.hpp @@ -5,7 +5,7 @@ #include <mutex> #include <utility> #include <vector> -#include <iostream> +#include <queue> #include <thread> namespace MC::Compute { @@ -20,9 +20,9 @@ public: } }; - void add(I id, std::function<X()> execute) { + void add(I id, float priority, std::function<X()> execute) { std::scoped_lock work_lock(m_control->work.mutex); - m_control->work.jobs.push_back({id, std::move(execute)}); + m_control->work.jobs.emplace(id, priority, execute); } struct Result { @@ -43,13 +43,19 @@ public: private: struct Job { + Job() = default; + Job(I id, float priority, std::function<X()> execute) : id(id), priority(priority), execute(execute) {} + I id; + float priority; std::function<X()> execute; + + bool operator>(const Job& other) const { return priority > other.priority; } }; struct Work { std::mutex mutex; - std::vector<Job> jobs; + std::priority_queue<Job, std::vector<Job>, std::greater<Job>> jobs; }; struct Results { @@ -71,8 +77,8 @@ private: { std::scoped_lock work_lock(control->work.mutex); if (!control->work.jobs.empty()) { - job = control->work.jobs.back(); - control->work.jobs.pop_back(); + job = control->work.jobs.top(); + control->work.jobs.pop(); nothing_to_do = false; } } diff --git a/src/Math/Vector.hpp b/src/Math/Vector.hpp index 9cc2d75..ccfa556 100644 --- a/src/Math/Vector.hpp +++ b/src/Math/Vector.hpp @@ -65,6 +65,10 @@ public: return map([=](auto x) { return x / m; }); } + T distance(Vector<S, T> other) const { + return (*this - other).magnitude(); + } + Vector<S, T> abs() const { return map([=](auto x) { return std::abs(x); }); } diff --git a/src/World/ChunkIndex.hpp b/src/World/ChunkIndex.hpp index bdb49b3..4701581 100644 --- a/src/World/ChunkIndex.hpp +++ b/src/World/ChunkIndex.hpp @@ -10,6 +10,10 @@ struct ChunkIndex { ChunkIndex() : x(0), y(0) {} ChunkIndex(int32_t x, int32_t y) : x(x), y(y) {} + Vector<3> middle() const { + return {(x + 0.5f) * Chunk::Width, Chunk::Height / 2.0f, (y + 0.5f) * Chunk::Width}; + } + int32_t x, y; }; diff --git a/src/World/World.cpp b/src/World/World.cpp index 1782fd4..9d88af3 100644 --- a/src/World/World.cpp +++ b/src/World/World.cpp @@ -15,7 +15,7 @@ std::vector<World::ChunkData> World::get_visible_chunks(Vector<3> position) { } if (!updates.empty()) { - process_chunk_visibility_updates(updates); + process_chunk_visibility_updates(updates, position); m_visible_chunks = visible_chunks; } @@ -31,22 +31,19 @@ std::vector<World::ChunkData> World::get_visible_chunks(Vector<3> position) { return chunks; } -void World::process_chunk_visibility_updates(std::unordered_set<ChunkIndex>& new_chunks) { +void World::process_chunk_visibility_updates(std::unordered_set<ChunkIndex>& new_chunks, Vector<3> player) { 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... + request_generation(new_index, player.distance(new_index.middle())); + data.status = ChunkStatus::WaitingForGeneration; break; case ChunkStatus::Done: - if (!data.mesh.has_value()) { - auto mesh = data.chunk.value().mesh(); - data.mesh = GFX::Binder::load(mesh); - } + data.mesh = GFX::Binder::load(data.chunk.value().mesh()); + data.status = ChunkStatus::Done; + break; + case ChunkStatus::WaitingForGeneration: break; } } @@ -82,8 +79,8 @@ std::unordered_set<ChunkIndex> World::load_finished_chunks_from_queue() { return indices; } -void World::request_generation(ChunkIndex index) { - m_queue.add(index, [=]() { +void World::request_generation(ChunkIndex index, float priority) { + m_queue.add(index, priority, [=]() { return m_generator.generate(index.x, index.y); }); } diff --git a/src/World/World.hpp b/src/World/World.hpp index dc8f8a7..d842600 100644 --- a/src/World/World.hpp +++ b/src/World/World.hpp @@ -12,11 +12,11 @@ namespace MC::World { class World { public: - World() : m_queue(2), m_chunks(), m_visible_chunks() {} + World() : m_queue(8), m_chunks(), m_visible_chunks() {} enum class ChunkStatus { Empty, - InFlight, + WaitingForGeneration, Done }; @@ -31,8 +31,8 @@ public: private: std::unordered_set<ChunkIndex> get_visible_chunk_indices(Vector<3> position) const; std::unordered_set<ChunkIndex> load_finished_chunks_from_queue(); - void process_chunk_visibility_updates(std::unordered_set<ChunkIndex>& new_chunks); - void request_generation(ChunkIndex index); + void process_chunk_visibility_updates(std::unordered_set<ChunkIndex>& new_chunks, Vector<3> player); + void request_generation(ChunkIndex index, float priority); ChunkData& get(ChunkIndex index); |
