1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
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();
}
|