From 14c41940712dcd717c453ad0e15be3be42154755 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Sun, 24 Mar 2024 14:19:44 -0400 Subject: [PATCH] Minimize allocations and avoid rebuilding weighted list when retrieving potential spawns (#732) --- .../neoforged/neoforge/event/EventHooks.java | 6 ++++- .../neoforge/event/level/LevelEvent.java | 23 ++++++++++++------- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/main/java/net/neoforged/neoforge/event/EventHooks.java b/src/main/java/net/neoforged/neoforge/event/EventHooks.java index ffbab83a9f..618d88c50d 100644 --- a/src/main/java/net/neoforged/neoforge/event/EventHooks.java +++ b/src/main/java/net/neoforged/neoforge/event/EventHooks.java @@ -850,10 +850,14 @@ public static void onPostServerTick(BooleanSupplier haveTime, MinecraftServer se NeoForge.EVENT_BUS.post(new TickEvent.ServerTickEvent(TickEvent.Phase.END, haveTime, server)); } + private static final WeightedRandomList NO_SPAWNS = WeightedRandomList.create(); + public static WeightedRandomList getPotentialSpawns(LevelAccessor level, MobCategory category, BlockPos pos, WeightedRandomList oldList) { LevelEvent.PotentialSpawns event = new LevelEvent.PotentialSpawns(level, category, pos, oldList); if (NeoForge.EVENT_BUS.post(event).isCanceled()) - return WeightedRandomList.create(); + return NO_SPAWNS; + else if (event.getSpawnerDataList() == oldList.unwrap()) + return oldList; return WeightedRandomList.create(event.getSpawnerDataList()); } diff --git a/src/main/java/net/neoforged/neoforge/event/level/LevelEvent.java b/src/main/java/net/neoforged/neoforge/event/level/LevelEvent.java index a293b94e35..4e8aaa3a51 100644 --- a/src/main/java/net/neoforged/neoforge/event/level/LevelEvent.java +++ b/src/main/java/net/neoforged/neoforge/event/level/LevelEvent.java @@ -24,6 +24,7 @@ import net.neoforged.bus.api.ICancellableEvent; import net.neoforged.fml.LogicalSide; import net.neoforged.neoforge.common.NeoForge; +import org.jetbrains.annotations.Nullable; /** * This event is fired whenever an event involving a {@link LevelAccessor} occurs. @@ -133,19 +134,16 @@ public ServerLevelData getSettings() { public static class PotentialSpawns extends LevelEvent implements ICancellableEvent { private final MobCategory mobcategory; private final BlockPos pos; - private final List list; - private final List view; + @Nullable + private List list; + private List view; public PotentialSpawns(LevelAccessor level, MobCategory category, BlockPos pos, WeightedRandomList oldList) { super(level); this.pos = pos; this.mobcategory = category; - if (!oldList.isEmpty()) - this.list = new ArrayList<>(oldList.unwrap()); - else - this.list = new ArrayList<>(); - - this.view = Collections.unmodifiableList(list); + this.list = null; + this.view = oldList.unwrap(); } /** @@ -169,12 +167,20 @@ public List getSpawnerDataList() { return view; } + private void makeList() { + if (list == null) { + list = new ArrayList<>(view); + view = Collections.unmodifiableList(list); + } + } + /** * Appends a SpawnerData entry to the spawn list. * * @param data SpawnerData entry to be appended to the spawn list. */ public void addSpawnerData(MobSpawnSettings.SpawnerData data) { + makeList(); list.add(data); } @@ -186,6 +192,7 @@ public void addSpawnerData(MobSpawnSettings.SpawnerData data) { * {@return {@code true} if the spawn list contained the specified element.} */ public boolean removeSpawnerData(MobSpawnSettings.SpawnerData data) { + makeList(); return list.remove(data); } }