From 53531e7deab04eda53e2a37dd13bb98a899cffba Mon Sep 17 00:00:00 2001 From: Player Date: Wed, 6 Nov 2024 18:56:58 -0500 Subject: [PATCH] Cancel pending src update tasks when they become outdated --- .../java/matcher/gui/tab/SourcecodeTab.java | 91 +++++++++++-------- 1 file changed, 55 insertions(+), 36 deletions(-) diff --git a/src/main/java/matcher/gui/tab/SourcecodeTab.java b/src/main/java/matcher/gui/tab/SourcecodeTab.java index 1c782df3..63bb32c2 100644 --- a/src/main/java/matcher/gui/tab/SourcecodeTab.java +++ b/src/main/java/matcher/gui/tab/SourcecodeTab.java @@ -3,10 +3,12 @@ import java.io.PrintWriter; import java.io.StringWriter; import java.util.Set; +import java.util.concurrent.Future; import matcher.NameType; import matcher.gui.Gui; import matcher.gui.ISelectionProvider; +import matcher.srcprocess.Decompiler; import matcher.srcprocess.HtmlUtil; import matcher.srcprocess.SrcDecorator; import matcher.srcprocess.SrcDecorator.SrcParseException; @@ -32,7 +34,7 @@ public void onSelectStateChange(boolean tabSelected) { this.tabSelected = tabSelected; if (!tabSelected) return; - if (updateNeeded > 0) update(); + if (updateNeeded != UPDATE_NONE) update(); if (selectedMember instanceof MethodInstance) { onMethodSelect((MethodInstance) selectedMember); @@ -44,14 +46,14 @@ public void onSelectStateChange(boolean tabSelected) { @Override public void onClassSelect(ClassInstance cls) { selectedClass = cls; - if (updateNeeded == 0) updateNeeded = 1; + if (updateNeeded == UPDATE_NONE) updateNeeded = UPDATE_RESET; if (tabSelected) update(); } @Override public void onMatchChange(Set types) { selectedClass = selectionProvider.getSelectedClass(); - updateNeeded = 2; + updateNeeded = UPDATE_REFRESH; if (tabSelected && selectedClass != null) { update(); @@ -67,8 +69,8 @@ public void onViewChange(ViewChangeCause cause) { update(); } else if (selectedClass != null && (cause == ViewChangeCause.NAME_TYPE_CHANGED - || cause == ViewChangeCause.DECOMPILER_CHANGED)) { - updateNeeded = 2; + || cause == ViewChangeCause.DECOMPILER_CHANGED)) { + updateNeeded = UPDATE_REFRESH; if (tabSelected) update(); } } @@ -78,6 +80,11 @@ private void update() { final int cDecompId = ++decompId; + if (pendingUpdateTask != null) { + pendingUpdateTask.cancel(true); + pendingUpdateTask = null; + } + if (selectedClass == null) { displayText("no class selected"); return; @@ -86,38 +93,45 @@ private void update() { displayText("decompiling..."); NameType nameType = gui.getNameType().withUnmatchedTmp(unmatchedTmp); + Decompiler decompiler = gui.getDecompiler().get(); //Gui.runAsyncTask(() -> gui.getEnv().decompile(selectedClass, true)) - Gui.runAsyncTask(() -> SrcDecorator.decorate(gui.getEnv().decompile(gui.getDecompiler().get(), selectedClass, nameType), selectedClass, nameType)) - .whenComplete((res, exc) -> { - if (cDecompId == decompId) { - if (exc != null) { - exc.printStackTrace(); - - StringWriter sw = new StringWriter(); - exc.printStackTrace(new PrintWriter(sw)); - - if (exc instanceof SrcParseException) { - SrcParseException parseExc = (SrcParseException) exc; - displayText("parse error: "+parseExc.problems+"\ndecompiled source:\n"+parseExc.source); - } else { - displayText("decompile error: "+sw.toString()); - } - } else { - double prevScroll = updateNeeded == 2 ? getScrollTop() : 0; - - displayHtml(res); - - if (updateNeeded == 2 && prevScroll > 0) { - setScrollTop(prevScroll); - } - } - } else if (exc != null) { - exc.printStackTrace(); - } - - updateNeeded = 0; - }); + pendingUpdateTask = Gui.runAsyncTask(() -> SrcDecorator.decorate(gui.getEnv().decompile(decompiler, selectedClass, nameType), selectedClass, nameType)) + .whenComplete((res, exc) -> applyDecompilerResult(res, exc, cDecompId)); + } + + private void applyDecompilerResult(String res, Throwable exc, int cDecompId) { + if (cDecompId != decompId) { + if (exc != null) { + exc.printStackTrace(); + } + + return; + } + + if (exc != null) { + exc.printStackTrace(); + + StringWriter sw = new StringWriter(); + exc.printStackTrace(new PrintWriter(sw)); + + if (exc instanceof SrcParseException) { + SrcParseException parseExc = (SrcParseException) exc; + displayText("parse error: "+parseExc.problems+"\ndecompiled source:\n"+parseExc.source); + } else { + displayText("decompile error: "+sw.toString()); + } + } else { + double prevScroll = updateNeeded == UPDATE_REFRESH ? getScrollTop() : 0; + + displayHtml(res); + + if (updateNeeded == UPDATE_REFRESH && prevScroll > 0) { + setScrollTop(prevScroll); + } + } + + updateNeeded = UPDATE_NONE; } @Override @@ -138,13 +152,18 @@ public void onFieldSelect(FieldInstance field) { } } + private static final int UPDATE_NONE = 0; + private static final int UPDATE_RESET = 1; + private static final int UPDATE_REFRESH = 2; // tries to keep scroll position + private final Gui gui; private final ISelectionProvider selectionProvider; private final boolean unmatchedTmp; private int decompId; - private int updateNeeded; + private int updateNeeded = UPDATE_NONE; private boolean tabSelected; private ClassInstance selectedClass; private MemberInstance selectedMember; + private Future pendingUpdateTask; }