-
-
Notifications
You must be signed in to change notification settings - Fork 241
/
voxel_stream_cache.h
73 lines (57 loc) · 2.31 KB
/
voxel_stream_cache.h
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
#ifndef VOXEL_STREAM_CACHE_H
#define VOXEL_STREAM_CACHE_H
#include "../storage/voxel_buffer.h"
#include "../util/containers/std_unordered_map.h"
#include "../util/memory/memory.h"
#include "../util/thread/rw_lock.h"
#include "instance_data.h"
namespace zylann::voxel {
// In-memory database for voxel streams.
// It allows to cache blocks so we can save to the filesystem later less frequently, or quickly reload recent blocks.
class VoxelStreamCache {
public:
struct Block {
Vector3i position;
int lod;
// Absence of voxel data can mean two things:
// - Voxel data has been erased (use case not really implemented yet, but may happen in the future)
// - Voxel data has never been saved over, so should be left untouched
bool has_voxels = false;
bool voxels_deleted = false;
VoxelBuffer voxels;
UniquePtr<InstanceBlockData> instances;
Block() : voxels(VoxelBuffer::ALLOCATOR_POOL) {}
};
// Copies cached block into provided buffer
bool load_voxel_block(Vector3i position, uint8_t lod_index, VoxelBuffer &out_voxels);
// Stores provided block into the cache. The cache will take ownership of the provided data.
void save_voxel_block(Vector3i position, uint8_t lod_index, VoxelBuffer &voxels);
// Copies cached data into the provided pointer. A new instance will be made if found.
bool load_instance_block(Vector3i position, uint8_t lod_index, UniquePtr<InstanceBlockData> &out_instances);
// Stores provided block into the cache. The cache will take ownership of the provided data.
void save_instance_block(Vector3i position, uint8_t lod_index, UniquePtr<InstanceBlockData> instances);
unsigned int get_indicative_block_count() const;
template <typename F>
void flush(F save_func) {
_count = 0;
for (unsigned int lod_index = 0; lod_index < _cache.size(); ++lod_index) {
Lod &lod = _cache[lod_index];
RWLockWrite wlock(lod.rw_lock);
for (auto it = lod.blocks.begin(); it != lod.blocks.end(); ++it) {
Block &block = it->second;
save_func(block);
}
lod.blocks.clear();
}
}
private:
struct Lod {
// Not using pointers for values, since unordered_map does not invalidate pointers to values
StdUnorderedMap<Vector3i, Block> blocks;
RWLock rw_lock;
};
FixedArray<Lod, constants::MAX_LOD> _cache;
unsigned int _count = 0;
};
} // namespace zylann::voxel
#endif // VOXEL_STREAM_CACHE_H