mirror of
https://github.com/Winds-Studio/Leaf.git
synced 2025-12-25 09:59:15 +00:00
avoid registry (un)boxing in attribute map and activity map
This commit is contained in:
@@ -1,6 +1,9 @@
|
||||
package org.dreeam.leaf.util;
|
||||
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.world.entity.ai.attributes.Attribute;
|
||||
import net.minecraft.world.entity.schedule.Activity;
|
||||
|
||||
public final class RegistryTypeManager {
|
||||
|
||||
@@ -9,6 +12,9 @@ public final class RegistryTypeManager {
|
||||
*/
|
||||
public static final int ATTRIBUTE_SIZE;
|
||||
public static final int ACTIVITY_SIZE;
|
||||
public static final Holder<Attribute>[] ATTRIBUTE;
|
||||
|
||||
public static final Activity[] ACTIVITY_DIRECT;
|
||||
|
||||
static {
|
||||
ATTRIBUTE_SIZE = BuiltInRegistries.ATTRIBUTE.size();
|
||||
@@ -19,6 +25,20 @@ public final class RegistryTypeManager {
|
||||
if (ACTIVITY_SIZE > 32) {
|
||||
throw new ExceptionInInitializerError("minecraft:activity out of range int bitset (>32)");
|
||||
}
|
||||
ATTRIBUTE = new Holder[ATTRIBUTE_SIZE];
|
||||
for (int i = 0; i < ATTRIBUTE_SIZE; i++) {
|
||||
ATTRIBUTE[i] = BuiltInRegistries.ATTRIBUTE.get(i).orElseThrow();
|
||||
if (ATTRIBUTE[i].value().uid != i) {
|
||||
throw new ExceptionInInitializerError();
|
||||
}
|
||||
}
|
||||
ACTIVITY_DIRECT = new Activity[ACTIVITY_SIZE];
|
||||
for (int i = 0; i < ACTIVITY_SIZE; i++) {
|
||||
ACTIVITY_DIRECT[i] = BuiltInRegistries.ACTIVITY.byIdOrThrow(i);
|
||||
if (ACTIVITY_DIRECT[i].id != i) {
|
||||
throw new ExceptionInInitializerError();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private RegistryTypeManager() {
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package org.dreeam.leaf.util.map;
|
||||
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.world.entity.schedule.Activity;
|
||||
import org.dreeam.leaf.util.RegistryTypeManager;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.AbstractMap.SimpleEntry;
|
||||
|
||||
public final class ActivityArrayMap<V> implements Map<Activity, V> {
|
||||
|
||||
@@ -26,7 +26,7 @@ public final class ActivityArrayMap<V> implements Map<Activity, V> {
|
||||
if ((bitset & mask) == 0) {
|
||||
return -1;
|
||||
}
|
||||
for (int i = 0; i < size; i++) {
|
||||
for (int i = 0, j = size; i < j; i++) {
|
||||
if (k[i] == activity) {
|
||||
return i;
|
||||
}
|
||||
@@ -56,7 +56,8 @@ public final class ActivityArrayMap<V> implements Map<Activity, V> {
|
||||
|
||||
@Override
|
||||
public V put(Activity key, V value) {
|
||||
int index = findIndex(key.id);
|
||||
int raw = key.id;
|
||||
int index = findIndex(raw);
|
||||
if (index >= 0) {
|
||||
final V oldValue = v[index];
|
||||
if (value == null) {
|
||||
@@ -67,9 +68,9 @@ public final class ActivityArrayMap<V> implements Map<Activity, V> {
|
||||
return oldValue;
|
||||
} else if (value != null) {
|
||||
ensureCap();
|
||||
k[size] = key.id;
|
||||
k[size] = raw;
|
||||
v[size] = value;
|
||||
bitset |= (1 << key.id);
|
||||
bitset |= (1 << raw);
|
||||
size++;
|
||||
}
|
||||
return null;
|
||||
@@ -150,6 +151,7 @@ public final class ActivityArrayMap<V> implements Map<Activity, V> {
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public Set<Activity> keySet() {
|
||||
if (keySet == null) {
|
||||
keySet = new KeySet();
|
||||
@@ -158,6 +160,7 @@ public final class ActivityArrayMap<V> implements Map<Activity, V> {
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public Collection<V> values() {
|
||||
if (values == null) {
|
||||
values = new Values();
|
||||
@@ -166,6 +169,7 @@ public final class ActivityArrayMap<V> implements Map<Activity, V> {
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public Set<Entry<Activity, V>> entrySet() {
|
||||
if (entrySet == null) {
|
||||
entrySet = new EntrySet();
|
||||
@@ -175,6 +179,7 @@ public final class ActivityArrayMap<V> implements Map<Activity, V> {
|
||||
|
||||
private final class KeySet extends AbstractSet<Activity> {
|
||||
@Override
|
||||
@NotNull
|
||||
public Iterator<Activity> iterator() {
|
||||
return new Iterator<>() {
|
||||
private int index = 0;
|
||||
@@ -189,7 +194,7 @@ public final class ActivityArrayMap<V> implements Map<Activity, V> {
|
||||
public Activity next() {
|
||||
if (!hasNext()) throw new NoSuchElementException();
|
||||
lastReturned = index;
|
||||
return BuiltInRegistries.ACTIVITY.byIdOrThrow(k[index++]);
|
||||
return RegistryTypeManager.ACTIVITY_DIRECT[k[index++]];
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -220,9 +225,11 @@ public final class ActivityArrayMap<V> implements Map<Activity, V> {
|
||||
|
||||
private final class Values extends AbstractCollection<V> {
|
||||
@Override
|
||||
@NotNull
|
||||
public Iterator<V> iterator() {
|
||||
return new Iterator<>() {
|
||||
private int index = 0;
|
||||
private int lastReturned = -1;
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
@@ -232,8 +239,17 @@ public final class ActivityArrayMap<V> implements Map<Activity, V> {
|
||||
@Override
|
||||
public V next() {
|
||||
if (!hasNext()) throw new NoSuchElementException();
|
||||
lastReturned = index;
|
||||
return v[index++];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
if (lastReturned < 0) throw new IllegalStateException();
|
||||
ActivityArrayMap.this.removeAtIndex(lastReturned);
|
||||
index = lastReturned;
|
||||
lastReturned = -1;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -255,6 +271,7 @@ public final class ActivityArrayMap<V> implements Map<Activity, V> {
|
||||
|
||||
private final class EntrySet extends AbstractSet<Entry<Activity, V>> {
|
||||
@Override
|
||||
@NotNull
|
||||
public Iterator<Entry<Activity, V>> iterator() {
|
||||
return new Iterator<>() {
|
||||
private int index = 0;
|
||||
@@ -272,7 +289,7 @@ public final class ActivityArrayMap<V> implements Map<Activity, V> {
|
||||
int key = k[index];
|
||||
V value = v[index];
|
||||
index++;
|
||||
return new SimpleEntry<>(BuiltInRegistries.ACTIVITY.byIdOrThrow(key), value);
|
||||
return new MapEntry(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -307,6 +324,51 @@ public final class ActivityArrayMap<V> implements Map<Activity, V> {
|
||||
}
|
||||
}
|
||||
|
||||
private final class MapEntry implements Entry<Activity, V> {
|
||||
private final int key;
|
||||
private V value;
|
||||
|
||||
MapEntry(int key, V value) {
|
||||
this.key = key;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Activity getKey() {
|
||||
return RegistryTypeManager.ACTIVITY_DIRECT[key];
|
||||
}
|
||||
|
||||
@Override
|
||||
public V getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public V setValue(V value) {
|
||||
V oldValue = this.value;
|
||||
this.value = value;
|
||||
ActivityArrayMap.this.put(RegistryTypeManager.ACTIVITY_DIRECT[key], value);
|
||||
return oldValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof Entry<?, ?> entry)) return false;
|
||||
return Objects.equals(RegistryTypeManager.ACTIVITY_DIRECT[key], entry.getKey()) && Objects.equals(value, entry.getValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(key) ^ Objects.hashCode(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return key + "=" + value;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
|
||||
@@ -2,7 +2,6 @@ package org.dreeam.leaf.util.map;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.AbstractObjectSet;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectIterator;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.world.entity.schedule.Activity;
|
||||
import org.dreeam.leaf.util.RegistryTypeManager;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -27,10 +26,6 @@ public final class ActivityBitSet extends AbstractObjectSet<Activity> {
|
||||
return bitset;
|
||||
}
|
||||
|
||||
private static Activity map(int i) {
|
||||
return BuiltInRegistries.ACTIVITY.byIdOrThrow(i);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean add(Activity activity) {
|
||||
int mask = 1 << activity.id;
|
||||
@@ -76,7 +71,7 @@ public final class ActivityBitSet extends AbstractObjectSet<Activity> {
|
||||
@Override
|
||||
public Activity next() {
|
||||
if (!hasNext()) throw new NoSuchElementException();
|
||||
Activity act = map(index++);
|
||||
Activity act = RegistryTypeManager.ACTIVITY_DIRECT[index++];
|
||||
while (index < RegistryTypeManager.ACTIVITY_SIZE && (bitset & (1 << index)) == 0) {
|
||||
index++;
|
||||
}
|
||||
@@ -109,7 +104,7 @@ public final class ActivityBitSet extends AbstractObjectSet<Activity> {
|
||||
int hash = 0;
|
||||
for (int i = 0; i < RegistryTypeManager.ACTIVITY_SIZE; i++) {
|
||||
if ((bitset & (1 << i)) != 0) {
|
||||
hash += map(i).hashCode();
|
||||
hash += RegistryTypeManager.ACTIVITY_DIRECT[i].hashCode();
|
||||
}
|
||||
}
|
||||
return hash;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package org.dreeam.leaf.util.map;
|
||||
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.world.entity.ai.attributes.Attribute;
|
||||
import net.minecraft.world.entity.ai.attributes.AttributeInstance;
|
||||
import org.dreeam.leaf.util.RegistryTypeManager;
|
||||
@@ -9,7 +8,6 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.AbstractMap.SimpleEntry;
|
||||
|
||||
// fast array backend map with O(1) get & put & remove
|
||||
public final class AttributeInstanceArrayMap implements Map<Holder<Attribute>, AttributeInstance>, Cloneable {
|
||||
@@ -21,11 +19,9 @@ public final class AttributeInstanceArrayMap implements Map<Holder<Attribute>, A
|
||||
private transient EntrySet entries;
|
||||
|
||||
public AttributeInstanceArrayMap() {
|
||||
// The check for a fixed vanilla size is no longer necessary
|
||||
}
|
||||
|
||||
public AttributeInstanceArrayMap(final @NotNull Map<Holder<Attribute>, AttributeInstance> m) {
|
||||
this();
|
||||
putAll(m);
|
||||
}
|
||||
|
||||
@@ -111,7 +107,8 @@ public final class AttributeInstanceArrayMap implements Map<Holder<Attribute>, A
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Set<Holder<Attribute>> keySet() {
|
||||
@NotNull
|
||||
public Set<Holder<Attribute>> keySet() {
|
||||
if (keys == null) {
|
||||
keys = new KeySet();
|
||||
}
|
||||
@@ -119,7 +116,8 @@ public final class AttributeInstanceArrayMap implements Map<Holder<Attribute>, A
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Collection<AttributeInstance> values() {
|
||||
@NotNull
|
||||
public Collection<AttributeInstance> values() {
|
||||
if (values == null) {
|
||||
values = new Values();
|
||||
}
|
||||
@@ -127,7 +125,8 @@ public final class AttributeInstanceArrayMap implements Map<Holder<Attribute>, A
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Set<Entry<Holder<Attribute>, AttributeInstance>> entrySet() {
|
||||
@NotNull
|
||||
public Set<Entry<Holder<Attribute>, AttributeInstance>> entrySet() {
|
||||
if (entries == null) {
|
||||
entries = new EntrySet();
|
||||
}
|
||||
@@ -201,7 +200,7 @@ public final class AttributeInstanceArrayMap implements Map<Holder<Attribute>, A
|
||||
if (!hasNext()) throw new NoSuchElementException();
|
||||
currentIndex = nextIndex;
|
||||
nextIndex = findNextOccupied(nextIndex + 1);
|
||||
return BuiltInRegistries.ATTRIBUTE.get(currentIndex).orElseThrow();
|
||||
return RegistryTypeManager.ATTRIBUTE[currentIndex];
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -288,17 +287,9 @@ public final class AttributeInstanceArrayMap implements Map<Holder<Attribute>, A
|
||||
public Entry<Holder<Attribute>, AttributeInstance> next() {
|
||||
if (!hasNext()) throw new NoSuchElementException();
|
||||
currentIndex = nextIndex;
|
||||
Holder<Attribute> key = BuiltInRegistries.ATTRIBUTE.get(nextIndex).orElseThrow();
|
||||
AttributeInstance value = a[nextIndex];
|
||||
nextIndex = findNextOccupied(nextIndex + 1);
|
||||
return new SimpleEntry<>(key, value) {
|
||||
@Override
|
||||
public AttributeInstance setValue(AttributeInstance newValue) {
|
||||
AttributeInstance old = put(key, newValue);
|
||||
super.setValue(newValue);
|
||||
return old;
|
||||
}
|
||||
};
|
||||
return new MapEntry(currentIndex, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -311,6 +302,51 @@ public final class AttributeInstanceArrayMap implements Map<Holder<Attribute>, A
|
||||
}
|
||||
}
|
||||
|
||||
private final class MapEntry implements Entry<Holder<Attribute>, AttributeInstance> {
|
||||
private final int key;
|
||||
private AttributeInstance value;
|
||||
|
||||
MapEntry(int key, AttributeInstance value) {
|
||||
this.key = key;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Holder<Attribute> getKey() {
|
||||
return RegistryTypeManager.ATTRIBUTE[this.key];
|
||||
}
|
||||
|
||||
@Override
|
||||
public AttributeInstance getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AttributeInstance setValue(AttributeInstance newValue) {
|
||||
AttributeInstance oldValue = this.value;
|
||||
this.value = newValue;
|
||||
AttributeInstanceArrayMap.this.setByIndex(this.key, newValue);
|
||||
return oldValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof Entry<?, ?> entry)) return false;
|
||||
return Objects.equals(RegistryTypeManager.ATTRIBUTE[key], entry.getKey()) && Objects.equals(value, entry.getValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(key) ^ Objects.hashCode(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return key + "=" + value;
|
||||
}
|
||||
}
|
||||
|
||||
private int findNextOccupied(int start) {
|
||||
for (int i = start; i < a.length; i++) {
|
||||
if (a[i] != null) {
|
||||
@@ -319,4 +355,8 @@ public final class AttributeInstanceArrayMap implements Map<Holder<Attribute>, A
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public AttributeInstance[] elements() {
|
||||
return a;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
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.Attribute;
|
||||
import net.minecraft.world.entity.ai.attributes.AttributeInstance;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -9,7 +9,7 @@ import java.lang.reflect.Array;
|
||||
import java.util.*;
|
||||
|
||||
public final class AttributeInstanceSet extends AbstractCollection<AttributeInstance> implements Set<AttributeInstance> {
|
||||
public final IntSet inner;
|
||||
public final IntArraySet inner;
|
||||
public final AttributeInstanceArrayMap map;
|
||||
|
||||
public AttributeInstanceSet(AttributeInstanceArrayMap map) {
|
||||
@@ -22,6 +22,10 @@ public final class AttributeInstanceSet extends AbstractCollection<AttributeInst
|
||||
return inner.add(instance.getAttribute().value().uid);
|
||||
}
|
||||
|
||||
public boolean addAttribute(Attribute attribute) {
|
||||
return inner.add(attribute.uid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remove(Object o) {
|
||||
return o instanceof AttributeInstance instance && inner.remove(instance.getAttribute().value().uid);
|
||||
@@ -81,7 +85,7 @@ public final class AttributeInstanceSet extends AbstractCollection<AttributeInst
|
||||
return a;
|
||||
}
|
||||
|
||||
static class CloneIterator implements Iterator<AttributeInstance> {
|
||||
private static final class CloneIterator implements Iterator<AttributeInstance> {
|
||||
private final int[] array;
|
||||
private int index = 0;
|
||||
private final AttributeInstanceArrayMap map;
|
||||
|
||||
Reference in New Issue
Block a user