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 12 class Entity 13 { 14 package Component[] components; 15 package t.Transform transform_; 16 package ptrdiff_t arrayIndex; 17 bool active; 18 Sprite sprite; 19 string name; 20 bool valid; 21 22 @property package bool inScene() { 23 return arrayIndex >= 0; 24 }; 25 26 this(bool addTransform = true) 27 { 28 components = new Component[5]; 29 components.length = 0; 30 if (addTransform) 31 AddComponent!(t.Transform)(); 32 active = true; 33 valid = true; 34 arrayIndex = -1; 35 } 36 37 final @property t.Transform transform() { return transform_; } 38 39 final @property public auto Components() { 40 return ConstArray!Component(components); 41 }; 42 43 public void SendMessage(Args...)(string name, Args args) { 44 foreach( c; components) { 45 c.RunFunction(name, args); 46 } 47 } 48 49 public auto AddComponent(T, Args...)(Args args) { 50 auto t = StorageImpl!(T).allocate(args); 51 components ~= new Component(t); 52 StorageImpl!(T).Bind(t,this); 53 return t; 54 } 55 56 public auto AddComponent()(Component component) { 57 components ~= component; 58 component.storage.Bind(component.component,this); 59 return component; 60 } 61 62 public auto AddComponent(T)(T component) if (!is(T == Component)) { 63 auto c = new Component(component); 64 components ~= c; 65 c.storage.Bind(c.component,this); 66 return component; 67 } 68 69 public auto GetComponent(T)() { 70 alias Tp = pointerType!T; 71 foreach( c; components) { 72 auto t = c.Cast!Tp(); 73 if (t !is null) { 74 return t; 75 } 76 } 77 return null; 78 } 79 80 public Entity Clone() 81 { 82 Entity t = new Entity(false); 83 foreach (ref c ; this.components) { 84 t.AddComponent(c.Clone()); 85 } 86 return t; 87 } 88 89 public void Destory() 90 { 91 if (!valid) 92 return; 93 Core.RemoveEntity(this); 94 foreach( c; components) { 95 c.storage.Remove(c.component); 96 } 97 components = null; 98 active = false; 99 valid = false; 100 } 101 102 package void onActive() { 103 foreach( c; components) { 104 c.storage.Active(c.component); 105 } 106 } 107 108 109 public bool RemoveComponent()(Component component) { 110 for (int i=0;i<components.length;i++) { 111 auto component2 = components[i]; 112 if (component.component == component2.component) { 113 component2.storage.Remove(component.component); 114 components[i] = components[components.length-1]; 115 components.length--; 116 return true; 117 } 118 } 119 return false; 120 } 121 122 public bool RemoveComponent(T)() { 123 for (int i=0;i<components.length;i++) { 124 auto component = components[i]; 125 if (component.Cast!T() !is null) { 126 component.storage.Remove(component.component); 127 components[i] = components[components.length-1]; 128 components.length--; 129 return true; 130 } 131 } 132 return false; 133 } 134 135 public bool RemoveComponents(T)() { 136 bool removed = false; 137 for (int i=0;i<components.length;i++) { 138 auto component = components[i]; 139 if (component.Cast!T() !is null) { 140 component.storage.Remove(component.component); 141 components[i] = components[components.length-1]; 142 components.length--; 143 removed = true; 144 } 145 } 146 return removed; 147 } 148 } 149 150