mirror of
https://github.com/YatopiaMC/Yatopia.git
synced 2024-11-14 22:56:29 +01:00
d065d41c0e
Apparently caused issues we werent aware of. Unfortunately there's no way to improve it without blocking the main thread.
113 lines
5.0 KiB
Diff
113 lines
5.0 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: JellySquid <jellysquid+atwork@protonmail.com>
|
|
Date: Tue, 4 Aug 2020 21:46:05 +0200
|
|
Subject: [PATCH] lithium-MixinDataWatcher
|
|
|
|
Original code by JellySquid, licensed under GNU Lesser General Public License v3.0
|
|
you can find the original code on https://github.com/jellysquid3/lithium-fabric/tree/1.16.x/fabric (Yarn mappings)
|
|
|
|
Co-authored-by: tr7zw <tr7zw@live.de>
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/DataWatcher.java b/src/main/java/net/minecraft/server/DataWatcher.java
|
|
index e69093b411f76ea4090789576f8fb6635bd02ca5..4a14431b198c227eb6f0f68eaac14f5c09fc3036 100644
|
|
--- a/src/main/java/net/minecraft/server/DataWatcher.java
|
|
+++ b/src/main/java/net/minecraft/server/DataWatcher.java
|
|
@@ -27,6 +27,77 @@ public class DataWatcher {
|
|
private boolean f = true;
|
|
private boolean g;
|
|
|
|
+ // Yatopia lithium start
|
|
+ private static final int DEFAULT_ENTRY_COUNT = 10, GROW_FACTOR = 8;
|
|
+ /** Mirrors the vanilla backing entries map. Each DataWatcher.Item can be accessed in this array through its ID. **/
|
|
+ private DataWatcher.Item<?>[] entriesArray = new DataWatcher.Item<?>[DEFAULT_ENTRY_COUNT];
|
|
+
|
|
+ /**
|
|
+ * We redirect the call to add a tracked data to the internal map so we can add it to our new storage structure. This
|
|
+ * should only ever occur during entity initialization. Type-erasure is a bit of a pain here since we must redirect
|
|
+ * a calls to the generic Map interface.
|
|
+ */
|
|
+ private Object onAddTrackedDataInsertMap(Int2ObjectOpenHashMap<DataWatcher.Item<?>> map, int keyRaw, DataWatcher.Item<?> valueRaw) {
|
|
+ int k = keyRaw;
|
|
+ DataWatcher.Item<?> v = (DataWatcher.Item<?>) valueRaw;
|
|
+
|
|
+ DataWatcher.Item<?>[] storage = this.entriesArray;
|
|
+
|
|
+ // Check if we need to grow the backing array to accommodate the new key range
|
|
+ if (storage.length <= k) {
|
|
+ // Grow the array to accommodate 8 entries after this one, but limit it to never be larger
|
|
+ // than 256 entries as per the vanilla limit
|
|
+ int newSize = Math.min(k + GROW_FACTOR, 256);
|
|
+
|
|
+ this.entriesArray = storage = java.util.Arrays.copyOf(storage, newSize);
|
|
+ }
|
|
+
|
|
+ // Update the storage
|
|
+ storage[k] = v;
|
|
+
|
|
+ // Ensure that the vanilla backing storage is still updated appropriately
|
|
+ return this.entries.put(k, v);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * @reason Avoid integer boxing/unboxing and use our array-based storage
|
|
+ * @author JellySquid
|
|
+ */
|
|
+ private <T> DataWatcher.Item<T> getEntry(DataWatcherObject<T> data) {
|
|
+ try {
|
|
+ DataWatcher.Item<?>[] array = this.entriesArray;
|
|
+
|
|
+ int id = data.a();
|
|
+
|
|
+ // The vanilla implementation will simply return null if the tracker doesn't contain the specified entry. However,
|
|
+ // accessing an array with an invalid pointer will throw a OOB exception, where-as a HashMap would simply
|
|
+ // return null. We check this case (which should be free, even if so insignificant, as the subsequent bounds
|
|
+ // check will hopefully be eliminated)
|
|
+ if (id < 0 || id >= array.length) {
|
|
+ return null;
|
|
+ }
|
|
+
|
|
+ // This cast can fail if trying to access a entry which doesn't belong to this tracker, as the ID could
|
|
+ // instead point to an entry of a different type. However, that is also vanilla behaviour.
|
|
+ // noinspection unchecked
|
|
+ return (DataWatcher.Item<T>) array[id];
|
|
+ } catch (Throwable cause) {
|
|
+ // Move to another method so this function can be in-lined better
|
|
+ throw onGetException(cause, data);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private static <T> ReportedException onGetException(Throwable cause, DataWatcherObject<T> data) {
|
|
+ CrashReport report = CrashReport.a(cause, "Getting synced entity data");
|
|
+
|
|
+ CrashReportSystemDetails section = report.a("Synced entity data");
|
|
+ section.a("Data ID", data);
|
|
+
|
|
+ return new ReportedException(report);
|
|
+ }
|
|
+
|
|
+ // Yatopia lithium end
|
|
+
|
|
public DataWatcher(Entity entity) {
|
|
this.entity = entity;
|
|
}
|
|
@@ -91,7 +162,8 @@ public class DataWatcher {
|
|
DataWatcher.Item<T> datawatcher_item = new DataWatcher.Item<>(datawatcherobject, t0);
|
|
|
|
// this.lock.writeLock().lock(); // Spigot - not required
|
|
- this.entries.put(datawatcherobject.a(), datawatcher_item);
|
|
+ //this.entries.put(datawatcherobject.a(), datawatcher_item);
|
|
+ this.onAddTrackedDataInsertMap(this.entries, datawatcherobject.a(), datawatcher_item); // Yatopia lithium
|
|
this.f = false;
|
|
// this.lock.writeLock().unlock(); // Spigot - not required
|
|
}
|
|
@@ -122,7 +194,8 @@ public class DataWatcher {
|
|
}
|
|
|
|
public <T> T get(DataWatcherObject<T> datawatcherobject) {
|
|
- return this.b(datawatcherobject).b();
|
|
+ return getEntry(datawatcherobject).b(); // Yatopia
|
|
+ //return this.b(datawatcherobject).b();
|
|
}
|
|
|
|
public <T> void set(DataWatcherObject<T> datawatcherobject, T t0) {
|