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