1 /** 2 Component facilities module. 3 4 Copyright: © 2015-2016 Claude Merle 5 Authors: Claude Merle 6 License: This file is part of EntitySysD. 7 8 EntitySysD is free software: you can redistribute it and/or modify it 9 under the terms of the Lesser GNU General Public License as published 10 by the Free Software Foundation, either version 3 of the License, or 11 (at your option) any later version. 12 13 EntitySysD is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 Lesser GNU General Public License for more details. 17 18 You should have received a copy of the Lesser GNU General Public License 19 along with EntitySysD. If not, see $(LINK http://www.gnu.org/licenses/). 20 */ 21 22 module entitysysd.component; 23 24 // UDA for component types 25 enum component; 26 27 /** 28 * To be a valid component, $(D C) must: 29 * - be a $(D struct) or $(D union) 30 * - have the UDA $(D component) 31 * - must contain fields without $(D shared) qualifier) 32 */ 33 template isComponent(C) 34 { 35 import std.meta : allSatisfy; 36 import std.traits : RepresentationTypeTuple, isMutable, hasUDA; 37 38 enum bool isNotShared(F) = !is(F == shared); 39 static if (__traits(compiles, hasUDA!(C, component))) 40 enum bool isComponent = (is(C == struct) || is(C == union)) && 41 hasUDA!(C, component) && 42 allSatisfy!(isNotShared, 43 RepresentationTypeTuple!C); 44 else 45 enum bool isComponent = false; 46 } 47 48 template areComponents(CList...) 49 { 50 import std.meta : allSatisfy; 51 enum bool areComponents = allSatisfy!(isComponent, CList); 52 } 53 54 55 struct BaseComponentCounter 56 { 57 static size_t counter = 0; 58 } 59 60 struct ComponentCounter(Derived) 61 { 62 public: 63 static size_t getId() 64 { 65 static size_t counter = -1; 66 if (counter == -1) 67 { 68 counter = mBaseComponentCounter.counter; 69 mBaseComponentCounter.counter++; 70 } 71 72 return counter; 73 } 74 75 private: 76 BaseComponentCounter mBaseComponentCounter; 77 } 78 79 80 //****************************************************************************** 81 //***** UNIT-TESTS 82 //****************************************************************************** 83 84 /// 85 unittest 86 { 87 @component struct TestComponent0 88 { 89 int a, b; 90 } 91 92 @component class TestComponent1 // component cannot be a class 93 { 94 string str; 95 } 96 97 @component union TestComponent2 98 { 99 float f; 100 uint u; 101 } 102 103 static assert(!isComponent!int); 104 static assert(isComponent!TestComponent0); 105 static assert(!isComponent!TestComponent1); 106 static assert(isComponent!TestComponent2); 107 }