1 /** 2 Copyright: Copyright (c) 2016-2018 Andrey Penechko. 3 License: $(WEB boost.org/LICENSE_1_0.txt, Boost License 1.0). 4 Authors: Andrey Penechko. 5 */ 6 module voxelman.world.storage.iomanager; 7 8 import voxelman.log; 9 import std.experimental.allocator.mallocator; 10 import std.bitmanip; 11 12 import cbor; 13 import pluginlib; 14 import voxelman.core.config; 15 import voxelman.config.configmanager : ConfigOption, ConfigManager; 16 import voxelman.world.worlddb; 17 import voxelman.utils.mapping; 18 import voxelman.serialization; 19 20 21 alias SaveHandler = void delegate(ref PluginDataSaver); 22 alias LoadHandler = void delegate(ref PluginDataLoader); 23 24 final class IoManager : IResourceManager 25 { 26 package(voxelman.world) LoadHandler[] worldLoadHandlers; 27 package(voxelman.world) SaveHandler[] worldSaveHandlers; 28 StringMap stringMap; 29 30 private: 31 ConfigOption saveDirOpt; 32 ConfigOption worldNameOpt; 33 34 void delegate(string) onPostInit; 35 36 auto dbKey = IoKey(null); 37 void loadStringKeys(ref PluginDataLoader loader) { 38 stringMap.load(loader.readEntryDecoded!(string[])(dbKey)); 39 if (stringMap.strings.length == 0) { 40 stringMap.put(null); // reserve 0 index for string map 41 } 42 } 43 44 void saveStringKeys(ref PluginDataSaver saver) { 45 saver.writeEntryEncoded(dbKey, stringMap.strings); 46 } 47 48 public: 49 this(void delegate(string) onPostInit) 50 { 51 this.onPostInit = onPostInit; 52 stringMap.put(null); // reserve 0 index for string map 53 worldLoadHandlers ~= &loadStringKeys; 54 worldSaveHandlers ~= &saveStringKeys; 55 } 56 57 override string id() @property { return "voxelman.world.iomanager"; } 58 59 override void init(IResourceManagerRegistry resmanRegistry) { 60 ConfigManager config = resmanRegistry.getResourceManager!ConfigManager; 61 saveDirOpt = config.registerOption!string("save_dir", "../../saves"); 62 worldNameOpt = config.registerOption!string("world_name", "world"); 63 } 64 override void postInit() { 65 import std.path : buildPath; 66 import std.file : mkdirRecurse; 67 auto saveFilename = buildPath(saveDirOpt.get!string, worldNameOpt.get!string~".db"); 68 mkdirRecurse(saveDirOpt.get!string); 69 onPostInit(saveFilename); 70 } 71 72 StringMap* getStringMap() { 73 return &stringMap; 74 } 75 76 void registerWorldLoadSaveHandlers(LoadHandler loadHandler, SaveHandler saveHandler) 77 { 78 worldLoadHandlers ~= loadHandler; 79 worldSaveHandlers ~= saveHandler; 80 } 81 }