Reduce overhead of the PotentialSpawns event

This commit is contained in:
embeddedt 2024-03-20 16:39:24 -04:00
parent 070b7b6d12
commit 1814bd3e1f
No known key found for this signature in database
GPG Key ID: A69433EC199B5613
2 changed files with 93 additions and 0 deletions

View File

@ -0,0 +1,25 @@
package org.embeddedt.modernfix.forge.mixin.perf.potential_spawns_alloc;
import net.minecraft.core.BlockPos;
import net.minecraft.util.random.WeightedRandomList;
import net.minecraft.world.entity.MobCategory;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.biome.MobSpawnSettings;
import net.minecraftforge.event.ForgeEventFactory;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
import java.util.List;
@Mixin(ForgeEventFactory.class)
public class ForgeEventFactoryMixin {
@Redirect(method = "getPotentialSpawns", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/random/WeightedRandomList;create(Ljava/util/List;)Lnet/minecraft/util/random/WeightedRandomList;"))
private static WeightedRandomList<MobSpawnSettings.SpawnerData> reuseOldList(List<MobSpawnSettings.SpawnerData> items, LevelAccessor level, MobCategory category, BlockPos pos, WeightedRandomList<MobSpawnSettings.SpawnerData> oldList) {
// Our patched version of PotentialSpawns will return the same list as unwrap() if no one mutated the list
if(items == oldList.unwrap()) {
return oldList;
}
return WeightedRandomList.create(items);
}
}

View File

@ -0,0 +1,68 @@
package org.embeddedt.modernfix.forge.mixin.perf.potential_spawns_alloc;
import net.minecraft.core.BlockPos;
import net.minecraft.util.random.WeightedRandomList;
import net.minecraft.world.entity.MobCategory;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.biome.MobSpawnSettings;
import net.minecraftforge.event.world.WorldEvent;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Mutable;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
@Mixin(WorldEvent.PotentialSpawns.class)
public class PotentialSpawnsMixin {
@Shadow(remap = false) @Final @Mutable private List<MobSpawnSettings.SpawnerData> view;
@Shadow(remap = false) @Final @Mutable private List<MobSpawnSettings.SpawnerData> list;
private static final ArrayList<MobSpawnSettings.SpawnerData> SENTINEL = new ArrayList<>();
@Redirect(method = "<init>", at = @At(value = "NEW", target = "java/util/ArrayList", ordinal = 1))
private ArrayList<?> avoidListAlloc1() {
return SENTINEL;
}
@Redirect(method = "<init>", at = @At(value = "NEW", target = "java/util/ArrayList", ordinal = 0))
private ArrayList<?> avoidListAlloc2(Collection c) {
return SENTINEL;
}
@Redirect(method = "<init>", at = @At(value = "INVOKE", target = "Ljava/util/Collections;unmodifiableList(Ljava/util/List;)Ljava/util/List;"))
private List<?> avoidListAlloc3(List<?> l) {
return null;
}
@Inject(method = "<init>", at = @At("RETURN"))
private void initializeSmartLists(LevelAccessor level, MobCategory category, BlockPos pos, WeightedRandomList<MobSpawnSettings.SpawnerData> oldList, CallbackInfo ci) {
this.view = oldList.unwrap();
this.list = null;
}
private void mfix$populateList() {
if(this.list == null) {
this.list = new ArrayList<>(this.view);
this.view = Collections.unmodifiableList(this.list);
}
}
@Inject(method = {"addSpawnerData" }, at = @At("HEAD"), remap = false)
private void populateList(MobSpawnSettings.SpawnerData data, CallbackInfo ci) {
mfix$populateList();
}
@Inject(method = {"removeSpawnerData" }, at = @At("HEAD"), remap = false)
private void populateList(MobSpawnSettings.SpawnerData data, CallbackInfoReturnable<Boolean> cir) {
mfix$populateList();
}
}