From 10802d5424227c639ec0d2f9e0daf2b3a0a60a25 Mon Sep 17 00:00:00 2001 From: Finn Rades <64548817+zOnlyKroks@users.noreply.github.com> Date: Tue, 11 Nov 2025 16:18:51 +0100 Subject: [PATCH] Tracy support for all run tasks (#1444) * Rework tracy support to work with all run tasks * Let user properly configure tracy --- .../fabricmc/loom/task/AbstractRunTask.java | 42 +++++++++++++++++++ .../fabricmc/loom/task/prod/TracyCapture.java | 2 +- 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/fabricmc/loom/task/AbstractRunTask.java b/src/main/java/net/fabricmc/loom/task/AbstractRunTask.java index c1483f5b..b13b1285 100644 --- a/src/main/java/net/fabricmc/loom/task/AbstractRunTask.java +++ b/src/main/java/net/fabricmc/loom/task/AbstractRunTask.java @@ -39,6 +39,7 @@ import java.util.stream.Collectors; import javax.inject.Inject; +import org.gradle.api.Action; import org.gradle.api.Project; import org.gradle.api.file.ConfigurableFileCollection; import org.gradle.api.file.FileCollection; @@ -50,12 +51,15 @@ import org.gradle.api.specs.Spec; import org.gradle.api.tasks.Input; import org.gradle.api.tasks.InputFiles; import org.gradle.api.tasks.JavaExec; +import org.gradle.api.tasks.Nested; +import org.gradle.api.tasks.Optional; import org.gradle.process.ExecOperations; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import net.fabricmc.loom.LoomGradleExtension; import net.fabricmc.loom.configuration.ide.RunConfig; +import net.fabricmc.loom.task.prod.TracyCapture; import net.fabricmc.loom.util.Constants; import net.fabricmc.loom.util.Platform; @@ -81,6 +85,22 @@ public abstract class AbstractRunTask extends JavaExec { @Input protected abstract Property getUseXvfb(); + @Nested + @Optional + public abstract Property getTracyCapture(); + + /** + * Configures the tracy profiler to run alongside the game. See @{@link TracyCapture} for more information. + * + * @param action The configuration action. + */ + @SuppressWarnings("unused") + public void tracy(Action action) { + getTracyCapture().set(getProject().getObjects().newInstance(TracyCapture.class)); + getTracyCapture().finalizeValue(); + action.execute(getTracyCapture().get()); + } + // We control the classpath, as we use a ArgFile to pass it over the command line: https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javac.html#commandlineargfile @InputFiles protected abstract ConfigurableFileCollection getInternalClasspath(); @@ -98,6 +118,13 @@ public abstract class AbstractRunTask extends JavaExec { ))); getArgumentProviders().add(() -> config.get().programArgs); + getArgumentProviders().add(() -> { + if (getTracyCapture().isPresent()) { + return List.of("--tracy"); + } + + return List.of(); + }); getMainClass().set(config.map(runConfig -> runConfig.mainClass)); getJvmArguments().addAll(getProject().provider(this::getGameJvmArgs)); @@ -151,6 +178,21 @@ public abstract class AbstractRunTask extends JavaExec { setWorkingDir(new File(getProjectDir().get(), getInternalRunDir().get())); environment(getInternalEnvironmentVars().get()); + // Wrap with Tracy if enabled + if (getTracyCapture().isPresent()) { + try { + getTracyCapture().get().runWithTracy(this::execInternal); + } catch (IOException e) { + throw new UncheckedIOException("Failed to run with Tracy", e); + } + + return; + } + + execInternal(); + } + + private void execInternal() { // Wrap with XVFB if enabled and on Linux if (getUseXvfb().get()) { LOGGER.info("Using XVFB for headless client execution"); diff --git a/src/main/java/net/fabricmc/loom/task/prod/TracyCapture.java b/src/main/java/net/fabricmc/loom/task/prod/TracyCapture.java index caff218e..a334e778 100644 --- a/src/main/java/net/fabricmc/loom/task/prod/TracyCapture.java +++ b/src/main/java/net/fabricmc/loom/task/prod/TracyCapture.java @@ -74,7 +74,7 @@ public abstract class TracyCapture { getMaxShutdownWaitSeconds().convention(10); } - void runWithTracy(IORunnable runnable) throws IOException { + public void runWithTracy(IORunnable runnable) throws IOException { TracyCaptureRunner tracyCaptureRunner = createRunner(); boolean success = false;