From ef4337d2c342c1d8e05f5be70e4ce16c5f01409f Mon Sep 17 00:00:00 2001 From: C-H716 <1536152356@qq.com> Date: Mon, 29 Sep 2025 19:53:33 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E7=BC=93=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ae/menu/EntitySpeedTickerMenu.java | 7 +- .../ae/parts/EntitySpeedTickerPart.java | 5 +- .../util/entitySpeed/ConfigParsingUtils.java | 178 ++++++++++-------- 3 files changed, 106 insertions(+), 84 deletions(-) diff --git a/src/main/java/com/extendedae_plus/ae/menu/EntitySpeedTickerMenu.java b/src/main/java/com/extendedae_plus/ae/menu/EntitySpeedTickerMenu.java index 008a9ff..e8f7d2a 100644 --- a/src/main/java/com/extendedae_plus/ae/menu/EntitySpeedTickerMenu.java +++ b/src/main/java/com/extendedae_plus/ae/menu/EntitySpeedTickerMenu.java @@ -6,7 +6,6 @@ import appeng.menu.implementations.UpgradeableMenu; import appeng.menu.slot.OptionalFakeSlot; import com.extendedae_plus.ae.parts.EntitySpeedTickerPart; import com.extendedae_plus.ae.screen.EntitySpeedTickerScreen; -import com.extendedae_plus.config.ModConfig; import com.extendedae_plus.init.ModItems; import com.extendedae_plus.init.ModMenuTypes; import com.extendedae_plus.util.entitySpeed.ConfigParsingUtils; @@ -17,8 +16,6 @@ import net.minecraft.world.inventory.Slot; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraftforge.registries.ForgeRegistries; -import java.util.List; - /** * 实体加速器菜单,负责管理客户端与服务端的数据同步,处理加速卡、能量卡和目标方块的状态。 */ @@ -135,8 +132,8 @@ public class EntitySpeedTickerMenu extends UpgradeableMenu BLACKLIST_SUPPLIER = () -> ModConfig.INSTANCE.entityTickerBlackList; + private static final Supplier MULTIPLIERS_SUPPLIER = () -> ModConfig.INSTANCE.entityTickerMultipliers; + + // 缓存字段 + private static volatile Map cachedBlacklist = null; + private static volatile Map cachedMultiplierEntries = null; + private static volatile String[] cachedBlacklistSourceSnapshot = null; + private static volatile String[] cachedMultiplierSourceSnapshot = null; + private static volatile Map blacklistResultCache = new HashMap<>(); + private static volatile Map multiplierResultCache = new HashMap<>(); + private static final Object CACHE_LOCK = new Object(); + private static final AtomicLong callCounter = new AtomicLong(0); + private static final long CHECK_INTERVAL = 100; + + /* + 初始化缓存,在模组加载时调用 + */ + static { + reload(); } /** @@ -98,116 +117,120 @@ public final class ConfigParsingUtils { /** * 检查方块是否在黑名单中。 */ - public static boolean isBlockBlacklisted(String blockId, List blacklist) { - if (blockId == null) return false; - return getCachedBlacklist(blacklist).stream().anyMatch(p -> p.matcher(blockId).matches()); + public static boolean isBlockBlacklisted(String blockId) { + if (blockId == null || BLACKLIST_SUPPLIER.get() == null || BLACKLIST_SUPPLIER.get().length == 0) { + return false; + } + checkConfigChange(); + return blacklistResultCache.computeIfAbsent(blockId, id -> + getCachedBlacklist().values().stream().anyMatch(p -> p.matcher(id).matches()) + ); } /** * 获取方块的倍率。 */ - public static double getMultiplierForBlock(String blockId, List multipliers) { - if (blockId == null) return 1.0; - double maxMultiplier = 1.0; - for (MultiplierEntry me : getCachedMultiplierEntries(multipliers)) { - if (me.pattern.matcher(blockId).matches()) { - maxMultiplier = Math.max(maxMultiplier, me.multiplier); - } + public static double getMultiplierForBlock(String blockId) { + if (blockId == null || MULTIPLIERS_SUPPLIER.get() == null || MULTIPLIERS_SUPPLIER.get().length == 0) { + return 1.0; } - return maxMultiplier; + checkConfigChange(); + return multiplierResultCache.computeIfAbsent(blockId, id -> { + double maxMultiplier = 1.0; + for (MultiplierEntry me : getCachedMultiplierEntries().values()) { + if (me.pattern.matcher(id).matches()) { + maxMultiplier = Math.max(maxMultiplier, me.multiplier); + } + } + return maxMultiplier; + }); } - public static List compilePatterns(List raw) { - List out = new ArrayList<>(); + /** + * 编译黑名单配置为 Map。 + */ + public static Map compilePatterns(String[] raw) { + Map out = new HashMap<>(); if (raw == null) return out; for (String s : raw) { if (s == null || s.trim().isEmpty()) continue; + String trimmed = s.trim(); try { - out.add(compilePattern(s)); + out.put(trimmed, compilePattern(trimmed)); } catch (IllegalArgumentException e) { - EAP$LOGGER.warn("Failed to compile pattern '{}': {}", s, e.getMessage()); + EAP$LOGGER.warn("Failed to compile pattern '{}': {}", trimmed, e.getMessage()); } } return out; } - public static List parseMultiplierList(List raw) { - List out = new ArrayList<>(); + /** + * 解析倍率配置为 Map。 + */ + public static Map parseMultiplierList(String[] raw) { + Map out = new HashMap<>(); if (raw == null) return out; for (String s : raw) { - MultiplierEntry me = parseMultiplierEntry(s); - if (me != null) out.add(me); + if (s == null || s.trim().isEmpty()) continue; + String trimmed = s.trim(); + MultiplierEntry me = parseMultiplierEntry(trimmed); + if (me != null) out.put(trimmed, me); } return out; } - // ------------------ 全局缓存与接口 ------------------ - private static volatile List cachedBlacklist = null; - private static volatile List cachedMultiplierEntries = null; - private static volatile List cachedBlacklistSourceSnapshot = null; - private static volatile List cachedMultiplierSourceSnapshot = null; - private static final Object CACHE_LOCK = new Object(); - /** * 获取已解析并缓存的黑名单(线程安全、懒加载)。 */ - public static List getCachedBlacklist(List source) { - List normalized = normalizeSource(source); - if (cachedBlacklist != null && listEquals(cachedBlacklistSourceSnapshot, normalized)) { - return Collections.unmodifiableList(cachedBlacklist); + private static Map getCachedBlacklist() { + String[] source = BLACKLIST_SUPPLIER.get(); + if (cachedBlacklist != null && Arrays.equals(cachedBlacklistSourceSnapshot, source)) { + return Collections.unmodifiableMap(cachedBlacklist); } synchronized (CACHE_LOCK) { - if (cachedBlacklist == null || !listEquals(cachedBlacklistSourceSnapshot, normalized)) { - cachedBlacklist = compilePatterns(normalized); - cachedBlacklistSourceSnapshot = normalized.isEmpty() ? Collections.emptyList() : new ArrayList<>(normalized); + if (cachedBlacklist == null || !Arrays.equals(cachedBlacklistSourceSnapshot, source)) { + cachedBlacklist = compilePatterns(source); + cachedBlacklistSourceSnapshot = source == null ? new String[0] : source.clone(); } - return Collections.unmodifiableList(cachedBlacklist); + return Collections.unmodifiableMap(cachedBlacklist); } } /** * 获取已解析并缓存的倍率列表(线程安全、懒加载)。 */ - public static List getCachedMultiplierEntries(List source) { - List normalized = normalizeSource(source); - if (cachedMultiplierEntries != null && listEquals(cachedMultiplierSourceSnapshot, normalized)) { - return Collections.unmodifiableList(cachedMultiplierEntries); + private static Map getCachedMultiplierEntries() { + String[] source = MULTIPLIERS_SUPPLIER.get(); + if (cachedMultiplierEntries != null && Arrays.equals(cachedMultiplierSourceSnapshot, source)) { + return Collections.unmodifiableMap(cachedMultiplierEntries); } synchronized (CACHE_LOCK) { - if (cachedMultiplierEntries == null || !listEquals(cachedMultiplierSourceSnapshot, normalized)) { - cachedMultiplierEntries = parseMultiplierList(normalized); - cachedMultiplierSourceSnapshot = normalized.isEmpty() ? Collections.emptyList() : new ArrayList<>(normalized); + if (cachedMultiplierEntries == null || !Arrays.equals(cachedMultiplierSourceSnapshot, source)) { + cachedMultiplierEntries = parseMultiplierList(source); + cachedMultiplierSourceSnapshot = source == null ? new String[0] : source.clone(); } - return Collections.unmodifiableList(cachedMultiplierEntries); + return Collections.unmodifiableMap(cachedMultiplierEntries); } } - // Normalize the incoming source list: trim entries, drop blanks, keep stable ordering - private static List normalizeSource(java.util.List source) { - List out = new ArrayList<>(); - if (source == null) return out; - for (String s : source) { - if (s == null) continue; - String t = s.trim(); - if (t.isEmpty()) continue; - out.add(t); - } - return out; - } - - // Null-safe equality for two lists of strings. Uses size + element equals. - private static boolean listEquals(List a, List b) { - if (a == b) return true; - if (a == null || b == null) return false; - if (a.size() != b.size()) return false; - for (int i = 0; i < a.size(); i++) { - if (!a.get(i).equals(b.get(i))) return false; - } - return true; - } - /** - * 清空缓存,下一次获取时将重新从提供的源解析(或调用方可以重新调用 getter)。 + * 每 100 次调用检查配置是否变化。 + */ + private static void checkConfigChange() { + if (callCounter.incrementAndGet() % CHECK_INTERVAL == 0) { + String[] currentBlacklist = BLACKLIST_SUPPLIER.get(); + String[] currentMultipliers = MULTIPLIERS_SUPPLIER.get(); + synchronized (CACHE_LOCK) { + if (cachedBlacklistSourceSnapshot == null || !Arrays.equals(cachedBlacklistSourceSnapshot, currentBlacklist) || + cachedMultiplierSourceSnapshot == null || !Arrays.equals(cachedMultiplierSourceSnapshot, currentMultipliers)) { + reload(); + } + } + } + } + + /** + * 清空缓存,下一次获取时将重新解析。 */ public static void reload() { synchronized (CACHE_LOCK) { @@ -215,6 +238,9 @@ public final class ConfigParsingUtils { cachedMultiplierEntries = null; cachedBlacklistSourceSnapshot = null; cachedMultiplierSourceSnapshot = null; + blacklistResultCache.clear(); + multiplierResultCache.clear(); + callCounter.set(0); } } } \ No newline at end of file