From be587ec40b9d303fcb69e9aeff5a0e574521801a Mon Sep 17 00:00:00 2001 From: artdeell Date: Sun, 8 Jan 2023 22:55:54 +0300 Subject: [PATCH] Wait for all tasks to finish before starting the game --- .../net/kdt/pojavlaunch/LauncherActivity.java | 14 ++------- .../progresskeeper/ProgressKeeper.java | 31 ++++++++++++++++++- 2 files changed, 32 insertions(+), 13 deletions(-) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/LauncherActivity.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/LauncherActivity.java index b09bc3350..c479b9d75 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/LauncherActivity.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/LauncherActivity.java @@ -1,13 +1,10 @@ package net.kdt.pojavlaunch; -import static android.os.Build.VERSION_CODES.P; - import static net.kdt.pojavlaunch.MainActivity.INTENT_MINECRAFT_VERSION; import android.Manifest; import android.content.Intent; import android.content.pm.PackageManager; -import android.graphics.Rect; import android.os.Build; import android.os.Bundle; import android.util.Log; @@ -23,14 +20,10 @@ import androidx.core.content.ContextCompat; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentContainerView; import androidx.fragment.app.FragmentManager; -import androidx.lifecycle.Lifecycle; -import androidx.lifecycle.LifecycleEventObserver; -import androidx.lifecycle.LifecycleOwner; import com.kdt.mcgui.ProgressLayout; import com.kdt.mcgui.mcAccountSpinner; -import net.kdt.pojavlaunch.fragments.LocalLoginFragment; import net.kdt.pojavlaunch.fragments.MainMenuFragment; import net.kdt.pojavlaunch.fragments.MicrosoftLoginFragment; import net.kdt.pojavlaunch.extra.ExtraConstants; @@ -43,14 +36,11 @@ import net.kdt.pojavlaunch.prefs.LauncherPreferences; import net.kdt.pojavlaunch.prefs.screens.LauncherPreferenceFragment; import net.kdt.pojavlaunch.progresskeeper.ProgressKeeper; import net.kdt.pojavlaunch.services.ProgressServiceKeeper; -import net.kdt.pojavlaunch.tasks.AsyncAssetManager; import net.kdt.pojavlaunch.tasks.AsyncMinecraftDownloader; import net.kdt.pojavlaunch.tasks.AsyncVersionList; import net.kdt.pojavlaunch.value.launcherprofiles.LauncherProfiles; import net.kdt.pojavlaunch.value.launcherprofiles.MinecraftProfile; -import java.util.List; - public class LauncherActivity extends BaseActivity { public static final String SETTING_FRAGMENT_TAG = "SETTINGS_FRAGMENT"; @@ -134,7 +124,7 @@ public class LauncherActivity extends BaseActivity { } String normalizedVersionId = AsyncMinecraftDownloader.normalizeVersionId(prof.lastVersionId); JMinecraftVersionList.Version mcVersion = AsyncMinecraftDownloader.getListedVersion(normalizedVersionId); - new AsyncMinecraftDownloader(this, mcVersion, normalizedVersionId, () -> runOnUiThread(() -> { + new AsyncMinecraftDownloader(this, mcVersion, normalizedVersionId, () -> ProgressKeeper.waitUntilDone(()-> runOnUiThread(() -> { try { Intent mainIntent = new Intent(getBaseContext(), MainActivity.class); mainIntent.putExtra(INTENT_MINECRAFT_VERSION, normalizedVersionId); @@ -145,7 +135,7 @@ public class LauncherActivity extends BaseActivity { } catch (Throwable e) { Tools.showError(getBaseContext(), e); } - })); + }))); return false; }; diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/progresskeeper/ProgressKeeper.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/progresskeeper/ProgressKeeper.java index d3f80a36e..9b5b76b80 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/progresskeeper/ProgressKeeper.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/progresskeeper/ProgressKeeper.java @@ -1,13 +1,17 @@ package net.kdt.pojavlaunch.progresskeeper; +import android.util.Log; + import java.util.ArrayList; +import java.util.Collections; +import java.util.List; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedQueue; public class ProgressKeeper { private static final ConcurrentHashMap> sProgressListeners = new ConcurrentHashMap<>(); private static final ConcurrentHashMap sProgressStates = new ConcurrentHashMap<>(); - private static final ArrayList sTaskCountListeners = new ArrayList<>(); + private static final List sTaskCountListeners = Collections.synchronizedList(new ArrayList<>()); public static void submitProgress(String progressRecord, int progress, int resid, Object... va) { ProgressState progressState = sProgressStates.get(progressRecord); @@ -72,6 +76,31 @@ public class ProgressKeeper { public static void removeTaskCountListener(TaskCountListener listener) { sTaskCountListeners.remove(listener); } + + /** + * Waits until all tasks are done and runs the runnable, or if there were no pending process remaining + * The runnable runs from the thread that updated the task count last, and it might be the UI thread, + * so dont put long running processes in it + * @param runnable the runnable to run when no tasks are remaining + */ + public static void waitUntilDone(final Runnable runnable) { + // If we do it the other way the listener would be removed before it was added, which will cause a listener object leak + if(getTaskCount() == 0) { + runnable.run(); + return; + } + TaskCountListener listener = new TaskCountListener() { + @Override + public void onUpdateTaskCount(int taskCount) { + if(taskCount == 0) { + runnable.run(); + } + removeTaskCountListener(this); + } + }; + addTaskCountListener(listener); + } + public static int getTaskCount() { return sProgressStates.size(); }