summaryrefslogtreecommitdiff
path: root/terrain_cache.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'terrain_cache.cpp')
-rw-r--r--terrain_cache.cpp73
1 files changed, 73 insertions, 0 deletions
diff --git a/terrain_cache.cpp b/terrain_cache.cpp
new file mode 100644
index 0000000..01cc161
--- /dev/null
+++ b/terrain_cache.cpp
@@ -0,0 +1,73 @@
+#include "terrain_cache.h"
+
+/* TerrainCacheObject */
+
+TerrainCacheObject::TerrainCacheObject(TerrainCache *cache, int64_t x, int64_t y, unsigned int width, unsigned int height, float *heights) {
+ this->cache = cache;
+ this->x = x;
+ this->y = y;
+ this->width = width;
+ this->height = height;
+ if(heights)
+ this->heights = heights;
+ else
+ this->heights = cache->tl->get_chunk(x, y, width, height);
+}
+
+TerrainCacheObject::~TerrainCacheObject() {
+ cache->tl->save_chunk(heights, x, y, width, height);
+ delete[] heights;
+}
+
+/* TerrainCache */
+
+TerrainCache::TerrainCache(fs::path root, size_t max_size) {
+ this->max_size = max_size;
+ tl = TerrainLoader::p(new TerrainLoader(root));
+}
+
+TerrainCache::TerrainCache(TerrainLoader::p loader, size_t max_size) {
+ this->max_size = max_size;
+ tl = loader;
+}
+
+TerrainCache::~TerrainCache() {
+ caches.clear();
+}
+
+TerrainCacheObject::p TerrainCache::make_object(int64_t x, int64_t y, unsigned int width, unsigned int height, float *heights) {
+ TerrainCacheObject::p ob(new TerrainCacheObject(this, x, y, width, height, heights));
+
+ if(caches.size() >= max_size) {
+ for(cache_map::iterator it = caches.begin(); it != caches.end(); it++) {
+ if(it->second.use_count() == 1) {
+ caches.erase(it);
+ break;
+ }
+ }
+ }
+
+ caches.insert(std::pair<intpair, TerrainCacheObject::p>(intpair(x, y), ob));
+ return ob;
+}
+
+TerrainCacheObject::p TerrainCache::get_chunk(int64_t x, int64_t y, unsigned int width, unsigned int height) {
+ cache_map::iterator it = caches.find(intpair(x, y));
+ if(it != caches.end())
+ return it->second;
+
+ return make_object(x, y, width, height);
+}
+
+void TerrainCache::add_chunk(float *heights, int64_t x, int64_t y, unsigned int width, unsigned int height) {
+ cache_map::iterator it = caches.find(intpair(x, y));
+ if(it != caches.end())
+ caches.erase(it);
+
+ tl->save_chunk(heights, x, y, width, height);
+ make_object(x, y, width, height, heights);
+}
+
+size_t TerrainCache::get_size() {
+ return caches.size();
+}