1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 package com.lhkbob.entreri.impl;
28
29 import com.lhkbob.entreri.*;
30
31 import java.util.Iterator;
32 import java.util.NoSuchElementException;
33
34
35
36
37
38
39 public final class EntityImpl implements Entity {
40 private final EntitySystemImpl system;
41 private final int id;
42
43 final OwnerSupport delegate;
44
45 int index;
46
47
48
49
50
51
52
53
54
55 EntityImpl(EntitySystemImpl system, int index, int id) {
56 if (system == null) {
57 throw new NullPointerException("System cannot be null");
58 }
59 if (index < 0) {
60 throw new IllegalArgumentException("Index must be at least 0, not: " + index);
61 }
62
63 this.system = system;
64 this.index = index;
65 this.id = id;
66
67 delegate = new OwnerSupport(this);
68 }
69
70 @Override
71 public int getId() {
72 return id;
73 }
74
75 @Override
76 public EntitySystem getEntitySystem() {
77 return system;
78 }
79
80 @Override
81 public boolean isAlive() {
82 return index != 0;
83 }
84
85 @Override
86 public <T extends Component> T get(Class<T> componentType) {
87 ComponentRepository<T> ci = system.getRepository(componentType);
88 return ci.getComponent(ci.getComponentIndex(index));
89 }
90
91 @Override
92 public <T extends Component> T add(Class<T> componentType) {
93 ComponentRepository<T> ci = system.getRepository(componentType);
94 return ci.addComponent(index);
95 }
96
97 @Override
98 public <T extends Component> T as(Class<T> componentType) {
99 ComponentRepository<T> ci = system.getRepository(componentType);
100 int componentIndex = ci.getComponentIndex(index);
101 if (componentIndex > 0) {
102 return ci.getComponent(componentIndex);
103 } else {
104 return ci.addComponent(index);
105 }
106 }
107
108 @Override
109 public boolean has(Class<? extends Component> componentType) {
110 ComponentRepository<?> ci = system.getRepository(componentType);
111 return ci.getComponentIndex(index) > 0;
112 }
113
114 @Override
115 @SuppressWarnings({ "unchecked", "rawtypes" })
116 public <T extends Component> T add(T toClone) {
117 if (toClone == null) {
118 throw new NullPointerException(
119 "ComponentData template, toClone, cannot be null");
120 }
121 ComponentRepository ci = system.getRepository(toClone.getType());
122 return (T) ci.addComponent(index, toClone);
123 }
124
125 @Override
126 public boolean remove(Class<? extends Component> componentType) {
127 ComponentRepository<?> ci = system.getRepository(componentType);
128 return ci.removeComponent(index);
129 }
130
131 @Override
132 public Iterator<Component> iterator() {
133 return new ComponentIterator(system, index);
134 }
135
136
137
138
139
140 private static class ComponentIterator implements Iterator<Component> {
141 private final int entityIndex;
142 private final Iterator<ComponentRepository<?>> indices;
143
144 private ComponentRepository<?> currentIndex;
145 private ComponentRepository<?> nextIndex;
146
147 public ComponentIterator(EntitySystemImpl system, int entityIndex) {
148 this.entityIndex = entityIndex;
149 indices = system.indexIterator();
150 }
151
152 @Override
153 public boolean hasNext() {
154 if (nextIndex == null) {
155 advance();
156 }
157 return nextIndex != null;
158 }
159
160 @Override
161 public Component next() {
162 if (!hasNext()) {
163 throw new NoSuchElementException();
164 }
165
166 currentIndex = nextIndex;
167 nextIndex = null;
168 return currentIndex.getComponent(currentIndex.getComponentIndex(entityIndex));
169 }
170
171 @Override
172 public void remove() {
173 if (currentIndex == null) {
174 throw new IllegalStateException("Must call next first");
175 }
176
177 if (currentIndex.removeComponent(entityIndex)) {
178 currentIndex = null;
179 } else {
180 throw new IllegalStateException("Already removed");
181 }
182 }
183
184 private void advance() {
185 while (indices.hasNext()) {
186 nextIndex = indices.next();
187
188 int index = nextIndex.getComponentIndex(entityIndex);
189 if (index != 0) {
190 break;
191 } else {
192 nextIndex = null;
193 }
194 }
195 }
196 }
197
198 @Override
199 public int compareTo(Entity o) {
200 return id - o.getId();
201 }
202
203 @Override
204 public int hashCode() {
205 return id;
206 }
207
208 @Override
209 public boolean equals(Object o) {
210 return o instanceof EntityImpl && o == this;
211 }
212
213 @Override
214 public Owner notifyOwnershipGranted(Ownable obj) {
215 delegate.notifyOwnershipGranted(obj);
216 return this;
217 }
218
219 @Override
220 public void notifyOwnershipRevoked(Ownable obj) {
221 delegate.notifyOwnershipRevoked(obj);
222 }
223
224 @Override
225 public void setOwner(Owner owner) {
226 delegate.setOwner(owner);
227 }
228
229 @Override
230 public Owner getOwner() {
231 return delegate.getOwner();
232 }
233
234 @Override
235 public String toString() {
236 StringBuilder sb = new StringBuilder("Entity(");
237 sb.append(id);
238
239 Iterator<Component> it = iterator();
240 while (it.hasNext()) {
241 sb.append(",\n\t").append(it.next());
242 }
243
244 sb.append(")");
245 return sb.toString();
246 }
247 }