From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com> Date: Thu, 11 Jul 2024 19:28:20 +0300 Subject: [PATCH] Petal: Reduce work done by game event system Original code by Bloom-host, licensed under GPL v3 You can find the original code on https://github.com/Bloom-host/Petal 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 4729befa12732a9fd65cce243b33b3b479026c41..4f63d2d9e37be27724eddea2c61f681ceb318a97 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 @@ -68,7 +68,7 @@ public class SculkCatalystBlockEntity extends BlockEntity implements GameEventLi return this.catalystListener; } - public static class CatalystListener implements GameEventListener { + public class CatalystListener implements GameEventListener { // DivineMC - static -> non-static public static final int PULSE_TICKS = 8; final SculkSpreader sculkSpreader; @@ -139,6 +139,13 @@ public class SculkCatalystBlockEntity extends BlockEntity implements GameEventLi world.playSound((Player) null, pos, SoundEvents.SCULK_CATALYST_BLOOM, SoundSource.BLOCKS, 2.0F, 0.6F + random.nextFloat() * 0.4F); } + // DivineMC start - Petal: Reduce work done by game event system + @Override + public boolean listensToEvent(GameEvent gameEvent, GameEvent.Context context) { + return !SculkCatalystBlockEntity.this.isRemoved() && gameEvent == GameEvent.ENTITY_DIE.value() && context.sourceEntity() instanceof LivingEntity; + } + // DivineMC end + private void tryAwardItSpreadsAdvancement(Level world, LivingEntity deadEntity) { LivingEntity entityliving1 = deadEntity.getLastHurtByMob(); 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 4640baec5bed6c2d53cc0f8ca1d273cc115abe9b..2194c96ad5d54e082cfbe165f086b8fa29a1ad52 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java @@ -83,7 +83,18 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p private Supplier fullStatus; @Nullable private LevelChunk.PostLoadProcessor postLoad; - private final Int2ObjectMap gameEventListenerRegistrySections; + // DivineMC start - Petal: Reduce work done by game event system + 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); + } + // DivineMC end private final LevelChunkTicks blockTicks; private final LevelChunkTicks fluidTicks; private LevelChunk.UnsavedListener unsavedListener; @@ -98,7 +109,7 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p this.unsavedListener = (chunkcoordintpair1) -> { }; this.level = (ServerLevel) world; // CraftBukkit - type - this.gameEventListenerRegistrySections = new Int2ObjectOpenHashMap(); + this.gameEventListenerRegistrySections = new GameEventListenerRegistry[getGameEventSectionLength(this.getSectionsCount())]; // DivineMC - Petal: Reduce work done by game event system Heightmap.Types[] aheightmap_type = Heightmap.Types.values(); int j = aheightmap_type.length; @@ -254,9 +265,23 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p Level world = this.level; if (world instanceof ServerLevel worldserver) { - return (GameEventListenerRegistry) this.gameEventListenerRegistrySections.computeIfAbsent(ySectionCoord, (j) -> { - return new EuclideanGameEventListenerRegistry(worldserver, ySectionCoord, this::removeGameEventListenerRegistry); - }); + // DivineMC start - Petal: Reduce work done by game event system + 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, ySectionCoord, this::removeGameEventListenerRegistry); + } + + return dispatcher; + // DivineMC end } else { return super.getListenerRegistry(ySectionCoord); } @@ -652,7 +677,7 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p } private void removeGameEventListenerRegistry(int ySectionCoord) { - this.gameEventListenerRegistrySections.remove(ySectionCoord); + this.gameEventListenerRegistrySections[getGameEventSectionIndex(this.getSectionIndexFromSectionY(ySectionCoord))] = null; // DivineMC - Petal: Reduce work done by game event system } private void removeBlockEntityTicker(BlockPos pos) { 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 1e93f3a1b11196a431a1f5a0957036fe0c9191a4..a28b48676b459e8cfa0c3ef2d4ad6de55fc91d66 100644 --- a/src/main/java/net/minecraft/world/level/gameevent/EuclideanGameEventListenerRegistry.java +++ b/src/main/java/net/minecraft/world/level/gameevent/EuclideanGameEventListenerRegistry.java @@ -14,8 +14,8 @@ import net.minecraft.world.phys.Vec3; public class EuclideanGameEventListenerRegistry implements GameEventListenerRegistry { private final List listeners = Lists.newArrayList(); - private final Set listenersToRemove = Sets.newHashSet(); - private final List listenersToAdd = Lists.newArrayList(); + //private final Set listenersToRemove = Sets.newHashSet(); // DivineMC - unused + //private final List listenersToAdd = Lists.newArrayList(); // DivineMC - unused private boolean processing; private final ServerLevel level; private final int sectionY; @@ -35,7 +35,7 @@ public class EuclideanGameEventListenerRegistry implements GameEventListenerRegi @Override public void register(GameEventListener listener) { if (this.processing) { - this.listenersToAdd.add(listener); + throw new java.util.ConcurrentModificationException(); // DivineMC - Disallow concurrent modification } else { this.listeners.add(listener); } @@ -46,7 +46,7 @@ public class EuclideanGameEventListenerRegistry implements GameEventListenerRegi @Override public void unregister(GameEventListener listener) { if (this.processing) { - this.listenersToRemove.add(listener); + throw new java.util.ConcurrentModificationException(); // DivineMC - Disallow concurrent modification } else { this.listeners.remove(listener); } @@ -66,7 +66,7 @@ public class EuclideanGameEventListenerRegistry implements GameEventListenerRegi while (iterator.hasNext()) { GameEventListener gameEventListener = iterator.next(); - if (this.listenersToRemove.remove(gameEventListener)) { + if (false) { // DivineMC - Disallow concurrent modification iterator.remove(); } else { Optional optional = getPostableListenerPosition(this.level, pos, gameEventListener); @@ -80,6 +80,7 @@ public class EuclideanGameEventListenerRegistry implements GameEventListenerRegi this.processing = false; } + /* // DivineMC start - Petal: Reduce work done by game event system if (!this.listenersToAdd.isEmpty()) { this.listeners.addAll(this.listenersToAdd); this.listenersToAdd.clear(); @@ -89,6 +90,7 @@ public class EuclideanGameEventListenerRegistry implements GameEventListenerRegi this.listeners.removeAll(this.listenersToRemove); this.listenersToRemove.clear(); } + */ // DivineMC end return bl; } diff --git a/src/main/java/net/minecraft/world/level/gameevent/GameEventDispatcher.java b/src/main/java/net/minecraft/world/level/gameevent/GameEventDispatcher.java index df6c97be1b278c97a20390be5d3e60f429383702..a99253227677f6d68cbb2d79ea847d36e5879175 100644 --- a/src/main/java/net/minecraft/world/level/gameevent/GameEventDispatcher.java +++ b/src/main/java/net/minecraft/world/level/gameevent/GameEventDispatcher.java @@ -45,6 +45,7 @@ public class GameEventDispatcher { int k1 = SectionPos.blockToSectionCoord(blockposition.getZ() + i); List list = new ArrayList(); GameEventListenerRegistry.ListenerVisitor gameeventlistenerregistry_a = (gameeventlistener, vec3d1) -> { + if (!gameeventlistener.listensToEvent(event.value(), emitter)) return; // DivineMC - If they don't listen, ignore if (gameeventlistener.getDeliveryMode() == GameEventListener.DeliveryMode.BY_DISTANCE) { list.add(new GameEvent.ListenerInfo(event, emitterPos, emitter, gameeventlistener, vec3d1)); } else { 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 0f3a79cc644a5b89fa35fdd413ff5781987c4ef3..57e6902990e163ff80b83df30d64e5959ac9d585 100644 --- a/src/main/java/net/minecraft/world/level/gameevent/GameEventListener.java +++ b/src/main/java/net/minecraft/world/level/gameevent/GameEventListener.java @@ -23,4 +23,10 @@ public interface GameEventListener { public interface Provider { T getListener(); } + + // DivineMC start - Add check for seeing if this listener cares about an event + default boolean listensToEvent(GameEvent gameEvent, GameEvent.Context context) { + return true; + } + // DivineMC end }