From 8e9074f55f3452c735a00e128711be0743431cc8 Mon Sep 17 00:00:00 2001 From: Petter Arvidsson Date: Sun, 8 May 2016 18:52:24 +0200 Subject: [PATCH] Handle server updates more intelligently - Handle the new ChunkUpdate message - Keep track of chunks that need updates - If we already have a chunk that needs an update, request it again --- src/chunk_shader.cpp | 27 +++++++++++++++++++++------ src/main.cpp | 12 ++++++++++++ src/world.cpp | 13 ++++++++++++- src/world.h | 5 ++++- 4 files changed, 49 insertions(+), 8 deletions(-) diff --git a/src/chunk_shader.cpp b/src/chunk_shader.cpp index efd48ae..623e9ca 100644 --- a/src/chunk_shader.cpp +++ b/src/chunk_shader.cpp @@ -167,8 +167,9 @@ namespace konstructs { Vector3i pos(p, q, k); int distance = (pos - player_chunk).norm(); int score; + auto it = models.find(pos); + bool is_updated = world.chunk_updated_since_requested(pos); if(chunk_visible(planes, pos)) { - auto it = models.find(pos); if(it != models.end()) { /* Ok, found the model, let's render it! */ @@ -177,10 +178,18 @@ namespace konstructs { c.set(translation, m->translation); c.draw(m); faces += m->faces; - /* We already have a model of the chunk, - * so we really don't need it. - */ - score = NO_CHUNK_FOUND; + if(is_updated) { + /* We already have a model of the chunk, + * but it's outdated, so it needs to be refreshed. + */ + score = distance / 2; + } else { + /* We already have a model of the chunk, + * it didn't change since last requested, + * so we really don't need it. + */ + score = NO_CHUNK_FOUND; + } } else { /* We wanted to render the model, * but we didn't have it, so we really want this chunk! @@ -192,7 +201,13 @@ namespace konstructs { * but if she turns around she might need this chunk * so let's fetch it, but not super urgent */ - score = distance; + if(it != models.end() && !is_updated) { + /* We already have it and it's not updated */ + score = NO_CHUNK_FOUND; + } else { + /* We don't have it or it's update*/ + score = distance; + } } if(score < best_chunk_score && world.chunk_not_requested(pos)) { best_chunk_score = score; diff --git a/src/main.cpp b/src/main.cpp index 6dae131..8a37772 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -366,6 +366,9 @@ class Konstructs: public nanogui::Screen { case 'T': handle_time(packet->to_string()); break; + case 'c': + handle_chunk_updated(packet->to_string()); + break; default: cout << "UNKNOWN: " << packet->type << endl; break; @@ -506,6 +509,15 @@ class Konstructs: public nanogui::Screen { glfwSetTime((double)time_value); } + void handle_chunk_updated(const string &str) { + int p,q,k; + if(sscanf(str.c_str(), ",%d,%d,%d", &p, &q, &k) != 3) { + throw std::runtime_error(str); + } + Vector3i pos(p, q, k); + world.set_chunk_updated(pos); + } + float time_of_day() { if (day_length <= 0) { return 0.5; diff --git a/src/world.cpp b/src/world.cpp index ab78b77..9a5efb2 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -4,11 +4,22 @@ namespace konstructs { void World::request_chunk(const Vector3i &pos, Client &client) { /* Keep track of the chunk so we don't request it again */ requested.insert(pos); + /* Remove requested chunks from updated (we will get the latest update) */ + updated.erase(pos); client.chunk(pos); } + void World::set_chunk_updated(const Vector3i &pos) { + updated.insert(pos); + } + bool World::chunk_not_requested(const Vector3i &pos) const { - return requested.find(pos) == requested.end() && chunks.find(pos) == chunks.end(); + return (updated.find(pos) != updated.end() && chunks.find(pos) != chunks.end()) // Updated and exist in the world + || (requested.find(pos) == requested.end() && chunks.find(pos) == chunks.end()); // Not requested and not in world + } + + bool World::chunk_updated_since_requested(const Vector3i &pos) const { + return updated.find(pos) != updated.end(); } void World::delete_unused_chunks(const Vector3f position, const int radi) { diff --git a/src/world.h b/src/world.h index d09f7bd..b2c98df 100644 --- a/src/world.h +++ b/src/world.h @@ -12,8 +12,10 @@ namespace konstructs { class World { public: void request_chunk(const Vector3i &pos, Client &client); + void set_chunk_updated(const Vector3i &pos); bool chunk_not_requested(const Vector3i &pos) const; -void delete_unused_chunks(const Vector3f position, const int radi); + bool chunk_updated_since_requested(const Vector3i &pos) const; + void delete_unused_chunks(const Vector3f position, const int radi); void insert(std::shared_ptr data); const std::shared_ptr chunk_at(const Vector3i &block_pos) const; const std::shared_ptr chunk(const Vector3i &chunk_pos) const; @@ -23,6 +25,7 @@ void delete_unused_chunks(const Vector3f position, const int radi); private: std::unordered_map, matrix_hash> chunks; std::unordered_set> requested; + std::unordered_set> updated; }; };