diff --git a/core/src/main/java/net/momirealms/craftengine/core/block/AbstractBlockManager.java b/core/src/main/java/net/momirealms/craftengine/core/block/AbstractBlockManager.java index f39da7dd4..870971aac 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/block/AbstractBlockManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/block/AbstractBlockManager.java @@ -363,15 +363,17 @@ public abstract class AbstractBlockManager extends AbstractModelGenerator implem } catch (IOException e) { AbstractBlockManager.this.plugin.logger().warn("Error while loading custom block states allocation cache", e); } - for (PendingConfigSection section : this.pendingConfigSections) { - ResourceConfigUtils.runCatching( - section.path(), - section.node(), - () -> parseSection(section.pack(), section.path(), section.node(), section.id(), section.config()), - () -> GsonHelper.get().toJson(section.config()) - ); + if (!this.pendingConfigSections.isEmpty()) { + for (PendingConfigSection section : this.pendingConfigSections) { + ResourceConfigUtils.runCatching( + section.path(), + section.node(), + () -> parseSection(section.pack(), section.path(), section.node(), section.id(), section.config()), + () -> GsonHelper.get().toJson(section.config()) + ); + } + this.pendingConfigSections.clear(); } - this.pendingConfigSections.clear(); } @Override diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/allocator/IdAllocator.java b/core/src/main/java/net/momirealms/craftengine/core/pack/allocator/IdAllocator.java index 3a42d71ed..0386d525c 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/allocator/IdAllocator.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/allocator/IdAllocator.java @@ -19,14 +19,18 @@ import java.util.function.Predicate; public class IdAllocator { private final Path cacheFilePath; private final BiMap forcedIdMap = HashBiMap.create(128); - private final Map cachedIdMap = new HashMap<>(); private final BitSet occupiedIdSet = new BitSet(); private final Map> pendingAllocations = new LinkedHashMap<>(); + private final Map cachedIdMap = new HashMap<>(); + + private long lastModified; private int nextAutoId; private int minId; private int maxId; + private boolean dirty; + public IdAllocator(Path cacheFilePath) { this.cacheFilePath = cacheFilePath; } @@ -43,7 +47,6 @@ public class IdAllocator { this.occupiedIdSet.clear(); this.forcedIdMap.clear(); this.pendingAllocations.clear(); - this.cachedIdMap.clear(); } /** @@ -81,6 +84,7 @@ public class IdAllocator { allocateId(newId, future); this.cachedIdMap.put(name, newId); + this.dirty = true; } this.pendingAllocations.clear(); @@ -164,12 +168,16 @@ public class IdAllocator { } } - for (String id : idsToRemove) { - Integer removedId = this.cachedIdMap.remove(id); - if (removedId != null && !this.forcedIdMap.containsValue(removedId)) { - this.occupiedIdSet.clear(removedId); + if (!idsToRemove.isEmpty()) { + this.dirty = true; + for (String id : idsToRemove) { + Integer removedId = this.cachedIdMap.remove(id); + if (removedId != null && !this.forcedIdMap.containsValue(removedId)) { + this.occupiedIdSet.clear(removedId); + } } } + return idsToRemove; } @@ -205,15 +213,23 @@ public class IdAllocator { */ public void loadFromCache() throws IOException { if (!Files.exists(this.cacheFilePath)) { + if (!this.cachedIdMap.isEmpty()) { + this.cachedIdMap.clear(); + } return; } - JsonElement element = GsonHelper.readJsonFile(this.cacheFilePath); - if (element instanceof JsonObject jsonObject) { - for (Map.Entry entry : jsonObject.entrySet()) { - if (entry.getValue() instanceof JsonPrimitive primitive) { - int id = primitive.getAsInt(); - this.cachedIdMap.put(entry.getKey(), id); + long lastTime = Files.getLastModifiedTime(this.cacheFilePath).toMillis(); + if (lastTime != this.lastModified) { + this.lastModified = lastTime; + this.cachedIdMap.clear(); + JsonElement element = GsonHelper.readJsonFile(this.cacheFilePath); + if (element instanceof JsonObject jsonObject) { + for (Map.Entry entry : jsonObject.entrySet()) { + if (entry.getValue() instanceof JsonPrimitive primitive) { + int id = primitive.getAsInt(); + this.cachedIdMap.put(entry.getKey(), id); + } } } } @@ -223,6 +239,13 @@ public class IdAllocator { * 保存缓存到文件 */ public void saveToCache() throws IOException { + // 如果没有更改 + if (!this.dirty) { + return; + } + + this.dirty = false; + // 创建按ID排序的TreeMap Map sortedById = new TreeMap<>(); for (Map.Entry entry : this.cachedIdMap.entrySet()) { diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/allocator/VisualBlockStateAllocator.java b/core/src/main/java/net/momirealms/craftengine/core/pack/allocator/VisualBlockStateAllocator.java index 2e75df0cd..9e7dc27d4 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/allocator/VisualBlockStateAllocator.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/allocator/VisualBlockStateAllocator.java @@ -27,6 +27,9 @@ public class VisualBlockStateAllocator { private final Function factory; private final Set forcedStates = new HashSet<>(); + private boolean dirty; + private long lastModified; + public VisualBlockStateAllocator(Path cacheFilePath, BlockStateCandidate[] candidates, Function factory) { this.cacheFilePath = cacheFilePath; this.candidates = candidates; @@ -37,7 +40,6 @@ public class VisualBlockStateAllocator { for (int i = 0; i < this.pendingAllocationFutures.length; i++) { this.pendingAllocationFutures[i] = new ArrayList<>(); } - this.cachedBlockStates.clear(); this.pendingAllocations.clear(); this.forcedStates.clear(); } @@ -73,8 +75,11 @@ public class VisualBlockStateAllocator { idsToRemove.add(entry.getKey()); } } - for (String id : idsToRemove) { - this.cachedBlockStates.remove(id); + if (!idsToRemove.isEmpty()) { + this.dirty = true; + for (String id : idsToRemove) { + this.cachedBlockStates.remove(id); + } } return idsToRemove; } @@ -144,16 +149,25 @@ public class VisualBlockStateAllocator { */ public void loadFromCache() throws IOException { if (!Files.exists(this.cacheFilePath)) { + if (!this.cachedBlockStates.isEmpty()) { + this.cachedBlockStates.clear(); + } return; } - JsonElement element = GsonHelper.readJsonFile(this.cacheFilePath); - if (element instanceof JsonObject jsonObject) { - for (Map.Entry entry : jsonObject.entrySet()) { - if (entry.getValue() instanceof JsonPrimitive primitive) { - String id = primitive.getAsString(); - BlockStateWrapper state = this.factory.apply(id); - if (state != null) { - this.cachedBlockStates.put(entry.getKey(), state); + + long lastTime = Files.getLastModifiedTime(this.cacheFilePath).toMillis(); + if (lastTime != this.lastModified) { + this.lastModified = lastTime; + this.cachedBlockStates.clear(); + JsonElement element = GsonHelper.readJsonFile(this.cacheFilePath); + if (element instanceof JsonObject jsonObject) { + for (Map.Entry entry : jsonObject.entrySet()) { + if (entry.getValue() instanceof JsonPrimitive primitive) { + String id = primitive.getAsString(); + BlockStateWrapper state = this.factory.apply(id); + if (state != null) { + this.cachedBlockStates.put(entry.getKey(), state); + } } } } @@ -164,6 +178,12 @@ public class VisualBlockStateAllocator { * 保存缓存到文件 */ public void saveToCache() throws IOException { + if (!this.dirty) { + return; + } + + this.dirty = false; + // 创建按ID排序的TreeMap Map sortedById = new TreeMap<>(); for (Map.Entry entry : this.cachedBlockStates.entrySet()) {