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 }