diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/helpers/HighlightedText.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/helpers/HighlightedText.java index 220cabde6..69657ecc1 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/helpers/HighlightedText.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/helpers/HighlightedText.java @@ -28,6 +28,8 @@ import java.util.List; */ public class HighlightedText implements Serializable { + public static HighlightedText EMPTY = new HighlightedText(); + public String text; private final List traitHighlights; @@ -69,7 +71,7 @@ public class HighlightedText implements Serializable { this.specialHighlights = writer.specialHilights; } - public HighlightedText() { + private HighlightedText() { this(""); } diff --git a/src/com/jpexs/decompiler/flash/gui/MainPanel.java b/src/com/jpexs/decompiler/flash/gui/MainPanel.java index cd8e36531..ae6dd9cf6 100644 --- a/src/com/jpexs/decompiler/flash/gui/MainPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/MainPanel.java @@ -196,7 +196,6 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Random; import java.util.Set; -import java.util.concurrent.CancellationException; import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Matcher; @@ -327,8 +326,6 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se private TreePanelMode treePanelMode; - private CancellableWorker setSourceWorker; - public TreeItem oldItem; // play morph shape in 2 second(s) @@ -3414,48 +3411,12 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se if (treeItem instanceof ScriptPack) { final ScriptPack scriptLeaf = (ScriptPack) treeItem; - if (setSourceWorker != null) { - setSourceWorker.cancel(true); - setSourceWorker = null; - } if (!Main.isInited() || !Main.isWorking() || Main.isDebugging()) { ABCPanel abcPanel = getABCPanel(); abcPanel.detailPanel.methodTraitPanel.methodCodePanel.clear(); abcPanel.setAbc(scriptLeaf.abc); - - CancellableWorker worker = new CancellableWorker() { - @Override - protected Void doInBackground() throws Exception { - abcPanel.decompiledTextArea.setScript(scriptLeaf, true); - abcPanel.decompiledTextArea.setNoTrait(); - return null; - } - - @Override - protected void onStart() { - Main.startWork(translate("work.decompiling") + "...", this); - } - - @Override - protected void done() { - View.execInEventDispatch(() -> { - setSourceWorker = null; - try { - get(); - } catch (CancellationException ex) { - abcPanel.decompiledTextArea.setText("// " + AppStrings.translate("work.canceled")); - } catch (Exception ex) { - logger.log(Level.SEVERE, "Error", ex); - getABCPanel().decompiledTextArea.setText("// " + AppStrings.translate("decompilationError") + ": " + ex); - } - - Main.stopWork(); - }); - } - }; - - worker.execute(); - setSourceWorker = worker; + abcPanel.decompiledTextArea.setScript(scriptLeaf, true); + abcPanel.decompiledTextArea.setNoTrait(); } showDetail(DETAILCARDAS3NAVIGATOR); diff --git a/src/com/jpexs/decompiler/flash/gui/abc/ASMSourceEditorPane.java b/src/com/jpexs/decompiler/flash/gui/abc/ASMSourceEditorPane.java index 760879a7d..1a21c08e4 100644 --- a/src/com/jpexs/decompiler/flash/gui/abc/ASMSourceEditorPane.java +++ b/src/com/jpexs/decompiler/flash/gui/abc/ASMSourceEditorPane.java @@ -76,7 +76,7 @@ public class ASMSourceEditorPane extends DebuggableEditorPane implements CaretLi return scriptIndex; } - private HighlightedText highlightedText = new HighlightedText(); + private HighlightedText highlightedText = HighlightedText.EMPTY; private final List docsListeners = new ArrayList<>(); diff --git a/src/com/jpexs/decompiler/flash/gui/abc/DecompiledEditorPane.java b/src/com/jpexs/decompiler/flash/gui/abc/DecompiledEditorPane.java index 48a56ca19..0b4f31ece 100644 --- a/src/com/jpexs/decompiler/flash/gui/abc/DecompiledEditorPane.java +++ b/src/com/jpexs/decompiler/flash/gui/abc/DecompiledEditorPane.java @@ -34,6 +34,7 @@ import com.jpexs.decompiler.flash.abc.types.traits.TraitFunction; import com.jpexs.decompiler.flash.abc.types.traits.TraitMethodGetterSetter; import com.jpexs.decompiler.flash.abc.types.traits.TraitSlotConst; import com.jpexs.decompiler.flash.gui.AppStrings; +import com.jpexs.decompiler.flash.gui.Main; import com.jpexs.decompiler.flash.gui.View; import com.jpexs.decompiler.flash.gui.editor.DebuggableEditorPane; import com.jpexs.decompiler.flash.helpers.GraphTextWriter; @@ -43,11 +44,15 @@ import com.jpexs.decompiler.flash.helpers.hilight.HighlightSpecialType; import com.jpexs.decompiler.flash.helpers.hilight.Highlighting; import com.jpexs.decompiler.flash.tags.ABCContainerTag; import com.jpexs.decompiler.graph.DottedChain; +import com.jpexs.helpers.CancellableWorker; import java.awt.Point; import java.util.ArrayList; import java.util.List; import java.util.Timer; import java.util.TimerTask; +import java.util.concurrent.CancellationException; +import java.util.logging.Level; +import java.util.logging.Logger; import javax.swing.event.CaretEvent; import javax.swing.event.CaretListener; import jsyntaxpane.SyntaxDocument; @@ -60,7 +65,9 @@ import jsyntaxpane.TokenType; */ public class DecompiledEditorPane extends DebuggableEditorPane implements CaretListener { - private HighlightedText highlightedText = new HighlightedText(); + private static final Logger logger = Logger.getLogger(DecompiledEditorPane.class.getName()); + + private HighlightedText highlightedText = HighlightedText.EMPTY; private Highlighting currentMethodHighlight; @@ -80,6 +87,8 @@ public class DecompiledEditorPane extends DebuggableEditorPane implements CaretL private boolean isStatic = false; + private CancellableWorker setSourceWorker; + private final List scriptListeners = new ArrayList<>(); public void addScriptListener(Runnable l) { @@ -649,6 +658,13 @@ public class DecompiledEditorPane extends DebuggableEditorPane implements CaretL } public void setScript(ScriptPack scriptLeaf, boolean force) { + View.checkAccess(); + + if (setSourceWorker != null) { + setSourceWorker.cancel(true); + setSourceWorker = null; + } + if (!force && this.script == scriptLeaf) { return; } @@ -661,23 +677,76 @@ public class DecompiledEditorPane extends DebuggableEditorPane implements CaretL if (scriptIndex > -1) { nscript = abc.script_info.get(scriptIndex); } + if (nscript == null) { - highlightedText = new HighlightedText(); - this.script = scriptLeaf; + highlightedText = HighlightedText.EMPTY; return; } - setText("// " + AppStrings.translate("pleasewait") + "..."); - this.script = scriptLeaf; - HighlightedText cd = null; - try { - cd = SWF.getCached(scriptLeaf); - } catch (InterruptedException ex) { + HighlightedText decompiledText = SWF.getFromCache(scriptLeaf); + + boolean decompileNeeded = decompiledText == null; + + if (decompileNeeded) { + CancellableWorker worker = new CancellableWorker() { + @Override + protected Void doInBackground() throws Exception { + + if (decompileNeeded) { + View.execInEventDispatch(() -> { + setText("// " + AppStrings.translate("work.decompiling") + "..."); + }); + + HighlightedText htext = SWF.getCached(scriptLeaf); + View.execInEventDispatch(() -> { + setSourceCompleted(scriptLeaf, htext); + }); + } + + return null; + } + + @Override + protected void done() { + View.execInEventDispatch(() -> { + setSourceWorker = null; + if (!Main.isDebugging()) { + Main.stopWork(); + } + + try { + get(); + } catch (CancellationException ex) { + setText("// " + AppStrings.translate("work.canceled")); + } catch (Exception ex) { + logger.log(Level.SEVERE, "Error", ex); + setText("// " + AppStrings.translate("decompilationError") + ": " + ex); + } + }); + } + }; + + worker.execute(); + setSourceWorker = worker; + if (!Main.isDebugging()) { + Main.startWork(AppStrings.translate("work.decompiling") + "...", worker); + } + } else { + setSourceCompleted(scriptLeaf, decompiledText); + } + } + + private void setSourceCompleted(ScriptPack scriptLeaf, HighlightedText decompiledText) { + View.checkAccess(); + + if (decompiledText == null) { + decompiledText = HighlightedText.EMPTY; } - if (cd != null) { - String hilightedCode = cd.text; - highlightedText = cd; + script = scriptLeaf; + highlightedText = decompiledText; + if (decompiledText != null) { + String hilightedCode = decompiledText.text; setText(hilightedCode); if (highlightedText.getClassHighlights().size() > 0) { @@ -688,15 +757,19 @@ public class DecompiledEditorPane extends DebuggableEditorPane implements CaretL } } } + fireScript(); } public void reloadClass() { + View.checkAccess(); + int ci = classIndex; SWF.uncache(script); if (script != null && getABC() != null) { setScript(script, true); } + setNoTrait(); setClassIndex(ci); } diff --git a/src/com/jpexs/decompiler/flash/gui/abc/DetailPanel.java b/src/com/jpexs/decompiler/flash/gui/abc/DetailPanel.java index e25f83b76..fb90237c8 100644 --- a/src/com/jpexs/decompiler/flash/gui/abc/DetailPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/abc/DetailPanel.java @@ -25,7 +25,6 @@ import com.jpexs.decompiler.flash.gui.Main; import com.jpexs.decompiler.flash.gui.TagEditorPanel; import com.jpexs.decompiler.flash.gui.View; import com.jpexs.decompiler.flash.helpers.GraphTextWriter; -import com.jpexs.helpers.CancellableWorker; import java.awt.BorderLayout; import java.awt.CardLayout; import java.awt.FlowLayout; @@ -130,7 +129,6 @@ public class DetailPanel extends JPanel implements TagEditorPanel { buttonsPanel.setVisible(false); conListener = new DebuggerHandler.ConnectionListener() { - @Override public void connected() { synchronized (DetailPanel.this) { @@ -305,23 +303,21 @@ public class DetailPanel extends JPanel implements TagEditorPanel { private void saveButtonActionPerformed(ActionEvent evt) { if (cardMap.get(selectedCard) instanceof TraitDetail) { if (((TraitDetail) cardMap.get(selectedCard)).save()) { - CancellableWorker worker = new CancellableWorker() { + DecompiledEditorPane decompiledTextArea = abcPanel.decompiledTextArea; + int lastTrait = decompiledTextArea.lastTraitIndex; + decompiledTextArea.reloadClass(); + Runnable reloadComplete = new Runnable() { @Override - public Void doInBackground() throws Exception { - int lasttrait = abcPanel.decompiledTextArea.lastTraitIndex; - abcPanel.decompiledTextArea.reloadClass(); - abcPanel.decompiledTextArea.gotoTrait(lasttrait); - return null; - } - - @Override - protected void done() { + public void run() { + decompiledTextArea.removeScriptListener(this); + decompiledTextArea.gotoTrait(lastTrait); setEditMode(false); View.showMessageDialog(null, AppStrings.translate("message.trait.saved"), AppStrings.translate("dialog.message.title"), JOptionPane.INFORMATION_MESSAGE, Configuration.showTraitSavedMessage); } }; - worker.execute(); + + decompiledTextArea.addScriptListener(reloadComplete); } } } diff --git a/src/com/jpexs/decompiler/flash/gui/abc/UsageFrame.java b/src/com/jpexs/decompiler/flash/gui/abc/UsageFrame.java index 5de5ca0c3..5f01771c8 100644 --- a/src/com/jpexs/decompiler/flash/gui/abc/UsageFrame.java +++ b/src/com/jpexs/decompiler/flash/gui/abc/UsageFrame.java @@ -103,11 +103,13 @@ public class UsageFrame extends AppDialog implements MouseListener { if (usage instanceof InsideClassMultinameUsageInterface) { final InsideClassMultinameUsageInterface icu = (InsideClassMultinameUsageInterface) usage; - Runnable settrait = new Runnable() { + DecompiledEditorPane decompiledTextArea = abcPanel.decompiledTextArea; + ABC abc = abcPanel.abc; + Runnable setTrait = new Runnable() { @Override public void run() { - abcPanel.decompiledTextArea.removeScriptListener(this); - abcPanel.decompiledTextArea.setClassIndex(icu.getClassIndex()); + decompiledTextArea.removeScriptListener(this); + decompiledTextArea.setClassIndex(icu.getClassIndex()); if (usage instanceof TraitMultinameUsage) { TraitMultinameUsage tmu = (TraitMultinameUsage) usage; int traitIndex; @@ -117,23 +119,23 @@ public class UsageFrame extends AppDialog implements MouseListener { traitIndex = tmu.getTraitIndex(); } if (tmu.getTraitsType() == TraitMultinameUsage.TRAITS_TYPE_INSTANCE) { - traitIndex += abcPanel.abc.class_info.get(tmu.getClassIndex()).static_traits.traits.size(); + traitIndex += abc.class_info.get(tmu.getClassIndex()).static_traits.traits.size(); } if (tmu instanceof MethodMultinameUsage) { MethodMultinameUsage mmu = (MethodMultinameUsage) usage; if (mmu.isInitializer() == true) { - traitIndex = abcPanel.abc.class_info.get(mmu.getClassIndex()).static_traits.traits.size() + abcPanel.abc.instance_info.get(mmu.getClassIndex()).instance_traits.traits.size() + (mmu.getTraitsType() == TraitMultinameUsage.TRAITS_TYPE_CLASS ? 1 : 0); + traitIndex = abc.class_info.get(mmu.getClassIndex()).static_traits.traits.size() + abc.instance_info.get(mmu.getClassIndex()).instance_traits.traits.size() + (mmu.getTraitsType() == TraitMultinameUsage.TRAITS_TYPE_CLASS ? 1 : 0); } } - abcPanel.decompiledTextArea.gotoTrait(traitIndex); + decompiledTextArea.gotoTrait(traitIndex); } } }; - if (abcPanel.decompiledTextArea.getClassIndex() == icu.getClassIndex() && abcPanel.abc == icu.getAbc()) { - settrait.run(); + if (decompiledTextArea.getClassIndex() == icu.getClassIndex() && abc == icu.getAbc()) { + setTrait.run(); } else { - abcPanel.decompiledTextArea.addScriptListener(settrait); + decompiledTextArea.addScriptListener(setTrait); abcPanel.hilightScript(abcPanel.getSwf(), icu.getAbc().instance_info.get(icu.getClassIndex()).getName(icu.getAbc().constants).getNameWithNamespace(icu.getAbc().constants, true).toRawString()); } } diff --git a/src/com/jpexs/decompiler/flash/gui/action/ActionPanel.java b/src/com/jpexs/decompiler/flash/gui/action/ActionPanel.java index 454005215..7bc064c9e 100644 --- a/src/com/jpexs/decompiler/flash/gui/action/ActionPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/action/ActionPanel.java @@ -156,9 +156,9 @@ public class ActionPanel extends JPanel implements SearchListener { - setEditorText(asm.getScriptName(), "; " + AppStrings.translate("work.disassembling") + "...", "text/flasm"); - if (decompileNeeded) { - setDecompiledText("-", "// " + AppStrings.translate("work.waitingfordissasembly") + "..."); - } - }); - - DisassemblyListener listener = getDisassemblyListener(); - asm.addDisassemblyListener(listener); - innerActions = asm.getActions(); - asm.removeDisassemblyListener(listener); - - lastCode = innerActions; - ActionList finalActions = innerActions; - View.execInEventDispatch(() -> { - setHex(getExportMode(), asm.getScriptName(), finalActions); - }); - } - - if (decompileNeeded) { - View.execInEventDispatch(() -> { - setDecompiledText("-", "// " + AppStrings.translate("work.decompiling") + "..."); - }); - - HighlightedText htext = SWF.getCached(asm, innerActions); - lastDecompiled = htext; - lastASM = asm; - - View.execInEventDispatch(() -> { - setDecompiledText(lastASM.getScriptName(), htext.text); - }); - } - - return null; - } - - @Override - protected void done() { - View.execInEventDispatch(() -> { - setSourceWorker = null; - if (!Main.isDebugging()) { - Main.stopWork(); - } - - try { - get(); - } catch (CancellationException ex) { - setEditorText("-", "; " + AppStrings.translate("work.canceled"), "text/flasm"); - } catch (Exception ex) { - setDecompiledText("-", "// " + AppStrings.translate("decompilationError") + ": " + ex); - } + if (disassemblingNeeded || decompileNeeded) { + CancellableWorker worker = new CancellableWorker() { + @Override + protected Void doInBackground() throws Exception { + ActionList innerActions = actions; if (disassemblingNeeded) { - setEditMode(false); + View.execInEventDispatch(() -> { + setEditorText(asm.getScriptName(), "; " + AppStrings.translate("work.disassembling") + "...", "text/flasm"); + if (decompileNeeded) { + setDecompiledText("-", "// " + AppStrings.translate("work.waitingfordissasembly") + "..."); + } + }); + + DisassemblyListener listener = getDisassemblyListener(); + asm.addDisassemblyListener(listener); + innerActions = asm.getActions(); + asm.removeDisassemblyListener(listener); } if (decompileNeeded) { - setDecompiledEditMode(false); + View.execInEventDispatch(() -> { + setDecompiledText("-", "// " + AppStrings.translate("work.decompiling") + "..."); + }); + + HighlightedText htext = SWF.getCached(asm, innerActions); + setSourceCompleted(asm, htext, innerActions); } - }); + + return null; + } + + @Override + protected void done() { + View.execInEventDispatch(() -> { + setSourceWorker = null; + if (!Main.isDebugging()) { + Main.stopWork(); + } + + try { + get(); + } catch (CancellationException ex) { + setEditorText("-", "; " + AppStrings.translate("work.canceled"), "text/flasm"); + } catch (Exception ex) { + logger.log(Level.SEVERE, "Error", ex); + setDecompiledText("-", "// " + AppStrings.translate("decompilationError") + ": " + ex); + } + }); + } + }; + + worker.execute(); + setSourceWorker = worker; + if (!Main.isDebugging()) { + Main.startWork(AppStrings.translate("work.decompiling") + "...", worker); } - }; - worker.execute(); - setSourceWorker = worker; - if (!Main.isDebugging()) { - Main.startWork(AppStrings.translate("work.decompiling") + "...", worker); + } else { + setSourceCompleted(asm, decompiledText, actions); } } + private void setSourceCompleted(ASMSource asm, HighlightedText decompiledText, ActionList actions) { + View.checkAccess(); + + if (decompiledText == null) { + decompiledText = HighlightedText.EMPTY; + } + + lastASM = asm; + lastCode = actions; + lastDecompiled = decompiledText; + + setHex(getExportMode(), asm.getScriptName(), actions); + setDecompiledText(asm.getScriptName(), decompiledText.text); + } + public void hilightOffset(long offset) { View.checkAccess(); }