From f0d25aada9c25fd39d1037402308dab609be29b7 Mon Sep 17 00:00:00 2001 From: Ellpeck Date: Mon, 7 Dec 2020 01:06:22 +0100 Subject: [PATCH] possibly increase performance by iterating chunks with spots in them only --- .../java/de/ellpeck/naturesaura/Helper.java | 16 +++++------ .../de/ellpeck/naturesaura/InternalHooks.java | 2 +- .../ellpeck/naturesaura/chunk/AuraChunk.java | 23 +++++++++++++--- .../naturesaura/events/ClientEvents.java | 27 +++++++++---------- .../ellpeck/naturesaura/misc/WorldData.java | 5 +++- 5 files changed, 43 insertions(+), 30 deletions(-) diff --git a/src/main/java/de/ellpeck/naturesaura/Helper.java b/src/main/java/de/ellpeck/naturesaura/Helper.java index e6dfdd4d..302cc913 100644 --- a/src/main/java/de/ellpeck/naturesaura/Helper.java +++ b/src/main/java/de/ellpeck/naturesaura/Helper.java @@ -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 consumer) { + public static void getAuraChunksWithSpotsInArea(World world, BlockPos pos, int radius, Consumer 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); } } } diff --git a/src/main/java/de/ellpeck/naturesaura/InternalHooks.java b/src/main/java/de/ellpeck/naturesaura/InternalHooks.java index 97c016b2..b150b1f5 100644 --- a/src/main/java/de/ellpeck/naturesaura/InternalHooks.java +++ b/src/main/java/de/ellpeck/naturesaura/InternalHooks.java @@ -110,7 +110,7 @@ public class InternalHooks implements NaturesAuraAPI.IInternalHooks { @Override public void getAuraSpotsInArea(World world, BlockPos pos, int radius, BiConsumer consumer) { - Helper.getAuraChunksInArea(world, pos, radius, chunk -> chunk.getSpotsInArea(pos, radius, consumer)); + Helper.getAuraChunksWithSpotsInArea(world, pos, radius, chunk -> chunk.getSpotsInArea(pos, radius, consumer)); } @Override diff --git a/src/main/java/de/ellpeck/naturesaura/chunk/AuraChunk.java b/src/main/java/de/ellpeck/naturesaura/chunk/AuraChunk.java index 84c7d9f6..426cd7f4 100644 --- a/src/main/java/de/ellpeck/naturesaura/chunk/AuraChunk.java +++ b/src/main/java/de/ellpeck/naturesaura/chunk/AuraChunk.java @@ -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 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); + } } } diff --git a/src/main/java/de/ellpeck/naturesaura/events/ClientEvents.java b/src/main/java/de/ellpeck/naturesaura/events/ClientEvents.java index 02006b9b..fd0ae95e 100644 --- a/src/main/java/de/ellpeck/naturesaura/events/ClientEvents.java +++ b/src/main/java/de/ellpeck/naturesaura/events/ClientEvents.java @@ -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)); } } diff --git a/src/main/java/de/ellpeck/naturesaura/misc/WorldData.java b/src/main/java/de/ellpeck/naturesaura/misc/WorldData.java index 6e90e5f1..3589afa7 100644 --- a/src/main/java/de/ellpeck/naturesaura/misc/WorldData.java +++ b/src/main/java/de/ellpeck/naturesaura/misc/WorldData.java @@ -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> effectPowders = ArrayListMultimap.create(); + public final Long2ObjectOpenHashMap auraChunksWithSpots = new Long2ObjectOpenHashMap<>(); public final List recentlyConvertedMossStones = new ArrayList<>(); - private final Map enderStorages = new HashMap<>(); public final Set spawnLamps = new HashSet<>(); + private final Map enderStorages = new HashMap<>(); private final LazyOptional lazyThis = LazyOptional.of(() -> this); @Nullable