From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Samsuik <40902469+Samsuik@users.noreply.github.com> Date: Tue, 23 May 2023 23:07:20 +0100 Subject: [PATCH] Sakura Utils diff --git a/src/main/java/me/samsuik/sakura/utils/collections/OrderedComparatorList.java b/src/main/java/me/samsuik/sakura/utils/collections/OrderedComparatorList.java new file mode 100644 index 0000000000000000000000000000000000000000..ff4909a2ba8f451a7c6aa55ee98e33c88dd69e5e --- /dev/null +++ b/src/main/java/me/samsuik/sakura/utils/collections/OrderedComparatorList.java @@ -0,0 +1,51 @@ +package me.samsuik.sakura.utils.collections; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; + +import java.util.Arrays; +import java.util.Comparator; + +public class OrderedComparatorList extends ObjectArrayList { + + private final Comparator comparator; + private boolean binarySearch = true; + + public OrderedComparatorList(int capacity, Comparator comparator) { + super(capacity); + this.comparator = Comparator.nullsLast(comparator); + } + + public OrderedComparatorList(Comparator comparator) { + this(DEFAULT_INITIAL_CAPACITY, comparator); + } + + private void validateBounds(int index, T t, boolean up) { + if (index != 0 && comparator.compare(get(index - 1), t) > 0) { + binarySearch = false; + } else if (up && index < size() - 1 && comparator.compare(get(index + 1), t) < 0) { + binarySearch = false; + } + } + + @Override + public boolean add(T t) { + validateBounds(size(), t, false); + return super.add(t); + } + + @Override + public void add(int index, T t) { + validateBounds(index, t, true); + super.add(index, t); + } + + @Override + public int indexOf(final Object k) { + if (binarySearch) { + return Math.max(Arrays.binarySearch(a, (T) k, comparator), -1); + } else { + return super.indexOf(k); + } + } + +} diff --git a/src/main/java/me/samsuik/sakura/utils/collections/TrackedEntityChunkMap.java b/src/main/java/me/samsuik/sakura/utils/collections/TrackedEntityChunkMap.java new file mode 100644 index 0000000000000000000000000000000000000000..e31998ac50b8bda8687d07b0022c0e039fa2e774 --- /dev/null +++ b/src/main/java/me/samsuik/sakura/utils/collections/TrackedEntityChunkMap.java @@ -0,0 +1,34 @@ +package me.samsuik.sakura.utils.collections; + +import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; +import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import it.unimi.dsi.fastutil.objects.ObjectCollection; +import net.minecraft.server.level.ChunkMap; + +public class TrackedEntityChunkMap extends Int2ObjectOpenHashMap { + + private final ObjectArrayList entityList = new UnorderedIndexedList<>(); + + @Override + public ChunkMap.TrackedEntity put(int k, ChunkMap.TrackedEntity trackedEntity) { + ChunkMap.TrackedEntity tracked = super.put(k, trackedEntity); + // bad plugins may replace entries + if (tracked != null) + entityList.remove(trackedEntity); + entityList.add(trackedEntity); + return tracked; + } + + @Override + public ChunkMap.TrackedEntity remove(int k) { + ChunkMap.TrackedEntity tracked = super.remove(k); + entityList.remove(tracked); + return tracked; + } + + @Override + public ObjectCollection values() { + return entityList; + } + +} diff --git a/src/main/java/me/samsuik/sakura/utils/collections/UnorderedIndexedList.java b/src/main/java/me/samsuik/sakura/utils/collections/UnorderedIndexedList.java new file mode 100644 index 0000000000000000000000000000000000000000..be4f5b4999c85fc6765e37cc9af0a87292327dbf --- /dev/null +++ b/src/main/java/me/samsuik/sakura/utils/collections/UnorderedIndexedList.java @@ -0,0 +1,65 @@ +package me.samsuik.sakura.utils.collections; + +import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; +import it.unimi.dsi.fastutil.objects.ObjectArrayList; + +public class UnorderedIndexedList extends ObjectArrayList { + + private final Int2IntOpenHashMap elementToIndex = new Int2IntOpenHashMap(); + + { + elementToIndex.defaultReturnValue(-1); + } + + public UnorderedIndexedList(int capacity) { + super(capacity); + } + + public UnorderedIndexedList() { + super(); + } + + @Override + public boolean add(final T t) { + elementToIndex.put(t.hashCode(), size()); + return super.add(t); + } + + @Override + public T remove(final int index) { + final int tail = size() - 1; + final T at = a[index]; + + if (index != tail) { + final T tailObj = a[tail]; + if (tailObj != null) + elementToIndex.put(tailObj.hashCode(), index); + a[index] = tailObj; + } + + if (at != null) + elementToIndex.remove(at.hashCode()); + a[tail] = null; + size = tail; + return at; + } + + @Override + public void clear() { + elementToIndex.clear(); + super.clear(); + } + + @Override + public int indexOf(final Object k) { + if (k == null) return -1; + // entities uses their id as a hashcode + return elementToIndex.get(k.hashCode()); + } + + @Override + public void add(final int index, final T t) { + throw new UnsupportedOperationException(); + } + +} diff --git a/src/main/java/me/samsuik/sakura/utils/objects/Expiry.java b/src/main/java/me/samsuik/sakura/utils/objects/Expiry.java new file mode 100644 index 0000000000000000000000000000000000000000..a05e7d03f17f675e190d63a4206129a74f42cadc --- /dev/null +++ b/src/main/java/me/samsuik/sakura/utils/objects/Expiry.java @@ -0,0 +1,21 @@ +package me.samsuik.sakura.utils.objects; + +public class Expiry { + + private long expireAt; + private final int inc; + + public Expiry(long tick, int inc) { + this.expireAt = tick + inc; + this.inc = inc; + } + + public void refresh(long tick) { + this.expireAt = tick + this.inc; + } + + public boolean isExpired(long tick) { + return tick >= this.expireAt; + } + +}