diff --git a/src/main/java/dev/micle/xptools/config/Config.java b/src/main/java/dev/micle/xptools/config/Config.java index 564903b..fb683cc 100644 --- a/src/main/java/dev/micle/xptools/config/Config.java +++ b/src/main/java/dev/micle/xptools/config/Config.java @@ -8,10 +8,7 @@ import net.minecraftforge.fml.config.ModConfig; import net.minecraftforge.fml.event.config.ModConfigEvent; import org.apache.commons.lang3.tuple.Pair; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Comparator; -import java.util.List; +import java.util.*; @Mod.EventBusSubscriber(modid = XpTools.MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD) public final class Config { @@ -91,6 +88,9 @@ public final class Config { } private static void onConfigReload() { + // Clear cache + OperationCache.clearBlockBreakCache(); + // Parse all block break global operations blockBreakGlobalOperationItems = new ArrayList<>(); for (String s : blockBreakGlobalOperationsRaw.get()) { diff --git a/src/main/java/dev/micle/xptools/config/OperationCache.java b/src/main/java/dev/micle/xptools/config/OperationCache.java new file mode 100644 index 0000000..7469f0c --- /dev/null +++ b/src/main/java/dev/micle/xptools/config/OperationCache.java @@ -0,0 +1,24 @@ +package dev.micle.xptools.config; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +public class OperationCache { + private static HashMap> blockBreakCache; + + public static void clearBlockBreakCache() { + blockBreakCache = new HashMap<>(); + } + + public static List getBlockBreakCacheEntry(String key) { + if (blockBreakCache.containsKey(key)) { + return new ArrayList<>(blockBreakCache.get(key)); + } + return null; + } + + public static void addBlockBreakCacheEntry(String key, List value) { + blockBreakCache.putIfAbsent(key, new ArrayList<>(value)); + } +} diff --git a/src/main/java/dev/micle/xptools/events/common/OnBlockBreakEventHandler.java b/src/main/java/dev/micle/xptools/events/common/OnBlockBreakEventHandler.java index c40dd4e..e7e6d28 100644 --- a/src/main/java/dev/micle/xptools/events/common/OnBlockBreakEventHandler.java +++ b/src/main/java/dev/micle/xptools/events/common/OnBlockBreakEventHandler.java @@ -2,6 +2,7 @@ package dev.micle.xptools.events.common; import dev.micle.xptools.XpTools; import dev.micle.xptools.config.Config; +import dev.micle.xptools.config.OperationCache; import dev.micle.xptools.config.OperationItem; import net.minecraft.resources.ResourceLocation; import net.minecraft.tags.TagKey; @@ -10,6 +11,8 @@ import net.minecraftforge.event.level.BlockEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.registries.ForgeRegistries; +import java.time.Duration; +import java.time.Instant; import java.util.ArrayList; import java.util.Comparator; import java.util.List; @@ -19,31 +22,57 @@ public class OnBlockBreakEventHandler { @SubscribeEvent public void OnBlockBreakEvent(BlockEvent.BreakEvent event) { float xpToDrop = event.getExpToDrop(); - List operations = new ArrayList<>(); - // Collect operations on relevant block_id + // Get Block id ResourceLocation block_rl = ForgeRegistries.BLOCKS.getKey(event.getState().getBlock()); + String block_id = ""; if (block_rl != null) { - String block_id = block_rl.toString(); - for (OperationItem operationItem : Config.Server.blockBreakOperationItems) { - if (!operationItem.isTag() && operationItem.getId().equals(block_id)) { - operations.add(operationItem); - } - } + block_id = block_rl.toString(); } - // Collect operations on relevant tag_id - for (TagKey tagKey : event.getState().getTags().toList()) { - String tag_id = tagKey.location().toString(); - for (OperationItem operationItem : Config.Server.blockBreakOperationItems) { - if (operationItem.isTag() && operationItem.getId().equals(tag_id)) { - operations.add(operationItem); + // Collect operations + Instant start = Instant.now(); + List operations = OperationCache.getBlockBreakCacheEntry(block_id); + if (operations != null) { + XpTools.LOGGER.debug("Got operations from cache for {} [time: {}]", block_id, Duration.between(start, Instant.now()).toNanos()); + } else { + operations = new ArrayList<>(); + + // Collect operations on relevant block_id + if (!block_id.isEmpty()) { + for (OperationItem operationItem : Config.Server.blockBreakOperationItems) { + if (!operationItem.isTag() && operationItem.getId().equals(block_id)) { + operations.add(operationItem); + } } } - } - // Sort operations based on priority - operations.sort(Comparator.comparingInt(OperationItem::getPriority)); + // Collect operations on relevant tag_id + for (TagKey tagKey : event.getState().getTags().toList()) { + String tag_id = tagKey.location().toString(); + for (OperationItem operationItem : Config.Server.blockBreakOperationItems) { + if (operationItem.isTag() && operationItem.getId().equals(tag_id)) { + operations.add(operationItem); + } + } + } + + // Sort operations based on priority + operations.sort(Comparator.comparingInt(OperationItem::getPriority)); + + // Remove any operations after last operation + for (OperationItem operationItem : operations) { + if (operationItem.isLast()) { + operations = operations.subList(0, operations.indexOf(operationItem) + 1); + break; + } + } + + XpTools.LOGGER.debug("Calculated operations for {} [time: {}]", block_id, Duration.between(start, Instant.now()).toNanos()); + + // Save operations to cache + OperationCache.addBlockBreakCacheEntry(block_id, operations); + } // Add global operations before all others operations.addAll(0, Config.Server.blockBreakGlobalOperationItems); @@ -76,7 +105,6 @@ public class OnBlockBreakEventHandler { // Stop if this is the last operation if (operation.isLast()) { - operations = operations.subList(0, operations.indexOf(operation) + 1); break; } }