mirror of
https://github.com/Winds-Studio/Leaf.git
synced 2025-12-20 15:39:37 +00:00
193 lines
10 KiB
Diff
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() {
|