9
0
mirror of https://github.com/Winds-Studio/Leaf.git synced 2025-12-26 02:19:19 +00:00

Replace GoalSelector#availableGoals with optimized collection (#465)

* optimize goal selector

* rebase

* rebase

---------

Co-authored-by: Taiyou06 <kaandindar21@gmail.com>
This commit is contained in:
hayanesuru
2025-08-20 04:48:46 +09:00
committed by GitHub
parent 23b7b02eee
commit 037ec255d4
2 changed files with 406 additions and 0 deletions

View File

@@ -0,0 +1,216 @@
package org.dreeam.leaf.util.map;
import net.minecraft.world.entity.ai.goal.WrappedGoal;
import org.jetbrains.annotations.NotNull;
import java.util.*;
import java.util.function.Predicate;
public final class BinaryGoalSet extends AbstractSet<WrappedGoal> {
private static final WrappedGoal[] EMPTY_ARRAY = {};
private WrappedGoal[] a;
private int size;
private static final int DEFAULT_CAPACITY = 4;
public BinaryGoalSet() {
this.a = EMPTY_ARRAY;
}
@Override
public int size() {
return size;
}
@Override
public void clear() {
Arrays.fill(a, 0, size, null);
size = 0;
}
@Override
public boolean isEmpty() {
return size == 0;
}
@Override
public boolean add(final WrappedGoal goal) {
Objects.requireNonNull(goal);
if (size == a.length) {
grow();
}
final int priority = goal.getPriority();
int left = 0;
int right = size;
while (left < right) {
final int mid = (left + right) >>> 1;
if (a[mid].getPriority() < priority) {
left = mid + 1;
} else {
right = mid;
}
}
int gap = left;
while (gap < size && a[gap].getPriority() == priority) {
if (a[gap] == goal) {
return false;
}
gap++;
}
if (left < size) {
System.arraycopy(a, left, a, left + 1, size - left);
}
a[left] = goal;
size++;
return true;
}
@Override
public boolean remove(final Object obj) {
if (!(obj instanceof final WrappedGoal goal)) {
return false;
}
final int priority = goal.getPriority();
int left = 0;
int right = size;
while (left < right) {
final int mid = (left + right) >>> 1;
if (a[mid].getPriority() < priority) {
left = mid + 1;
} else {
right = mid;
}
}
int gap = -1;
for (int i = left; i < size && a[i].getPriority() == priority; i++) {
if (a[i] == goal) {
gap = i;
break;
}
}
if (gap == -1) {
return false;
}
if (gap < size - 1) {
System.arraycopy(a, gap + 1, a, gap, size - gap - 1);
}
size--;
a[size] = null;
return true;
}
@Override
public boolean removeIf(@NotNull final Predicate<? super WrappedGoal> filter) {
Objects.requireNonNull(filter);
boolean removed = false;
for (int i = size - 1; i >= 0; i--) {
final WrappedGoal e = a[i];
if (!filter.test(e)) {
continue;
}
if (i < size - 1) {
System.arraycopy(a, i + 1, a, i, size - i - 1);
}
size--;
a[size] = null;
removed = true;
}
return removed;
}
@Override
public boolean contains(final Object obj) {
if (!(obj instanceof final WrappedGoal goal)) {
return false;
}
final int priority = goal.getPriority();
int left = 0;
int right = size;
while (left < right) {
final int mid = (left + right) >>> 1;
if (a[mid].getPriority() < priority) {
left = mid + 1;
} else {
right = mid;
}
}
for (int i = left; i < size && a[i].getPriority() == priority; i++) {
if (a[i] == goal) {
return true;
}
}
return false;
}
private void grow() {
final int capacity = (a.length == 0) ? DEFAULT_CAPACITY : a.length + (a.length >> 1);
final WrappedGoal[] newArray = new WrappedGoal[capacity];
System.arraycopy(a, 0, newArray, 0, size);
a = newArray;
}
@Override
@NotNull
public Iterator<WrappedGoal> iterator() {
return new Iterator<>() {
private int cursor = 0;
private int last = -1;
@Override
public boolean hasNext() {
return cursor < size;
}
@Override
public WrappedGoal next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
last = cursor;
return a[cursor++];
}
@Override
public void remove() {
if (last == -1) {
throw new IllegalStateException();
}
System.arraycopy(a, last + 1, a, last, size - last - 1);
size--;
a[size] = null;
cursor = last;
last = -1;
}
};
}
@Override
public int hashCode() {
int result = 0;
for (int i = 0, j = size; i < j; i++) {
final WrappedGoal e = a[i];
result += e == null ? 0 : e.hashCode();
}
return result;
}
public WrappedGoal[] elements() {
return a;
}
}