summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/Compute/Queue.hpp18
-rw-r--r--src/Math/Vector.hpp4
-rw-r--r--src/World/ChunkIndex.hpp4
-rw-r--r--src/World/World.cpp23
-rw-r--r--src/World/World.hpp8
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);