1 /**
2 Copyright: Copyright (c) 2015-2016 Andrey Penechko.
3 License: $(WEB boost.org/LICENSE_1_0.txt, Boost License 1.0).
4 Authors: Andrey Penechko.
5 */
6 module voxelman.storage.worldaccess;
7 
8 import std.experimental.logger;
9 import voxelman.core.config;
10 import voxelman.storage.chunk;
11 import voxelman.storage.coordinates;
12 import voxelman.storage.utils;
13 import voxelman.storage.world;
14 
15 /// When modifying world through WorldAccess
16 /// changes will automatically proparate to client each tick
17 struct WorldAccess
18 {
19 	this(Chunk* delegate(ChunkWorldPos) chunkGetter,
20 		TimestampType delegate() timestampGetter)
21 	{
22 		this.chunkGetter = chunkGetter;
23 		assert(chunkGetter);
24 		this.timestampGetter = timestampGetter;
25 		assert(timestampGetter);
26 	}
27 	@disable this();
28 
29 	BlockType getBlock(BlockWorldPos blockPos)
30 	{
31 		ChunkWorldPos chunkPos = ChunkWorldPos(blockPos);
32 		Chunk* chunk = chunkGetter(chunkPos);
33 		if (chunk)
34 		{
35 			BlockDataSnapshot* snapshot = chunk.getReadableSnapshot(timestampGetter());
36 			if (snapshot)
37 			{
38 				auto blockIndex = BlockChunkIndex(blockPos);
39 				return snapshot.blockData.getBlockType(blockIndex);
40 			}
41 		}
42 
43 		return 0; // unknown block. Indicates that chunk is not loaded.
44 	}
45 
46 	bool setBlock(BlockWorldPos blockPos, BlockType blockType)
47 	{
48 		ChunkWorldPos chunkPos = ChunkWorldPos(blockPos);
49 		Chunk* chunk = chunkGetter(chunkPos);
50 
51 		if (chunk)
52 		{
53 			BlockDataSnapshot* snapshot = chunk.getWriteableSnapshot(timestampGetter());
54 
55 			// chunk was not loaded yet
56 			if (snapshot is null)
57 				return false;
58 
59 			auto blockIndex = BlockChunkIndex(blockPos);
60 			snapshot.blockData.setBlockType(blockIndex, blockType);
61 
62 			foreach(handler; onChunkModifiedHandlers)
63 				handler(chunk, [BlockChange(blockIndex.index, blockType)]);
64 
65 			return true;
66 		}
67 		else
68 			return false;
69 	}
70 
71 	//bool isBlockLoaded(BlockWorldPos blockPos);
72 	//bool loadBlockRange(AABB aabb);
73 	TimestampType currentTimestamp() @property
74 	{
75 		return timestampGetter();
76 	}
77 
78 	void delegate(Chunk*, BlockChange[])[] onChunkModifiedHandlers;
79 private:
80 	Chunk* delegate(ChunkWorldPos) chunkGetter;
81 	TimestampType delegate() timestampGetter;
82 }