1 module Engine.Entity; 2 3 import Engine.Component; 4 import t = Engine.Transform; 5 import Engine.Core; 6 import Engine.Coroutine; 7 import std.stdio; 8 import Engine.Sprite; 9 import Engine.util; 10 import Engine.CStorage; 11 import std.bitmanip; 12 13 class Entity 14 { 15 package Component[] components; 16 package t.Transform transform_; 17 package ptrdiff_t arrayIndex; 18 BitArray componentsBits; 19 bool active; 20 Sprite sprite; 21 string name; 22 bool valid; 23 24 @property package bool inScene() { 25 return arrayIndex >= 0; 26 }; 27 28 this(bool addTransform = true) 29 { 30 components = new Component[5]; 31 components.length = 0; 32 componentsBits.length = ComponentStorage.bitCounter+1; 33 if (addTransform) 34 AddComponent!(t.Transform)(); 35 active = true; 36 valid = true; 37 arrayIndex = -1; 38 } 39 40 final @property t.Transform transform() { return transform_; } 41 42 final @property public auto Components() { 43 return ConstArray!Component(components); 44 }; 45 46 public void SendMessage(Args...)(string name, Args args) { 47 foreach( c; components) { 48 c.RunFunction(name, args); 49 } 50 } 51 52 public auto AddComponent(T, Args...)(Args args) { 53 auto t = StorageImpl!(T).allocate(args); 54 components ~= new Component(t); 55 StorageImpl!(T).Bind(t,this); 56 setComponentBit(StorageImpl!(T)._bitIndex, true); 57 return t; 58 } 59 60 public auto AddComponent()(Component component) { 61 components ~= component; 62 component.storage.Bind(component.component,this); 63 setComponentBit(component.storage.bitIndex, true); 64 return component; 65 } 66 67 public auto AddComponent(T)(T component) if (!is(T == Component)) { 68 auto c = new Component(component); 69 components ~= c; 70 c.storage.Bind(c.component,this); 71 setComponentBit(c.storage.bitIndex, true); 72 return component; 73 } 74 75 package void setComponentBit(int bit, bool flag) { 76 if (bit >= componentsBits.length) { 77 componentsBits.length = ComponentStorage.bitCounter; 78 } 79 componentsBits[bit] = flag; 80 } 81 82 public auto GetComponent(T)() { 83 alias Tp = pointerType!T; 84 foreach( c; components) { 85 auto t = c.Cast!Tp(); 86 if (t !is null) { 87 return t; 88 } 89 } 90 return null; 91 } 92 93 public Entity Clone() 94 { 95 Entity t = new Entity(false); 96 foreach (ref c ; this.components) { 97 t.AddComponent(c.Clone()); 98 } 99 return t; 100 } 101 102 public void Destory() 103 { 104 if (!valid) 105 return; 106 Core.RemoveEntity(this); 107 foreach( c; components) { 108 c.storage.Remove(c.component); 109 } 110 components.length = 0; 111 components = null; 112 active = false; 113 valid = false; 114 } 115 116 package void onActive() { 117 foreach( c; components) { 118 c.storage.Active(c.component); 119 } 120 } 121 122 public bool RemoveComponent(T)(T component) if (!is(T == Component)) { 123 ComponentStorage storage = StorageImpl!(baseType!T).it; 124 auto found = false; 125 auto left = 0; 126 for (int i=0;i<components.length;i++) { 127 auto c = components[i]; 128 if (c.storage == storage) { 129 if (cast(void*)component == c.component) { 130 components[i] = components[components.length-1]; 131 components.length--; 132 storage.Remove(component.component); 133 found = true; 134 } else { 135 left++; 136 } 137 } 138 } 139 if (found && left == 0) { 140 setComponentBit(storage.bitIndex, false); 141 } 142 return found; 143 } 144 145 146 public bool RemoveComponent()(Component component) { 147 ComponentStorage storage = component.storage; 148 auto found = false; 149 auto left = 0; 150 for (int i=0;i<components.length;i++) { 151 auto c = components[i]; 152 if (c.storage == storage) { 153 if (component.component == c.component) { 154 components[i] = components[components.length-1]; 155 components.length--; 156 storage.Remove(component.component); 157 found = true; 158 } else { 159 left++; 160 } 161 } 162 } 163 if (found && left == 0) { 164 setComponentBit(storage.bitIndex, false); 165 } 166 return found; 167 } 168 169 public bool RemoveComponents(T)() { 170 auto found = false; 171 for (int i=0;i<components.length;i++) { 172 auto component = components[i]; 173 if (component.Cast!T() !is null) { 174 setComponentBit(component.storage.bitIndex, false); 175 components[i] = components[components.length-1]; 176 components.length--; 177 component.storage.Remove(component.component); 178 found = true; 179 } 180 } 181 return found; 182 } 183 } 184 185