diff --git a/src/main/java/com/falsepattern/lib/internal/asm/CoreLoadingPlugin.java b/src/main/java/com/falsepattern/lib/internal/asm/CoreLoadingPlugin.java index a6f4e8b..38d168c 100644 --- a/src/main/java/com/falsepattern/lib/internal/asm/CoreLoadingPlugin.java +++ b/src/main/java/com/falsepattern/lib/internal/asm/CoreLoadingPlugin.java @@ -62,7 +62,6 @@ public class CoreLoadingPlugin implements IFMLLoadingPlugin { long end = System.nanoTime(); Share.LOG.info("Scanned in " + (end - start) / 1000000 + "ms"); //Initializing the rest - Share.LOG.info("Initializing mapping manager..."); MappingManager.initialize(); } diff --git a/src/main/java/com/falsepattern/lib/mapping/MappingManager.java b/src/main/java/com/falsepattern/lib/mapping/MappingManager.java index b85a6a1..a47d23a 100644 --- a/src/main/java/com/falsepattern/lib/mapping/MappingManager.java +++ b/src/main/java/com/falsepattern/lib/mapping/MappingManager.java @@ -21,6 +21,8 @@ package com.falsepattern.lib.mapping; import com.falsepattern.lib.StableAPI; +import com.falsepattern.lib.internal.FalsePatternLib; +import com.falsepattern.lib.internal.Share; import com.falsepattern.lib.internal.asm.CoreLoadingPlugin; import com.falsepattern.lib.mapping.storage.Lookup; import com.falsepattern.lib.mapping.types.MappingType; @@ -37,44 +39,83 @@ import org.objectweb.asm.tree.MethodInsnNode; import java.util.HashMap; import java.util.Map; +import java.util.concurrent.atomic.AtomicLong; @StableAPI(since = "0.10.0") public class MappingManager { - private static final Lookup internalLookup = new Lookup<>(); - private static final Lookup regularLookup = new Lookup<>(); - private static final Map stringPool = new HashMap<>(); + private static Lookup internalLookup; + private static Lookup regularLookup; private static boolean initialized = false; private static final Object MUTEX = new Object(); + private static final AtomicLong lastInitializedAt = new AtomicLong(); + + private static class CleanupThread extends Thread { + public CleanupThread() { + setName("MappingManager Cleanup Watchdog"); + setDaemon(true); + } + + @Override + public void run() { + while (true) { + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + synchronized (MUTEX) { + long time = System.currentTimeMillis(); + long lastInit = lastInitializedAt.get(); + if (time - lastInit < 10_000) { + continue; + } + Share.LOG.info("Terminating MappingManager"); + internalLookup = null; + regularLookup = null; + initialized = false; + return; + } + } + } + } @SneakyThrows public static void initialize() { synchronized (MUTEX) { if (initialized) { + lastInitializedAt.set(System.currentTimeMillis()); return; } initialized = true; - } - val classMappings = - new String(ResourceUtil.getResourceBytesFromJar("/classes.csv", CoreLoadingPlugin.class)).split("\n"); - for (int i = 1; i < classMappings.length; i++) { - val line = classMappings[i].split(","); - val clazz = new UniversalClass(line, stringPool); - internalLookup.unwrap(clazz.internalName, clazz); - regularLookup.unwrap(clazz.regularName, clazz); - } - var fieldMappings = - new String(ResourceUtil.getResourceBytesFromJar("/fields.csv", CoreLoadingPlugin.class)).split("\n"); - for (int i = 1; i < fieldMappings.length; i++) { - val line = fieldMappings[i].split(","); - val clazz = internalLookup.get(MappingType.Notch, line[0].substring(0, line[0].lastIndexOf('/'))); - UniversalField.createAndAddToParent(clazz, line, stringPool); - } - val methodMappings = - new String(ResourceUtil.getResourceBytesFromJar("/methods.csv", CoreLoadingPlugin.class)).split("\n"); - for (int i = 1; i < methodMappings.length; i++) { - val line = methodMappings[i].split(","); - val clazz = internalLookup.get(MappingType.Notch, line[0].substring(0, line[0].lastIndexOf('/'))); - UniversalMethod.createAndAddToParent(clazz, line, stringPool); + val cleanupThread = new CleanupThread(); + Share.LOG.info("Initializing MappingManager"); + internalLookup = new Lookup<>(); + regularLookup = new Lookup<>(); + val stringPool = new HashMap(); + val classMappings = + new String(ResourceUtil.getResourceBytesFromJar("/classes.csv", CoreLoadingPlugin.class)).split("\n"); + for (int i = 1; i < classMappings.length; i++) { + val line = classMappings[i].split(","); + val clazz = new UniversalClass(line, stringPool); + internalLookup.unwrap(clazz.internalName, clazz); + regularLookup.unwrap(clazz.regularName, clazz); + } + var fieldMappings = + new String(ResourceUtil.getResourceBytesFromJar("/fields.csv", CoreLoadingPlugin.class)).split("\n"); + for (int i = 1; i < fieldMappings.length; i++) { + val line = fieldMappings[i].split(","); + val clazz = internalLookup.get(MappingType.Notch, line[0].substring(0, line[0].lastIndexOf('/'))); + UniversalField.createAndAddToParent(clazz, line, stringPool); + } + val methodMappings = + new String(ResourceUtil.getResourceBytesFromJar("/methods.csv", CoreLoadingPlugin.class)).split("\n"); + for (int i = 1; i < methodMappings.length; i++) { + val line = methodMappings[i].split(","); + val clazz = internalLookup.get(MappingType.Notch, line[0].substring(0, line[0].lastIndexOf('/'))); + UniversalMethod.createAndAddToParent(clazz, line, stringPool); + } + lastInitializedAt.set(System.currentTimeMillis()); + cleanupThread.start(); } }