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.world;
7 
8 import std.experimental.logger;
9 import std.file : readFile = read, writeFile = write, exists, mkdirRecurse, isValidPath;
10 import std.path : absolutePath, buildPath, buildNormalizedPath;
11 
12 import cbor;
13 import dlib.math.vector;
14 
15 import voxelman.core.config;
16 import voxelman.storage.chunkprovider;
17 import voxelman.storage.chunkstorage;
18 import voxelman.storage.worldaccess;
19 
20 struct WorldInfo
21 {
22 	string name = DEFAULT_WORLD_NAME;
23 	TimestampType simulationTick;
24 	ivec3 spawnPosition;
25 	//block mapping
26 }
27 
28 private ubyte[1024] buffer;
29 
30 struct World
31 {
32 	WorldInfo worldInfo;
33 
34 	string worldDirectory;
35 	string worldInfoFilename = WORLD_FILE_NAME;
36 
37 	void init(string worldDir)
38 	{
39 		assert(isValidPath(worldDir));
40 
41 		worldDirectory = worldDir.absolutePath.buildNormalizedPath;
42 		worldInfoFilename = buildPath(worldDirectory, WORLD_FILE_NAME);
43 	}
44 
45 	TimestampType currentTimestamp() @property
46 	{
47 		return worldInfo.simulationTick;
48 	}
49 
50 	void update()
51 	{
52 		++worldInfo.simulationTick;
53 	}
54 
55 	void save()
56 	{
57 		writeWorldInfo();
58 		infof("saved world '%s'", worldInfoFilename);
59 	}
60 
61 	void load()
62 	{
63 		if (!exists(worldDirectory))
64 		{
65 			mkdirRecurse(worldDirectory);
66 		}
67 
68 		if (!exists(worldInfoFilename))
69 		{
70 			writeWorldInfo();
71 			return;
72 		}
73 
74 		readWorldInfo();
75 		infof("loaded world %s %s", worldInfoFilename, worldInfo);
76 	}
77 
78 	private void readWorldInfo()
79 	{
80 		ubyte[] data = cast(ubyte[])readFile(worldInfoFilename, 1024);
81 		worldInfo = decodeCborSingleDup!WorldInfo(data);
82 	}
83 
84 	private void writeWorldInfo()
85 	{
86 		ubyte[] bufferTemp = buffer;
87 		size_t size = encodeCbor(bufferTemp[], worldInfo);
88 		writeFile(worldInfoFilename, bufferTemp[0..size]);
89 	}
90 }