Fix occasional CME when rebuilding blockstate cache

This commit is contained in:
embeddedt 2023-02-08 09:56:17 -05:00
parent 0ffb3cc973
commit 3d7422496e

View File

@ -14,6 +14,7 @@ import org.embeddedt.modernfix.ModernFix;
import org.embeddedt.modernfix.core.config.ModernFixConfig; import org.embeddedt.modernfix.core.config.ModernFixConfig;
import org.embeddedt.modernfix.util.BakeReason; import org.embeddedt.modernfix.util.BakeReason;
import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
@ -40,16 +41,22 @@ public class BlockStateCacheHandler {
} }
public static void rebuildParallel(boolean force) { public static void rebuildParallel(boolean force) {
if(force || needToBake()) { if(currentRebuildThread != null) {
if(currentRebuildThread != null) { ModernFix.LOGGER.warn("Interrupting previous blockstate cache rebuild");
currentRebuildThread.stopRebuild(); currentRebuildThread.stopRebuild();
try { try {
currentRebuildThread.join(); currentRebuildThread.join();
} catch(InterruptedException e) { } catch(InterruptedException e) {
throw new RuntimeException("Don't interrupt Minecraft threads", e); throw new RuntimeException("Don't interrupt Minecraft threads", e);
}
} }
currentRebuildThread = new RebuildThread(); ModernFix.LOGGER.debug("Rebuild thread exited");
}
if(force || needToBake()) {
ArrayList<BlockState> stateList = new ArrayList<>(Block.BLOCK_STATE_REGISTRY.size());
for (BlockState blockState : Block.BLOCK_STATE_REGISTRY) {
stateList.add(blockState);
}
currentRebuildThread = new RebuildThread(stateList);
if(ModernFixConfig.REBUILD_BLOCKSTATES_ASYNC.get()) if(ModernFixConfig.REBUILD_BLOCKSTATES_ASYNC.get())
currentRebuildThread.start(); currentRebuildThread.start();
else { else {
@ -63,10 +70,12 @@ public class BlockStateCacheHandler {
private static class RebuildThread extends Thread { private static class RebuildThread extends Thread {
private boolean stopRebuild = false; private boolean stopRebuild = false;
private final List<BlockState> blockStateList;
public RebuildThread() { public RebuildThread(List<BlockState> statesToInit) {
this.setName("ModernFix blockstate cache rebuild thread"); this.setName("ModernFix blockstate cache rebuild thread");
this.setPriority(Thread.MIN_PRIORITY + 1); this.setPriority(Thread.MIN_PRIORITY + 1);
this.blockStateList = statesToInit;
} }
public void stopRebuild() { public void stopRebuild() {
@ -74,7 +83,7 @@ public class BlockStateCacheHandler {
} }
private void rebuildCache() { private void rebuildCache() {
Iterator<BlockState> stateIterator = Block.BLOCK_STATE_REGISTRY.iterator(); Iterator<BlockState> stateIterator = blockStateList.iterator();
while(!stopRebuild && stateIterator.hasNext()) { while(!stopRebuild && stateIterator.hasNext()) {
stateIterator.next().initCache(); stateIterator.next().initCache();
} }
@ -85,7 +94,7 @@ public class BlockStateCacheHandler {
public void run() { public void run() {
Stopwatch realtimeStopwatch = Stopwatch.createStarted(); Stopwatch realtimeStopwatch = Stopwatch.createStarted();
/* Run some special sauce for Refined Storage since it has very slow collision shapes */ /* Run some special sauce for Refined Storage since it has very slow collision shapes */
List<BlockState> specialStates = StreamSupport.stream(Block.BLOCK_STATE_REGISTRY.spliterator(), false) List<BlockState> specialStates = blockStateList.stream()
.filter(state -> PRECACHED_COLLISION_SHAPES.contains(state.getBlock().getRegistryName().getNamespace())).collect(Collectors.toList()); .filter(state -> PRECACHED_COLLISION_SHAPES.contains(state.getBlock().getRegistryName().getNamespace())).collect(Collectors.toList());
CompletableFuture.runAsync(() -> { CompletableFuture.runAsync(() -> {
specialStates.parallelStream() specialStates.parallelStream()