1package com.osroyale.game.world.entity;
3import com.osroyale.game.world.entity.mob.Mob;
4import com.osroyale.util.RandomUtils;
7import java.util.function.Consumer;
8import java.util.function.Predicate;
9import java.util.stream.Collectors;
10import java.util.stream.IntStream;
11import java.util.stream.Stream;
12import java.util.stream.StreamSupport;
14import static com.google.common.base.Preconditions.*;
26public final class MobList<E
extends Mob> implements Iterable<E> {
36 public static final class EntityListIterator<E
extends Mob> implements Iterator<E> {
45 private int prev = -1;
58 public boolean hasNext() {
59 return curr < list.capacity() && skipNullIndexes();
65 checkPositionIndex(curr, list.capacity(),
"No elements left");
66 E entity = list.element(curr);
72 public void remove() {
73 checkState(prev != -1,
"remove() can only be called once after each call to next()");
75 list.remove(list.get(prev));
86 private boolean skipNullIndexes() {
87 while (list.get(curr) ==
null) {
88 if (++curr >= list.capacity()) {
97 private final E[] entities;
100 private final TreeSet<Integer> indices;
106 private int largestIndex;
113 @SuppressWarnings(
"unchecked")
116 Stream<Integer> indexStream = IntStream.rangeClosed(1,
capacity).boxed();
117 indices =
new TreeSet<>(indexStream.collect(Collectors.toList()));
121 public Iterator<E> iterator() {
122 return new EntityListIterator<>(
this);
131 for (
int index = largestIndex; index > 1; index--) {
132 int first = index - 1;
133 int second = RandomUtils.inclusive(1, index);
134 if (first == second)
continue;
136 E tmp = entities[first];
137 entities[first] = entities[second];
138 entities[second] = tmp;
140 if (entities[first] !=
null) {
141 entities[first].setListIndex(first);
144 if (entities[second] !=
null) {
145 entities[second].setListIndex(second);
162 public void forEach(Consumer<? super E> action) {
164 for (E e : entities) {
165 if (e ==
null)
continue;
167 if (++index >= size)
return;
178 public Optional<E>
findFirst(Predicate<? super E> filter) {
180 if (filter.test(e)) {
181 return Optional.of(e);
184 return Optional.empty();
194 public Optional<E>
findLast(Predicate<? super E> filter) {
195 for (
int index =
capacity(); index > 1; index--) {
196 E entity = entities[index];
197 if (entity ==
null) {
200 if (filter.test(entity)) {
201 return Optional.of(entity);
204 return Optional.empty();
213 public List<E>
findAll(Predicate<? super E> filter) {
214 List<E> list =
new ArrayList<>();
216 if (filter.test(e)) {
231 return Spliterators.spliterator(entities, Spliterator.ORDERED | Spliterator.DISTINCT);
240 public boolean add(E entity) {
241 Integer index = indices.pollFirst();
243 if (index ==
null || index ==
capacity()) {
247 if (index > largestIndex) {
248 largestIndex = index;
251 entities[index] = entity;
252 entity.setIndex(index);
253 entity.setListIndex(index);
264 public boolean remove(E entity) {
265 checkArgument(entity.getListIndex() != -1,
"index == -1");
266 indices.add(entity.getListIndex());
267 entities[entity.getListIndex()] =
null;
279 public void remove(
int index) {
280 remove(entities[index]);
289 public E
get(
int index) {
290 return entities[index];
302 E entity =
get(index);
303 checkArgument(entity !=
null,
"index -> null EntityNode");
315 return entity !=
null && entity.equals(
get(entity.getListIndex()));
350 return entities.length;
360 return Arrays.copyOf(entities, entities.length);
375 return StreamSupport.stream(
spliterator(),
false).filter(Objects::nonNull);
383 Spliterator<E> split = Spliterators.spliterator(entities,
spliterator().characteristics() | Spliterator.IMMUTABLE);
384 return StreamSupport.stream(split,
true).filter(Objects::nonNull);
Stream< E > parallelStream()
void forEach(Consumer<? super E > action)
Optional< E > findFirst(Predicate<? super E > filter)
Optional< E > findLast(Predicate<? super E > filter)
List< E > findAll(Predicate<? super E > filter)
boolean contains(E entity)
Spliterator< E > spliterator()