mirror of
https://github.com/Winds-Studio/Leaf.git
synced 2025-12-25 18:09:17 +00:00
fix attribute crash server
This commit is contained in:
@@ -11,7 +11,7 @@ import java.util.*;
|
||||
import java.util.AbstractMap.SimpleEntry;
|
||||
|
||||
// fast array backend map with O(1) get & put & remove
|
||||
public class AttributeInstanceArrayMap implements Map<Holder<Attribute>, AttributeInstance>, Cloneable {
|
||||
public final class AttributeInstanceArrayMap implements Map<Holder<Attribute>, AttributeInstance>, Cloneable {
|
||||
|
||||
private int size = 0;
|
||||
private transient AttributeInstance[] a = new AttributeInstance[32];
|
||||
@@ -46,17 +46,17 @@ public class AttributeInstanceArrayMap implements Map<Holder<Attribute>, Attribu
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int size() {
|
||||
public int size() {
|
||||
return size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean isEmpty() {
|
||||
public boolean isEmpty() {
|
||||
return size == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean containsKey(Object key) {
|
||||
public boolean containsKey(Object key) {
|
||||
if (key instanceof Holder<?> holder && holder.value() instanceof Attribute attribute) {
|
||||
int uid = attribute.uid;
|
||||
return uid >= 0 && uid < a.length && a[uid] != null;
|
||||
@@ -65,22 +65,22 @@ public class AttributeInstanceArrayMap implements Map<Holder<Attribute>, Attribu
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean containsValue(Object value) {
|
||||
for (final AttributeInstance instance : a) {
|
||||
if (Objects.equals(value, instance)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
public boolean containsValue(Object value) {
|
||||
return value instanceof AttributeInstance val && Objects.equals(getInstance(val.getAttribute().value().uid), val);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final AttributeInstance get(Object key) {
|
||||
public AttributeInstance get(Object key) {
|
||||
return key instanceof Holder<?> holder && holder.value() instanceof Attribute attribute ? a[attribute.uid] : null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public AttributeInstance getInstance(int key) {
|
||||
return a[key];
|
||||
}
|
||||
|
||||
@Override
|
||||
public final AttributeInstance put(@NotNull Holder<Attribute> key, AttributeInstance value) {
|
||||
public AttributeInstance put(@NotNull Holder<Attribute> key, AttributeInstance value) {
|
||||
int uid = key.value().uid;
|
||||
AttributeInstance prev = a[uid];
|
||||
setByIndex(uid, value);
|
||||
@@ -88,7 +88,7 @@ public class AttributeInstanceArrayMap implements Map<Holder<Attribute>, Attribu
|
||||
}
|
||||
|
||||
@Override
|
||||
public final AttributeInstance remove(Object key) {
|
||||
public AttributeInstance remove(Object key) {
|
||||
if (!(key instanceof Holder<?> holder) || !(holder.value() instanceof Attribute attribute)) return null;
|
||||
int uid = attribute.uid;
|
||||
AttributeInstance prev = a[uid];
|
||||
@@ -97,7 +97,7 @@ public class AttributeInstanceArrayMap implements Map<Holder<Attribute>, Attribu
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void putAll(@NotNull Map<? extends Holder<Attribute>, ? extends AttributeInstance> m) {
|
||||
public void putAll(@NotNull Map<? extends Holder<Attribute>, ? extends AttributeInstance> m) {
|
||||
for (AttributeInstance e : m.values()) {
|
||||
if (e != null) {
|
||||
setByIndex(e.getAttribute().value().uid, e);
|
||||
@@ -106,13 +106,13 @@ public class AttributeInstanceArrayMap implements Map<Holder<Attribute>, Attribu
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void clear() {
|
||||
public void clear() {
|
||||
Arrays.fill(a, null);
|
||||
size = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final @NotNull Set<Holder<Attribute>> keySet() {
|
||||
public @NotNull Set<Holder<Attribute>> keySet() {
|
||||
if (keys == null) {
|
||||
keys = new KeySet();
|
||||
}
|
||||
@@ -120,7 +120,7 @@ public class AttributeInstanceArrayMap implements Map<Holder<Attribute>, Attribu
|
||||
}
|
||||
|
||||
@Override
|
||||
public final @NotNull Collection<AttributeInstance> values() {
|
||||
public @NotNull Collection<AttributeInstance> values() {
|
||||
if (values == null) {
|
||||
values = new Values();
|
||||
}
|
||||
@@ -128,7 +128,7 @@ public class AttributeInstanceArrayMap implements Map<Holder<Attribute>, Attribu
|
||||
}
|
||||
|
||||
@Override
|
||||
public final @NotNull Set<Entry<Holder<Attribute>, AttributeInstance>> entrySet() {
|
||||
public @NotNull Set<Entry<Holder<Attribute>, AttributeInstance>> entrySet() {
|
||||
if (entries == null) {
|
||||
entries = new EntrySet();
|
||||
}
|
||||
@@ -136,13 +136,23 @@ public class AttributeInstanceArrayMap implements Map<Holder<Attribute>, Attribu
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean equals(Object o) {
|
||||
if (!(o instanceof AttributeInstanceArrayMap that)) return false;
|
||||
return size == that.size && Arrays.equals(a, that.a);
|
||||
public boolean equals(Object o) {
|
||||
if (o == this) return true;
|
||||
if (!(o instanceof Map<?, ?> s)) return false;
|
||||
if (s.size() != size()) return false;
|
||||
if (o instanceof AttributeInstanceArrayMap that) {
|
||||
return Arrays.equals(a, that.a);
|
||||
}
|
||||
for (Entry<?, ?> e : s.entrySet()) {
|
||||
if (!Objects.equals(get(e.getKey()), e.getValue())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int hashCode() {
|
||||
public int hashCode() {
|
||||
return Arrays.hashCode(a);
|
||||
}
|
||||
|
||||
@@ -192,7 +202,7 @@ public class AttributeInstanceArrayMap implements Map<Holder<Attribute>, Attribu
|
||||
if (!hasNext()) throw new NoSuchElementException();
|
||||
currentIndex = nextIndex;
|
||||
nextIndex = findNextOccupied(nextIndex + 1);
|
||||
return BuiltInRegistries.ATTRIBUTE.asHolderIdMap().byIdOrThrow(currentIndex);
|
||||
return BuiltInRegistries.ATTRIBUTE.get(currentIndex).orElseThrow();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -279,7 +289,7 @@ public class AttributeInstanceArrayMap implements Map<Holder<Attribute>, Attribu
|
||||
public Entry<Holder<Attribute>, AttributeInstance> next() {
|
||||
if (!hasNext()) throw new NoSuchElementException();
|
||||
currentIndex = nextIndex;
|
||||
Holder<Attribute> key = BuiltInRegistries.ATTRIBUTE.asHolderIdMap().byIdOrThrow(nextIndex);
|
||||
Holder<Attribute> key = BuiltInRegistries.ATTRIBUTE.get(nextIndex).orElseThrow();
|
||||
AttributeInstance value = a[nextIndex];
|
||||
nextIndex = findNextOccupied(nextIndex + 1);
|
||||
return new SimpleEntry<>(key, value) {
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
package org.dreeam.leaf.util.map;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.IntArraySet;
|
||||
import it.unimi.dsi.fastutil.ints.IntSet;
|
||||
import net.minecraft.world.entity.ai.attributes.AttributeInstance;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.*;
|
||||
|
||||
public final class AttributeInstanceSet extends AbstractCollection<AttributeInstance> implements Set<AttributeInstance> {
|
||||
public final IntSet inner;
|
||||
public final AttributeInstanceArrayMap map;
|
||||
|
||||
public AttributeInstanceSet(AttributeInstanceArrayMap map) {
|
||||
this.map = map;
|
||||
inner = new IntArraySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean add(AttributeInstance instance) {
|
||||
return inner.add(instance.getAttribute().value().uid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remove(Object o) {
|
||||
return o instanceof AttributeInstance instance && inner.remove(instance.getAttribute().value().uid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Iterator<AttributeInstance> iterator() {
|
||||
return new CloneIterator(inner.toIntArray(), map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return inner.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return inner.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
inner.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(Object o) {
|
||||
if (o instanceof AttributeInstance instance) {
|
||||
return inner.contains(instance.getAttribute().value().uid);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AttributeInstance @NotNull [] toArray() {
|
||||
int[] innerClone = inner.toIntArray();
|
||||
AttributeInstance[] arr = new AttributeInstance[innerClone.length];
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
arr[i] = map.getInstance(innerClone[i]);
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
@Override
|
||||
public <T> T @NotNull [] toArray(T[] a) {
|
||||
if (a == null || (a.getClass() == AttributeInstance[].class && a.length == 0)) {
|
||||
return (T[]) toArray();
|
||||
}
|
||||
if (a.length < size()) {
|
||||
a = (T[]) Array.newInstance(a.getClass().getComponentType(), size());
|
||||
}
|
||||
System.arraycopy((T[]) toArray(), 0, a, 0, size());
|
||||
if (a.length > size()) {
|
||||
a[size()] = null;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
static class CloneIterator implements Iterator<AttributeInstance> {
|
||||
private final int[] array;
|
||||
private int index = 0;
|
||||
private final AttributeInstanceArrayMap map;
|
||||
|
||||
CloneIterator(int[] array, AttributeInstanceArrayMap map) {
|
||||
this.array = array;
|
||||
this.map = map;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return index < array.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AttributeInstance next() {
|
||||
if (!hasNext()) throw new NoSuchElementException();
|
||||
return map.getInstance(array[index++]);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o == this) return true;
|
||||
if (!(o instanceof Set<?> s)) return false;
|
||||
if (s.size() != size()) return false;
|
||||
return containsAll(s);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user