9
0
mirror of https://github.com/Winds-Studio/Leaf.git synced 2025-12-20 15:39:37 +00:00
Files
Leaf/patches/server/0031-Petal-reduce-work-done-by-game-event-system.patch
Dreeam 8efb01c852 1.19.4
still WIP
2023-03-22 10:06:35 -04:00

193 lines
10 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: peaches94 <peachescu94@gmail.com>
Date: Sun, 10 Jul 2022 13:29:20 -0500
Subject: [PATCH] Petal: reduce work done by game event system
Original license: GPL v3
Original project: https://github.com/Bloom-host/Petal
1. going into game event dispatching can be expensive so run the checks before dispatching
2. EuclideanGameEventListenerRegistry is not used concurrently so we ban that usage for improved performance with allays
diff --git a/src/main/java/net/minecraft/world/level/block/entity/SculkCatalystBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/SculkCatalystBlockEntity.java
index 902f2b39104bf059849228829bfe93b6dbc757d4..088bc38bfe82532a9ec80a96de8178dee21d07d6 100644
--- a/src/main/java/net/minecraft/world/level/block/entity/SculkCatalystBlockEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/entity/SculkCatalystBlockEntity.java
@@ -85,6 +85,13 @@ public class SculkCatalystBlockEntity extends BlockEntity implements GameEventLi
}
+ // petal start
+ @Override
+ public boolean listensToEvent(GameEvent gameEvent, GameEvent.Context context) {
+ return !this.isRemoved() && gameEvent == GameEvent.ENTITY_DIE && context.sourceEntity() instanceof LivingEntity;
+ }
+ // petal end
+
public static void serverTick(Level world, BlockPos pos, BlockState state, SculkCatalystBlockEntity blockEntity) {
org.bukkit.craftbukkit.event.CraftEventFactory.sourceBlockOverride = blockEntity.getBlockPos(); // CraftBukkit - SPIGOT-7068: Add source block override, not the most elegant way but better than passing down a BlockPosition up to five methods deep.
blockEntity.sculkSpreader.updateCursors(world, pos, world.getRandom(), true);
diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
index ccf7a5abfe1d15c02eaa7b7b5699642f53bc3510..e6d3fa7921e5e5d002613391851a75a53370276a 100644
--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
@@ -87,7 +87,18 @@ public class LevelChunk extends ChunkAccess {
private Supplier<ChunkHolder.FullChunkStatus> fullStatus;
@Nullable
private LevelChunk.PostLoadProcessor postLoad;
- private final Int2ObjectMap<GameEventListenerRegistry> gameEventListenerRegistrySections;
+ // petal start
+ private final GameEventListenerRegistry[] gameEventListenerRegistrySections;
+ private static final int GAME_EVENT_DISPATCHER_RADIUS = 2;
+
+ private static int getGameEventSectionIndex(int sectionIndex) {
+ return sectionIndex + GAME_EVENT_DISPATCHER_RADIUS;
+ }
+
+ private static int getGameEventSectionLength(int sectionCount) {
+ return sectionCount + (GAME_EVENT_DISPATCHER_RADIUS * 2);
+ }
+ // petal end
private final LevelChunkTicks<Block> blockTicks;
private final LevelChunkTicks<Fluid> fluidTicks;
@@ -116,7 +127,7 @@ public class LevelChunk extends ChunkAccess {
this.tickersInLevel = Maps.newHashMap();
this.clientLightReady = false;
this.level = (ServerLevel) world; // CraftBukkit - type
- this.gameEventListenerRegistrySections = new Int2ObjectOpenHashMap();
+ this.gameEventListenerRegistrySections = new GameEventListenerRegistry[getGameEventSectionLength(this.getSectionsCount())]; // petal
Heightmap.Types[] aheightmap_type = Heightmap.Types.values();
int j = aheightmap_type.length;
@@ -449,9 +460,23 @@ public class LevelChunk extends ChunkAccess {
if (world instanceof ServerLevel) {
ServerLevel worldserver = (ServerLevel) world;
- return (GameEventListenerRegistry) this.gameEventListenerRegistrySections.computeIfAbsent(ySectionCoord, (j) -> {
- return new EuclideanGameEventListenerRegistry(worldserver);
- });
+ // petal start
+ int sectionIndex = getGameEventSectionIndex(this.getSectionIndexFromSectionY(ySectionCoord));
+
+ // drop game events that are too far away (32 blocks) from loaded sections
+ // this matches the highest radius of game events in the game
+ if (sectionIndex < 0 || sectionIndex >= this.gameEventListenerRegistrySections.length) {
+ return GameEventListenerRegistry.NOOP;
+ }
+
+ var dispatcher = this.gameEventListenerRegistrySections[sectionIndex];
+
+ if (dispatcher == null) {
+ dispatcher = this.gameEventListenerRegistrySections[sectionIndex] = new EuclideanGameEventListenerRegistry(worldserver);
+ }
+
+ return dispatcher;
+ // petal end
} else {
return super.getListenerRegistry(ySectionCoord);
}
@@ -815,7 +840,7 @@ public class LevelChunk extends ChunkAccess {
gameeventlistenerregistry.unregister(gameeventlistener);
if (gameeventlistenerregistry.isEmpty()) {
- this.gameEventListenerRegistrySections.remove(i);
+ this.gameEventListenerRegistrySections[getGameEventSectionIndex(this.getSectionIndexFromSectionY(i))] = null; // petal
}
}
}
diff --git a/src/main/java/net/minecraft/world/level/gameevent/EuclideanGameEventListenerRegistry.java b/src/main/java/net/minecraft/world/level/gameevent/EuclideanGameEventListenerRegistry.java
index 878a42695ecedf0c3f2e6310e3ce44c6b6c36858..3c3168284bfc22dab4037a861aff9f1712cb1c05 100644
--- a/src/main/java/net/minecraft/world/level/gameevent/EuclideanGameEventListenerRegistry.java
+++ b/src/main/java/net/minecraft/world/level/gameevent/EuclideanGameEventListenerRegistry.java
@@ -12,8 +12,8 @@ import net.minecraft.world.phys.Vec3;
public class EuclideanGameEventListenerRegistry implements GameEventListenerRegistry {
private final List<GameEventListener> listeners = Lists.newArrayList();
- private final Set<GameEventListener> listenersToRemove = Sets.newHashSet();
- private final List<GameEventListener> listenersToAdd = Lists.newArrayList();
+ //private final Set<GameEventListener> listenersToRemove = Sets.newHashSet(); // petal - not necessary
+ //private final List<GameEventListener> listenersToAdd = Lists.newArrayList(); // petal
private boolean processing;
private final ServerLevel level;
@@ -29,7 +29,7 @@ public class EuclideanGameEventListenerRegistry implements GameEventListenerRegi
@Override
public void register(GameEventListener listener) {
if (this.processing) {
- this.listenersToAdd.add(listener);
+ throw new java.util.ConcurrentModificationException(); // petal - disallow concurrent modification
} else {
this.listeners.add(listener);
}
@@ -40,7 +40,7 @@ public class EuclideanGameEventListenerRegistry implements GameEventListenerRegi
@Override
public void unregister(GameEventListener listener) {
if (this.processing) {
- this.listenersToRemove.add(listener);
+ throw new java.util.ConcurrentModificationException(); // petal - disallow concurrent modification
} else {
this.listeners.remove(listener);
}
@@ -57,7 +57,7 @@ public class EuclideanGameEventListenerRegistry implements GameEventListenerRegi
while(iterator.hasNext()) {
GameEventListener gameEventListener = iterator.next();
- if (this.listenersToRemove.remove(gameEventListener)) {
+ if (false) { // petal - disallow concurrent modification
iterator.remove();
} else {
Optional<Vec3> optional = getPostableListenerPosition(this.level, pos, gameEventListener);
@@ -71,6 +71,8 @@ public class EuclideanGameEventListenerRegistry implements GameEventListenerRegi
this.processing = false;
}
+ // petal start
+ /*
if (!this.listenersToAdd.isEmpty()) {
this.listeners.addAll(this.listenersToAdd);
this.listenersToAdd.clear();
@@ -80,6 +82,8 @@ public class EuclideanGameEventListenerRegistry implements GameEventListenerRegi
this.listeners.removeAll(this.listenersToRemove);
this.listenersToRemove.clear();
}
+ */
+ // petal end
return bl;
}
diff --git a/src/main/java/net/minecraft/world/level/gameevent/GameEventListener.java b/src/main/java/net/minecraft/world/level/gameevent/GameEventListener.java
index a6689c03777c2b4b79dcafcae5d70c949519cd8e..f94169a3e177251a05644e3e384ac0514efd3719 100644
--- a/src/main/java/net/minecraft/world/level/gameevent/GameEventListener.java
+++ b/src/main/java/net/minecraft/world/level/gameevent/GameEventListener.java
@@ -18,4 +18,10 @@ public interface GameEventListener {
UNSPECIFIED,
BY_DISTANCE;
}
+
+ // petal start - add check for seeing if this listener cares about an event
+ default boolean listensToEvent(net.minecraft.world.level.gameevent.GameEvent gameEvent, net.minecraft.world.level.gameevent.GameEvent.Context context) {
+ return true;
+ }
+ // petal end
}
diff --git a/src/main/java/net/minecraft/world/level/gameevent/vibrations/VibrationListener.java b/src/main/java/net/minecraft/world/level/gameevent/vibrations/VibrationListener.java
index 103e12ec589dcbe6dbad7432b50e0644c3a37b1b..c90a827ca260d5f010c699488cba0dd00f9e97e4 100644
--- a/src/main/java/net/minecraft/world/level/gameevent/vibrations/VibrationListener.java
+++ b/src/main/java/net/minecraft/world/level/gameevent/vibrations/VibrationListener.java
@@ -228,6 +228,13 @@ public class VibrationListener implements GameEventListener {
return true;
}
+ // petal start
+ @Override
+ public boolean listensToEvent(GameEvent gameEvent, GameEvent.Context context) {
+ return this.currentVibration == null && gameEvent.is(this.config.getListenableEvents());
+ }
+ // petal end
+
public interface VibrationListenerConfig {
default TagKey<GameEvent> getListenableEvents() {