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 datadriven.api; 7 8 import std.traits : TemplateArgsOf; 9 import std.typecons : BitFlags; 10 11 enum Replication 12 { 13 none, 14 toDb = 1 << 0, 15 toClient = 1 << 1, 16 } 17 18 struct Component { 19 this(string _key, Replication flags) { 20 key = _key; 21 replication = flags; 22 } 23 string key; 24 BitFlags!Replication replication = BitFlags!Replication(Replication.toDb, Replication.toClient); 25 } 26 27 template componentUda(C) 28 { 29 import std.traits : hasUDA, getUDAs; 30 static if (hasUDA!(C, Component)) 31 Component componentUda = getUDAs!(C, Component)[0]; 32 else 33 static assert(false, "Component " ~ C.stringof ~ " has no Component UDA"); 34 } 35 36 alias EntityId = ulong; 37 38 alias componentType(ComponentStorage) = TemplateArgsOf!ComponentStorage[0]; 39 40 // tests if CS is a Component storage of components C 41 template isComponentStorage(CS, C) 42 { 43 enum bool isComponentStorage = is(typeof( 44 (inout int = 0) 45 { 46 CS cs = CS.init; 47 C c = C.init; 48 EntityId id = EntityId.init; 49 50 cs.set(id, c); // Can add component 51 cs.remove(id); // Can remove component 52 C* cptr = cs.get(id); // Can get component pointer 53 54 foreach(key, value; cs) 55 { 56 id = key; 57 c = value = c; 58 } 59 })); 60 } 61 62 // tests if CS is a Component storage of any component type 63 template isAnyComponentStorage(CS) 64 { 65 static if (is(CS.ComponentType C)) 66 enum bool isAnyComponentStorage = isComponentStorage!(CS, C); 67 else 68 enum bool isAnyComponentStorage = false; 69 } 70 71 template isEntitySet(S) 72 { 73 enum bool isEntitySet = is(typeof( 74 (inout int = 0) 75 { 76 S s = S.init; 77 EntityId id = EntityId.init; 78 79 s.set(id); // Can add component 80 s.remove(id); // Can remove component 81 bool contains = s.get(id); // Can check presence 82 83 foreach(key; s) 84 { 85 id = key; 86 } 87 })); 88 } 89 90 unittest 91 { 92 struct A {} 93 struct B 94 { 95 void set(EntityId); 96 void remove(EntityId); 97 bool get(EntityId); 98 int opApply(scope int delegate(in EntityId) del) { 99 return 0; 100 } 101 } 102 struct C 103 { 104 void set(EntityId, int); 105 void remove(EntityId); 106 int* get(EntityId); 107 int opApply(scope int delegate(in EntityId, ref int) del) { 108 return 0; 109 } 110 alias ComponentType = int; 111 } 112 static assert(!isComponentStorage!(A, int)); 113 static assert(!isAnyComponentStorage!A); 114 static assert(!isEntitySet!(A)); 115 116 static assert(!isComponentStorage!(B, int)); 117 static assert(!isAnyComponentStorage!B); 118 static assert( isEntitySet!(B)); 119 120 static assert( isComponentStorage!(C, int)); 121 static assert( isAnyComponentStorage!C); 122 static assert(!isEntitySet!(C)); 123 }