Skip to content

Commit

Permalink
Minimize allocations and avoid rebuilding weighted list when retrievi…
Browse files Browse the repository at this point in the history
…ng potential spawns (neoforged#732)
  • Loading branch information
embeddedt authored Mar 24, 2024
1 parent fd7f314 commit 14c4194
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 9 deletions.
6 changes: 5 additions & 1 deletion src/main/java/net/neoforged/neoforge/event/EventHooks.java
Original file line number Diff line number Diff line change
Expand Up @@ -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<MobSpawnSettings.SpawnerData> NO_SPAWNS = WeightedRandomList.create();

public static WeightedRandomList<MobSpawnSettings.SpawnerData> getPotentialSpawns(LevelAccessor level, MobCategory category, BlockPos pos, WeightedRandomList<MobSpawnSettings.SpawnerData> 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());
}

Expand Down
23 changes: 15 additions & 8 deletions src/main/java/net/neoforged/neoforge/event/level/LevelEvent.java
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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<MobSpawnSettings.SpawnerData> list;
private final List<MobSpawnSettings.SpawnerData> view;
@Nullable
private List<MobSpawnSettings.SpawnerData> list;
private List<MobSpawnSettings.SpawnerData> view;

public PotentialSpawns(LevelAccessor level, MobCategory category, BlockPos pos, WeightedRandomList<MobSpawnSettings.SpawnerData> 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();
}

/**
Expand All @@ -169,12 +167,20 @@ public List<MobSpawnSettings.SpawnerData> 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);
}

Expand All @@ -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);
}
}
Expand Down

0 comments on commit 14c4194

Please sign in to comment.