diff --git a/src/main/java/net/rptools/lib/CodeTimer.java b/src/main/java/net/rptools/lib/CodeTimer.java index f49eac0a04..00cfe35cd7 100644 --- a/src/main/java/net/rptools/lib/CodeTimer.java +++ b/src/main/java/net/rptools/lib/CodeTimer.java @@ -14,10 +14,51 @@ */ package net.rptools.lib; +import java.util.ArrayList; import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; +import net.rptools.maptool.client.AppState; +import net.rptools.maptool.client.MapTool; public class CodeTimer { + private static final ThreadLocal ROOT_TIMER = + ThreadLocal.withInitial(() -> new CodeTimer("")); + private static final ThreadLocal> timerStack = + ThreadLocal.withInitial(ArrayList::new); + + @FunctionalInterface + public interface TimedSection { + void call(CodeTimer timer) throws Ex; + } + + public static void using(String name, TimedSection callback) + throws Ex { + var stack = timerStack.get(); + + var timer = new CodeTimer(name); + timer.setEnabled(AppState.isCollectProfilingData()); + + stack.addLast(timer); + try { + callback.call(timer); + } finally { + final var lastTimer = stack.removeLast(); + assert lastTimer == timer : "Timer stack is corrupted"; + + if (timer.isEnabled()) { + String results = timer.toString(); + MapTool.getProfilingNoteFrame().addText(results); + } + timer.clear(); + } + } + + public static CodeTimer get() { + final var stack = timerStack.get(); + return stack.isEmpty() ? ROOT_TIMER.get() : stack.getLast(); + } + private final Map timeMap = new LinkedHashMap<>(); private final String name; private boolean enabled;