possibly increase performance by iterating chunks with spots in them only

This commit is contained in:
Ell 2020-12-07 01:06:22 +01:00
parent eb44c5e784
commit f0d25aada9
5 changed files with 43 additions and 30 deletions

View file

@ -5,14 +5,15 @@ import com.mojang.blaze3d.systems.RenderSystem;
import de.ellpeck.naturesaura.api.NaturesAuraAPI;
import de.ellpeck.naturesaura.api.aura.container.IAuraContainer;
import de.ellpeck.naturesaura.api.aura.item.IAuraRecharge;
import de.ellpeck.naturesaura.api.misc.IWorldData;
import de.ellpeck.naturesaura.blocks.tiles.TileEntityImpl;
import de.ellpeck.naturesaura.chunk.AuraChunk;
import de.ellpeck.naturesaura.compat.Compat;
import de.ellpeck.naturesaura.misc.WorldData;
import net.minecraft.advancements.Advancement;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.entity.item.ItemEntity;
import net.minecraft.entity.item.ItemFrameEntity;
import net.minecraft.entity.player.PlayerEntity;
@ -27,7 +28,6 @@ import net.minecraft.util.*;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.util.math.vector.Vector3d;
import net.minecraft.world.IWorld;
import net.minecraft.world.World;
@ -77,15 +77,13 @@ public final class Helper {
return false;
}
public static void getAuraChunksInArea(World world, BlockPos pos, int radius, Consumer<AuraChunk> consumer) {
public static void getAuraChunksWithSpotsInArea(World world, BlockPos pos, int radius, Consumer<AuraChunk> consumer) {
WorldData data = (WorldData) IWorldData.getWorldData(world);
for (int x = pos.getX() - radius >> 4; x <= pos.getX() + radius >> 4; x++) {
for (int z = pos.getZ() - radius >> 4; z <= pos.getZ() + radius >> 4; z++) {
Chunk chunk = getLoadedChunk(world, x, z);
if (chunk != null) {
AuraChunk auraChunk = (AuraChunk) chunk.getCapability(NaturesAuraAPI.capAuraChunk, null).orElse(null);
if (auraChunk != null)
consumer.accept(auraChunk);
}
AuraChunk chunk = data.auraChunksWithSpots.get(ChunkPos.asLong(x, z));
if (chunk != null)
consumer.accept(chunk);
}
}
}

View file

@ -110,7 +110,7 @@ public class InternalHooks implements NaturesAuraAPI.IInternalHooks {
@Override
public void getAuraSpotsInArea(World world, BlockPos pos, int radius, BiConsumer<BlockPos, Integer> consumer) {
Helper.getAuraChunksInArea(world, pos, radius, chunk -> chunk.getSpotsInArea(pos, radius, consumer));
Helper.getAuraChunksWithSpotsInArea(world, pos, radius, chunk -> chunk.getSpotsInArea(pos, radius, consumer));
}
@Override

View file

@ -5,6 +5,8 @@ import de.ellpeck.naturesaura.api.aura.chunk.IAuraChunk;
import de.ellpeck.naturesaura.api.aura.chunk.IDrainSpotEffect;
import de.ellpeck.naturesaura.api.aura.chunk.IDrainSpotEffect.ActiveType;
import de.ellpeck.naturesaura.api.aura.type.IAuraType;
import de.ellpeck.naturesaura.api.misc.IWorldData;
import de.ellpeck.naturesaura.misc.WorldData;
import de.ellpeck.naturesaura.packet.PacketAuraChunk;
import de.ellpeck.naturesaura.packet.PacketHandler;
import net.minecraft.entity.player.PlayerEntity;
@ -50,8 +52,8 @@ public class AuraChunk implements IAuraChunk {
public int drainAura(BlockPos pos, int amount, boolean aimForZero, boolean simulate) {
if (amount <= 0)
return 0;
MutableInt spot = this.getActualDrainSpot(pos, true);
int curr = spot.intValue();
MutableInt spot = this.getActualDrainSpot(pos, !simulate);
int curr = spot != null ? spot.intValue() : 0;
if (curr < 0 && curr - amount > 0) // Underflow protection
return this.drainAura(pos.up(), amount, aimForZero, simulate);
if (aimForZero) {
@ -76,8 +78,8 @@ public class AuraChunk implements IAuraChunk {
public int storeAura(BlockPos pos, int amount, boolean aimForZero, boolean simulate) {
if (amount <= 0)
return 0;
MutableInt spot = this.getActualDrainSpot(pos, true);
int curr = spot.intValue();
MutableInt spot = this.getActualDrainSpot(pos, !simulate);
int curr = spot != null ? spot.intValue() : 0;
if (curr > 0 && curr + amount < 0) // Overflow protection
return this.storeAura(pos.up(), amount, aimForZero, simulate);
if (aimForZero) {
@ -128,6 +130,7 @@ public class AuraChunk implements IAuraChunk {
this.drainSpots.clear();
for (Map.Entry<BlockPos, MutableInt> entry : spots.entrySet())
this.addDrainSpot(entry.getKey(), entry.getValue());
this.addOrRemoveAsActive();
}
@Override
@ -139,6 +142,7 @@ public class AuraChunk implements IAuraChunk {
public void markDirty() {
this.chunk.markDirty();
this.needsSync = true;
this.addOrRemoveAsActive();
}
public void update() {
@ -218,5 +222,16 @@ public class AuraChunk implements IAuraChunk {
BlockPos.fromLong(tag.getLong("pos")),
new MutableInt(tag.getInt("amount")));
}
this.addOrRemoveAsActive();
}
private void addOrRemoveAsActive() {
long chunkPos = this.chunk.getPos().asLong();
WorldData data = (WorldData) IWorldData.getWorldData(this.chunk.getWorld());
if (this.drainSpots.size() > 0) {
data.auraChunksWithSpots.put(chunkPos, this);
} else {
data.auraChunksWithSpots.remove(chunkPos);
}
}
}

View file

@ -12,13 +12,10 @@ import de.ellpeck.naturesaura.api.aura.container.IAuraContainer;
import de.ellpeck.naturesaura.api.aura.type.IAuraType;
import de.ellpeck.naturesaura.api.render.IVisualizable;
import de.ellpeck.naturesaura.blocks.tiles.*;
import de.ellpeck.naturesaura.enchant.ModEnchantment;
import de.ellpeck.naturesaura.items.ItemAuraBottle;
import de.ellpeck.naturesaura.items.ItemAuraCache;
import de.ellpeck.naturesaura.items.ItemRangeVisualizer;
import de.ellpeck.naturesaura.items.ModItems;
import de.ellpeck.naturesaura.packet.PacketAuraChunk;
import de.ellpeck.naturesaura.particles.ParticleHandler;
import net.minecraft.block.*;
import net.minecraft.client.MainWindow;
import net.minecraft.client.Minecraft;
@ -26,22 +23,19 @@ import net.minecraft.client.gui.AbstractGui;
import net.minecraft.client.gui.screen.ChatScreen;
import net.minecraft.client.renderer.ActiveRenderInfo;
import net.minecraft.client.resources.I18n;
import net.minecraft.enchantment.Enchantment;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.entity.Entity;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.IReorderingProcessor;
import net.minecraft.util.RegistryKey;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.Tuple;
import net.minecraft.util.math.*;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.vector.Vector3d;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.StringTextComponent;
import net.minecraft.util.text.TextFormatting;
import net.minecraft.util.text.TranslationTextComponent;
import net.minecraft.world.World;
import net.minecraft.world.biome.BiomeColors;
import net.minecraft.world.gen.Heightmap;
@ -53,14 +47,15 @@ import net.minecraftforge.client.event.RenderWorldLastEvent;
import net.minecraftforge.common.IPlantable;
import net.minecraftforge.energy.EnergyStorage;
import net.minecraftforge.event.TickEvent;
import net.minecraftforge.event.entity.player.ItemTooltipEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.ModList;
import org.apache.commons.lang3.mutable.MutableInt;
import org.lwjgl.opengl.GL11;
import java.text.NumberFormat;
import java.util.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@OnlyIn(Dist.CLIENT)
public class ClientEvents {
@ -85,12 +80,14 @@ public class ClientEvents {
left.add("");
MutableInt amount = new MutableInt(IAuraChunk.DEFAULT_AURA);
MutableInt spots = new MutableInt();
MutableInt chunks = new MutableInt();
IAuraChunk.getSpotsInArea(mc.world, mc.player.getPosition(), 35, (blockPos, drainSpot) -> {
spots.increment();
amount.add(drainSpot);
});
Helper.getAuraChunksWithSpotsInArea(mc.world, mc.player.getPosition(), 35, c -> chunks.increment());
NumberFormat format = NumberFormat.getInstance();
left.add(prefix + "A: " + format.format(amount.intValue()) + " (S: " + spots.intValue() + ")");
left.add(prefix + "A: " + format.format(amount.intValue()) + " (S: " + spots.intValue() + ", C: " + chunks.intValue() + ")");
left.add(prefix + "AT: " + IAuraType.forWorld(mc.world).getName());
}
}
@ -161,7 +158,7 @@ public class ClientEvents {
if (!heldOcular.isEmpty() && mc.world.getGameTime() % 20 == 0) {
SHOWING_EFFECTS.clear();
Helper.getAuraChunksInArea(mc.world, mc.player.getPosition(), 100,
Helper.getAuraChunksWithSpotsInArea(mc.world, mc.player.getPosition(), 100,
chunk -> chunk.getActiveEffectIcons(mc.player, SHOWING_EFFECTS));
}
}

View file

@ -7,7 +7,9 @@ import de.ellpeck.naturesaura.api.NaturesAuraAPI;
import de.ellpeck.naturesaura.api.misc.IWorldData;
import de.ellpeck.naturesaura.blocks.tiles.ItemStackHandlerNA;
import de.ellpeck.naturesaura.blocks.tiles.TileEntitySpawnLamp;
import de.ellpeck.naturesaura.chunk.AuraChunk;
import de.ellpeck.naturesaura.items.ModItems;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.nbt.INBT;
@ -28,9 +30,10 @@ import java.util.*;
public class WorldData implements IWorldData {
public final ListMultimap<ResourceLocation, Tuple<Vector3d, Integer>> effectPowders = ArrayListMultimap.create();
public final Long2ObjectOpenHashMap<AuraChunk> auraChunksWithSpots = new Long2ObjectOpenHashMap<>();
public final List<BlockPos> recentlyConvertedMossStones = new ArrayList<>();
private final Map<String, ItemStackHandlerNA> enderStorages = new HashMap<>();
public final Set<TileEntitySpawnLamp> spawnLamps = new HashSet<>();
private final Map<String, ItemStackHandlerNA> enderStorages = new HashMap<>();
private final LazyOptional<WorldData> lazyThis = LazyOptional.of(() -> this);
@Nullable