From 236cbf2dccdb575a6da5174ff9a30b40729c2357 Mon Sep 17 00:00:00 2001 From: Matt Date: Fri, 25 Oct 2024 14:33:38 -0400 Subject: [PATCH] Allow scheduling FX tasks before FX is initialized via FxThreadUtil --- .../coley/recaf/RecafApplication.java | 3 +++ .../coley/recaf/util/FxThreadUtil.java | 21 +++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/recaf-ui/src/main/java/software/coley/recaf/RecafApplication.java b/recaf-ui/src/main/java/software/coley/recaf/RecafApplication.java index 6db6ee748..0178a3d3c 100644 --- a/recaf-ui/src/main/java/software/coley/recaf/RecafApplication.java +++ b/recaf-ui/src/main/java/software/coley/recaf/RecafApplication.java @@ -45,6 +45,9 @@ public class RecafApplication extends Application implements WorkspaceOpenListen @Override public void start(Stage stage) { + // Notify the thread util that FX has been initialized + FxThreadUtil.onInitialize(); + // Setup global style setUserAgentStylesheet(new RecafTheme().getUserAgentStylesheet()); diff --git a/recaf-ui/src/main/java/software/coley/recaf/util/FxThreadUtil.java b/recaf-ui/src/main/java/software/coley/recaf/util/FxThreadUtil.java index 12d09218e..025a210f2 100644 --- a/recaf-ui/src/main/java/software/coley/recaf/util/FxThreadUtil.java +++ b/recaf-ui/src/main/java/software/coley/recaf/util/FxThreadUtil.java @@ -2,9 +2,12 @@ import jakarta.annotation.Nonnull; import javafx.application.Platform; +import software.coley.recaf.RecafApplication; import software.coley.recaf.util.threading.ThreadPoolFactory; import software.coley.recaf.util.threading.ThreadUtil; +import java.util.ArrayList; +import java.util.List; import java.util.concurrent.Executor; /** @@ -17,6 +20,8 @@ */ public class FxThreadUtil { private static final Executor jfxExecutor = FxThreadUtil::run; + private static final List preInitQueue = new ArrayList<>(); + private static boolean initialized; /** * Run action in JavaFX thread. @@ -28,6 +33,12 @@ public static void run(@Nonnull Runnable action) { // Skip under test environment. if (TestEnvironment.isTestEnv()) return; + // Hold for later if FX has not been initialized. + if (!initialized) { + preInitQueue.add(action); + return; + } + // Wrap action so that if it fails we don't explode and kill the FX thread. action = ThreadUtil.wrap(action); @@ -55,4 +66,14 @@ public static void delayedRun(long delayMs, @Nonnull Runnable action) { public static Executor executor() { return jfxExecutor; } + + /** + * Called by {@link RecafApplication} when it is first initialized. + */ + public static void onInitialize() { + initialized = true; + for (Runnable runnable : preInitQueue) + run(runnable); + preInitQueue.clear(); + } }