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.session.clientdb; 7 8 import netlib : SessionId; 9 import datadriven; 10 import std.typecons : Nullable; 11 import voxelman.world.storage; 12 13 struct ClientDb 14 { 15 private auto ioKey = IoKey("voxelman.session.clientdb.nameToKeyMap"); 16 17 private EntityId[string] nameToKeyMap; 18 EntityManager* eman; 19 20 EntityId getOrCreate(string name, out bool createdNew) { 21 auto idPtr = name in nameToKeyMap; 22 createdNew = false; 23 if (idPtr) 24 return *idPtr; 25 else 26 { 27 createdNew = true; 28 auto newId = eman.eidMan.nextEntityId; 29 nameToKeyMap[name] = newId; 30 return newId; 31 } 32 } 33 34 // returns 0 if doesn't exist 35 EntityId getIdForName(string name) { 36 return nameToKeyMap.get(name, 0); 37 } 38 39 // hasConflict returns true if there is conflict 40 string resolveNameConflict(string conflictingName, 41 bool delegate(string) hasConflict) 42 { 43 import std.regex : matchFirst, regex; 44 import std.conv : to; 45 import voxelman.text.textformatter; 46 47 auto re = regex(`(.*)(\d+)$`, "m"); 48 auto captures = matchFirst(conflictingName, re); 49 50 string firstNamePart = conflictingName; 51 int counter = 1; 52 if (!captures.empty) 53 { 54 firstNamePart = captures[1]; 55 counter = to!int(captures[2]); 56 } 57 58 const(char)[] newName; 59 60 do 61 { 62 newName = makeFormattedText("%s%s", firstNamePart, counter); 63 ++counter; 64 } 65 while(hasConflict(cast(string)newName)); 66 67 return newName.idup; 68 } 69 70 // forward methods of eman 71 bool has(C)(EntityId eid) { return eman.has!C(eid); } 72 void set(C...)(C c) { eman.set(c); } 73 C* get(C)(EntityId eid) { return eman.get!C(eid); } 74 C* getOrCreate(C)(EntityId eid) { return eman.getOrCreate!C(eid); } 75 void remove(C)(EntityId eid) { eman.remove!C(eid); } 76 77 void load(ref PluginDataLoader loader) 78 { 79 loader.readEntryDecoded(ioKey, nameToKeyMap); 80 } 81 82 void save(ref PluginDataSaver saver) 83 { 84 saver.writeEntryEncoded(ioKey, nameToKeyMap); 85 } 86 }