From 0a941684f8eb65b0b2f458a479fb7013baa0d7c1 Mon Sep 17 00:00:00 2001 From: TheBrokenRail Date: Wed, 24 Jun 2020 14:03:02 -0400 Subject: [PATCH] Multi-Threading --- .../thebrokenrail/modupdater/ModUpdater.java | 23 +++++--- .../client/gui/ModUpdateScreen.java | 29 ++++++++-- .../strategy/ModUpdateStrategies.java | 53 ++++++++++++++----- .../thebrokenrail/modupdater/util/Util.java | 6 ++- .../assets/modupdater/lang/en_us.json | 3 +- 5 files changed, 88 insertions(+), 26 deletions(-) diff --git a/src/main/java/com/thebrokenrail/modupdater/ModUpdater.java b/src/main/java/com/thebrokenrail/modupdater/ModUpdater.java index b4a308b..274697d 100644 --- a/src/main/java/com/thebrokenrail/modupdater/ModUpdater.java +++ b/src/main/java/com/thebrokenrail/modupdater/ModUpdater.java @@ -6,6 +6,8 @@ import net.fabricmc.api.ModInitializer; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import java.util.Objects; + public class ModUpdater implements ModInitializer { public static final String NAMESPACE = "modupdater"; @@ -21,19 +23,28 @@ public class ModUpdater implements ModInitializer { private static ModUpdate[] updates; + private static Thread updateThread; + public static ModUpdate[] getUpdates() { if (updates == null) { - updates = ModUpdateStrategies.findAvailableUpdates(); + if (Thread.currentThread() == updateThread) { + updates = ModUpdateStrategies.findAvailableUpdates(); + } else { + return null; + } } return updates; } @Override public void onInitialize() { - getLogger().info("Checking For Mod Updates..."); - for (ModUpdate update : getUpdates()) { - getLogger().info(update.text + " (" + update.downloadURL + ')'); - } - getLogger().info(updates.length + " Mod Update(s) Found"); + updateThread = new Thread(() -> { + getLogger().info("Checking For Mod Updates..."); + for (ModUpdate update : Objects.requireNonNull(getUpdates())) { + getLogger().info(update.text + " (" + update.downloadURL + ')'); + } + getLogger().info(updates.length + " Mod Update(s) Found"); + }); + //updateThread.start(); } } diff --git a/src/main/java/com/thebrokenrail/modupdater/client/gui/ModUpdateScreen.java b/src/main/java/com/thebrokenrail/modupdater/client/gui/ModUpdateScreen.java index 3fa7434..e2296b9 100644 --- a/src/main/java/com/thebrokenrail/modupdater/client/gui/ModUpdateScreen.java +++ b/src/main/java/com/thebrokenrail/modupdater/client/gui/ModUpdateScreen.java @@ -14,9 +14,11 @@ import net.minecraft.client.util.math.MatrixStack; import net.minecraft.text.TranslatableText; import net.minecraft.util.Util; +import java.util.Arrays; + @Environment(EnvType.CLIENT) public class ModUpdateScreen extends Screen { - private ModUpdateListWidget list; + public ModUpdateListWidget list; private ButtonWidget download; private final Screen parent; @@ -56,13 +58,25 @@ public class ModUpdateScreen extends Screen { @Environment(EnvType.CLIENT) private static class ModUpdateListWidget extends EntryListWidget { private final ModUpdateScreen screen; + private ModUpdate[] updates = null; private ModUpdateListWidget(MinecraftClient client, ModUpdateScreen screen) { super(client, screen.width, screen.height, 32, screen.height - 40, 18); this.screen = screen; - for (ModUpdate update : ModUpdater.getUpdates()) { - addEntry(new ModUpdateEntry(update, screen, this)); + reload(); + } + + public void reload() { + ModUpdate[] newUpdates = ModUpdater.getUpdates(); + if (!Arrays.equals(updates, newUpdates)) { + clearEntries(); + if (newUpdates != null) { + for (ModUpdate update : newUpdates) { + addEntry(new ModUpdateEntry(update, screen, this)); + } + } + updates = newUpdates; } } @@ -100,6 +114,15 @@ public class ModUpdateScreen extends Screen { protected boolean isFocused() { return screen.getFocused() == this; } + + @Override + public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) { + reload(); + super.render(matrices, mouseX, mouseY, delta); + if (updates == null) { + drawCenteredText(matrices, screen.textRenderer, new TranslatableText("gui.modupdater.loading"), width / 2, height / 2 - screen.textRenderer.fontHeight, 16777215); + } + } } @Environment(EnvType.CLIENT) diff --git a/src/main/java/com/thebrokenrail/modupdater/strategy/ModUpdateStrategies.java b/src/main/java/com/thebrokenrail/modupdater/strategy/ModUpdateStrategies.java index b216b06..f902dd4 100644 --- a/src/main/java/com/thebrokenrail/modupdater/strategy/ModUpdateStrategies.java +++ b/src/main/java/com/thebrokenrail/modupdater/strategy/ModUpdateStrategies.java @@ -13,6 +13,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; public class ModUpdateStrategies { private static final Map data = new HashMap<>(); @@ -40,26 +41,50 @@ public class ModUpdateStrategies { public static ModUpdate[] findAvailableUpdates() { List updates = new ArrayList<>(); + AtomicInteger remaining = new AtomicInteger(0); + for (ModContainer mod : FabricLoader.getInstance().getAllMods()) { - ModMetadata metadata = mod.getMetadata(); - String name = metadata.getName() + " (" + metadata.getId() + ')'; + Thread thread = new Thread(() -> { + ModMetadata metadata = mod.getMetadata(); + String name = metadata.getName() + " (" + metadata.getId() + ')'; - ModUpdate update = null; - if (metadata.containsCustomValue(ModUpdater.NAMESPACE)) { - try { - update = checkForUpdate(metadata, new ConfigObject.ConfigObjectCustom(metadata.getCustomValue(ModUpdater.NAMESPACE).getAsObject()), name); - } catch (ClassCastException e) { - ModUpdater.invalidModUpdaterConfig(name); + ModUpdate update = null; + if (metadata.containsCustomValue(ModUpdater.NAMESPACE)) { + try { + update = checkForUpdate(metadata, new ConfigObject.ConfigObjectCustom(metadata.getCustomValue(ModUpdater.NAMESPACE).getAsObject()), name); + } catch (ClassCastException e) { + ModUpdater.invalidModUpdaterConfig(name); + } + } else { + ConfigObject obj = HardcodedData.getData(metadata.getId()); + if (obj != null) { + update = checkForUpdate(metadata, obj, name); + } } - } else { - ConfigObject obj = HardcodedData.getData(metadata.getId()); - if (obj != null) { - update = checkForUpdate(metadata, obj, name); + + if (update != null) { + synchronized (updates) { + updates.add(update); + } } + + synchronized (remaining) { + remaining.decrementAndGet(); + remaining.notifyAll(); + } + }); + synchronized (remaining) { + remaining.incrementAndGet(); } + thread.start(); + } - if (update != null) { - updates.add(update); + synchronized (remaining) { + while (remaining.get() > 0) { + try { + remaining.wait(); + } catch (InterruptedException ignored) { + } } } diff --git a/src/main/java/com/thebrokenrail/modupdater/util/Util.java b/src/main/java/com/thebrokenrail/modupdater/util/Util.java index 733ab04..5f619d1 100644 --- a/src/main/java/com/thebrokenrail/modupdater/util/Util.java +++ b/src/main/java/com/thebrokenrail/modupdater/util/Util.java @@ -35,8 +35,10 @@ public class Util { public static final String JAR_EXTENSION = ".jar"; public static String getVersionFromFileName(String fileName) { - int index = fileName.indexOf("-"); - fileName = fileName.substring(index != -1 ? index + 1 : 0); + while (!Character.isDigit(fileName.charAt(0))) { + int index = fileName.indexOf("-"); + fileName = fileName.substring(index != -1 ? index + 1 : 0); + } if (fileName.endsWith(JAR_EXTENSION)) { fileName = fileName.substring(0, fileName.length() - JAR_EXTENSION.length()); } diff --git a/src/main/resources/assets/modupdater/lang/en_us.json b/src/main/resources/assets/modupdater/lang/en_us.json index c2f7218..9f21a3b 100644 --- a/src/main/resources/assets/modupdater/lang/en_us.json +++ b/src/main/resources/assets/modupdater/lang/en_us.json @@ -1,4 +1,5 @@ { "gui.modupdater.title": "Available Mod Updates", - "gui.modupdater.download": "Download" + "gui.modupdater.download": "Download", + "gui.modupdater.loading": "Loading..." } \ No newline at end of file