cache some more aura values

Possibly addresses #252
This commit is contained in:
Ell 2022-05-20 19:03:44 +02:00
parent fb278bd76b
commit a68e728695
3 changed files with 32 additions and 7 deletions

View file

@ -109,20 +109,20 @@ public class InternalHooks implements NaturesAuraAPI.IInternalHooks {
@Override @Override
public void getAuraSpotsInArea(Level level, BlockPos pos, int radius, BiConsumer<BlockPos, Integer> consumer) { public void getAuraSpotsInArea(Level level, BlockPos pos, int radius, BiConsumer<BlockPos, Integer> consumer) {
Helper.getAuraChunksWithSpotsInArea(level, pos, radius, chunk -> chunk.getSpotsInArea(pos, radius, consumer)); Helper.getAuraChunksWithSpotsInArea(level, pos, radius, chunk -> chunk.getSpots(pos, radius, consumer));
} }
@Override @Override
public int getSpotAmountInArea(Level level, BlockPos pos, int radius) { public int getSpotAmountInArea(Level level, BlockPos pos, int radius) {
var result = new MutableInt(); var result = new MutableInt();
this.getAuraSpotsInArea(level, pos, radius, (blockpos, drainSpot) -> result.increment()); Helper.getAuraChunksWithSpotsInArea(level, pos, radius, chunk -> result.add(chunk.getAuraAndSpotAmount(pos, radius).getRight()));
return result.intValue(); return result.intValue();
} }
@Override @Override
public int getAuraInArea(Level level, BlockPos pos, int radius) { public int getAuraInArea(Level level, BlockPos pos, int radius) {
var result = new MutableInt(IAuraChunk.DEFAULT_AURA); var result = new MutableInt(IAuraChunk.DEFAULT_AURA);
this.getAuraSpotsInArea(level, pos, radius, (blockPos, drainSpot) -> result.add(drainSpot)); Helper.getAuraChunksWithSpotsInArea(level, pos, radius, chunk -> result.add(chunk.getAuraAndSpotAmount(pos, radius).getLeft()));
return result.intValue(); return result.intValue();
} }
@ -130,9 +130,10 @@ public class InternalHooks implements NaturesAuraAPI.IInternalHooks {
public Pair<Integer, Integer> getAuraAndSpotAmountInArea(Level level, BlockPos pos, int radius) { public Pair<Integer, Integer> getAuraAndSpotAmountInArea(Level level, BlockPos pos, int radius) {
var spots = new MutableInt(); var spots = new MutableInt();
var aura = new MutableInt(IAuraChunk.DEFAULT_AURA); var aura = new MutableInt(IAuraChunk.DEFAULT_AURA);
this.getAuraSpotsInArea(level, pos, radius, (blockPos, drainSpot) -> { Helper.getAuraChunksWithSpotsInArea(level, pos, radius, chunk -> {
aura.add(drainSpot); var auraAndSpots = chunk.getAuraAndSpotAmount(pos, radius);
spots.increment(); aura.add(auraAndSpots.getLeft());
spots.add(auraAndSpots.getRight());
}); });
return Pair.of(aura.intValue(), spots.intValue()); return Pair.of(aura.intValue(), spots.intValue());
} }

View file

@ -1,5 +1,7 @@
package de.ellpeck.naturesaura.chunk; package de.ellpeck.naturesaura.chunk;
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.Table;
import de.ellpeck.naturesaura.api.NaturesAuraAPI; import de.ellpeck.naturesaura.api.NaturesAuraAPI;
import de.ellpeck.naturesaura.api.aura.chunk.IAuraChunk; import de.ellpeck.naturesaura.api.aura.chunk.IAuraChunk;
import de.ellpeck.naturesaura.api.aura.chunk.IDrainSpotEffect; import de.ellpeck.naturesaura.api.aura.chunk.IDrainSpotEffect;
@ -18,6 +20,7 @@ import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.chunk.LevelChunk; import net.minecraft.world.level.chunk.LevelChunk;
import org.apache.commons.lang3.mutable.MutableInt; import org.apache.commons.lang3.mutable.MutableInt;
import org.apache.commons.lang3.tuple.Pair;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -30,6 +33,7 @@ public class AuraChunk implements IAuraChunk {
private final LevelChunk chunk; private final LevelChunk chunk;
private final IAuraType type; private final IAuraType type;
private final Map<BlockPos, MutableInt> drainSpots = new ConcurrentHashMap<>(); private final Map<BlockPos, MutableInt> drainSpots = new ConcurrentHashMap<>();
private final Table<BlockPos, Integer, Pair<Integer, Integer>> auraAndSpotAmountCache = HashBasedTable.create();
private final List<IDrainSpotEffect> effects = new ArrayList<>(); private final List<IDrainSpotEffect> effects = new ArrayList<>();
private boolean needsSync; private boolean needsSync;
@ -138,6 +142,7 @@ public class AuraChunk implements IAuraChunk {
public void markDirty() { public void markDirty() {
this.chunk.setUnsaved(true); this.chunk.setUnsaved(true);
this.needsSync = true; this.needsSync = true;
this.auraAndSpotAmountCache.clear();
this.addOrRemoveAsActive(); this.addOrRemoveAsActive();
} }
@ -165,7 +170,7 @@ public class AuraChunk implements IAuraChunk {
return new PacketAuraChunk(pos.x, pos.z, this.drainSpots); return new PacketAuraChunk(pos.x, pos.z, this.drainSpots);
} }
public void getSpotsInArea(BlockPos pos, int radius, BiConsumer<BlockPos, Integer> consumer) { public void getSpots(BlockPos pos, int radius, BiConsumer<BlockPos, Integer> consumer) {
for (var entry : this.drainSpots.entrySet()) { for (var entry : this.drainSpots.entrySet()) {
var drainPos = entry.getKey(); var drainPos = entry.getKey();
if (drainPos.distSqr(pos) <= radius * radius) { if (drainPos.distSqr(pos) <= radius * radius) {
@ -174,6 +179,21 @@ public class AuraChunk implements IAuraChunk {
} }
} }
public Pair<Integer, Integer> getAuraAndSpotAmount(BlockPos pos, int radius) {
var ret = this.auraAndSpotAmountCache.get(pos, radius);
if (ret == null) {
var aura = new MutableInt();
var spots = new MutableInt();
this.getSpots(pos, radius, (p, i) -> {
aura.add(i);
spots.increment();
});
ret = Pair.of(aura.intValue(), spots.intValue());
this.auraAndSpotAmountCache.put(pos, radius, ret);
}
return ret;
}
public void getActiveEffectIcons(Player player, Map<ResourceLocation, Tuple<ItemStack, Boolean>> icons) { public void getActiveEffectIcons(Player player, Map<ResourceLocation, Tuple<ItemStack, Boolean>> icons) {
for (var effect : this.effects) { for (var effect : this.effects) {
var alreadyThere = icons.get(effect.getName()); var alreadyThere = icons.get(effect.getName());

View file

@ -1,7 +1,9 @@
package de.ellpeck.naturesaura.misc; package de.ellpeck.naturesaura.misc;
import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.ListMultimap; import com.google.common.collect.ListMultimap;
import com.google.common.collect.Table;
import de.ellpeck.naturesaura.Helper; import de.ellpeck.naturesaura.Helper;
import de.ellpeck.naturesaura.api.NaturesAuraAPI; import de.ellpeck.naturesaura.api.NaturesAuraAPI;
import de.ellpeck.naturesaura.api.misc.ILevelData; import de.ellpeck.naturesaura.api.misc.ILevelData;
@ -21,6 +23,7 @@ import net.minecraft.util.Tuple;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.common.util.LazyOptional;
import org.apache.commons.lang3.tuple.Pair;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -30,6 +33,7 @@ public class LevelData implements ILevelData {
public final ListMultimap<ResourceLocation, Tuple<Vec3, Integer>> effectPowders = ArrayListMultimap.create(); public final ListMultimap<ResourceLocation, Tuple<Vec3, Integer>> effectPowders = ArrayListMultimap.create();
public final Long2ObjectOpenHashMap<AuraChunk> auraChunksWithSpots = new Long2ObjectOpenHashMap<>(); public final Long2ObjectOpenHashMap<AuraChunk> auraChunksWithSpots = new Long2ObjectOpenHashMap<>();
public final Table<BlockPos, Integer, Pair<Integer, Integer>> auraAndSpotAmountCache = HashBasedTable.create();
public final List<BlockPos> recentlyConvertedMossStones = new ArrayList<>(); public final List<BlockPos> recentlyConvertedMossStones = new ArrayList<>();
public final Set<BlockEntitySpawnLamp> spawnLamps = new HashSet<>(); public final Set<BlockEntitySpawnLamp> spawnLamps = new HashSet<>();
private final Map<String, ItemStackHandlerNA> enderStorages = new HashMap<>(); private final Map<String, ItemStackHandlerNA> enderStorages = new HashMap<>();