simplify TagTree nodes 11

This commit is contained in:
2014-10-05 16:29:48 +02:00
parent 4fa91fab3e
commit 7f789aafbc
11 changed files with 148 additions and 206 deletions
@@ -938,12 +938,11 @@ public final class SWF implements TreeItem, Timelined {
list2.addAll(tags);
List<TreeNode> list = createASTagList(list2, this);
TagNode.setExport(list, true);
if (!outdir.endsWith(File.separator)) {
outdir += File.separator;
}
outdir += "scripts" + File.separator;
ret.addAll(TagNode.exportNodeAS(handler, list, outdir, exportMode, evl));
ret.addAll(TagNode.exportNodeAS(handler, list, list, outdir, exportMode, evl));
return ret;
}
@@ -1036,38 +1035,31 @@ public final class SWF implements TreeItem, Timelined {
public static List<TreeNode> createASTagList(List<? extends ContainerItem> list, Timelined parent) {
List<TreeNode> ret = new ArrayList<>();
int frame = 1;
int frame = 0;
List<TreeNode> frames = new ArrayList<>();
List<ExportAssetsTag> exportAssetsTags = new ArrayList<>();
for (ContainerItem t : list) {
if (t instanceof ExportAssetsTag) {
exportAssetsTags.add((ExportAssetsTag) t);
}
TreeNode addNode = null;
if (t instanceof ShowFrameTag) {
// do not add PlaceObjects (+etc) to script nodes
FrameNode tti = new FrameNode(new FrameNodeItem(t.getSwf(), frame, parent, false), null, true);
for (int r = ret.size() - 1; r >= 0; r--) {
if (!(ret.get(r).getItem() instanceof DefineSpriteTag)) {
if (!(ret.get(r).getItem() instanceof DefineButtonTag)) {
if (!(ret.get(r).getItem() instanceof DefineButton2Tag)) {
if (!(ret.get(r).getItem() instanceof DoInitActionTag)) {
if (!(ret.get(r).getItem() instanceof AS2PackageNodeItem)) {
tti.subNodes.add(ret.get(r));
ret.remove(r);
}
}
}
}
TreeNode node = ret.get(r);
TreeItem item = node.getItem();
if (!(item instanceof DefineSpriteTag
|| item instanceof DefineButtonTag
|| item instanceof DefineButton2Tag
|| item instanceof DoInitActionTag
|| item instanceof AS2PackageNodeItem)) {
tti.subNodes.add(node);
ret.remove(r);
}
}
frame++;
frames.add(tti);
} else if (t instanceof ASMSource) {
ContainerNode tti = new ContainerNode(t);
//ret.add(tti);
addNode = tti;
} else if (t instanceof Container) {
if (((Container) t).getItemCount() > 0) {
@@ -1078,7 +1070,6 @@ public final class SWF implements TreeItem, Timelined {
Timelined timelined = t instanceof Timelined ? (Timelined) t : null;
tti.subNodes = createASTagList(subItems, timelined);
addNode = tti;
//ret.add(tti);
}
}
if (addNode != null) {
@@ -1088,24 +1079,15 @@ public final class SWF implements TreeItem, Timelined {
if (path == null) {
path = "";
}
String[] pathParts;
if (path.contains(".")) {
pathParts = path.split("\\.");
} else {
pathParts = new String[]{path};
}
String[] pathParts = path.contains(".") ? path.split("\\.") : new String[]{ path };
List<TreeNode> items = ret;
int pos = 0;
TreeNode selNode = null;
do {
if (pos == pathParts.length - 1) {
break;
}
selNode = null;
for (int pos = 0; pos < pathParts.length - 1; pos++) {
String pathPart = pathParts[pos];
TreeNode selNode = null;
for (TreeNode node : items) {
if (node.getItem() instanceof AS2PackageNodeItem) {
AS2PackageNodeItem pkg = (AS2PackageNodeItem) node.getItem();
if (pkg.packageName.equals(pathParts[pos])) {
if (pkg.packageName.equals(pathPart)) {
selNode = node;
break;
}
@@ -1114,8 +1096,8 @@ public final class SWF implements TreeItem, Timelined {
int pkgCount = 0;
for (; pkgCount < items.size(); pkgCount++) {
if (items.get(pkgCount).getItem() instanceof AS3PackageNodeItem) {
AS2PackageNodeItem pkg = (AS2PackageNodeItem) items.get(pkgCount).getItem();
if (pkg.packageName.compareTo(pathParts[pos]) > 0) {
AS3PackageNodeItem pkg = (AS3PackageNodeItem) items.get(pkgCount).getItem();
if (pkg.packageName.compareTo(pathPart) > 0) {
break;
}
} else {
@@ -1123,16 +1105,14 @@ public final class SWF implements TreeItem, Timelined {
}
}
if (selNode == null) {
items.add(pkgCount, selNode = new AS2PackageNode(new AS2PackageNodeItem(pathParts[pos], t.getSwf())));
items.add(pkgCount, selNode = new AS2PackageNode(new AS2PackageNodeItem(pathPart, t.getSwf())));
}
pos++;
if (selNode != null) {
items = selNode.subNodes;
}
} while (selNode != null);
items = selNode.subNodes;
}
int clsCount = 0;
String addNodeName = addNode.getItem().getClass().getName() + "_" + pathParts[pathParts.length - 1];
for (; clsCount < items.size(); clsCount++) {
if (items.get(clsCount).getItem() instanceof CharacterIdTag) {
CharacterIdTag ct = (CharacterIdTag) items.get(clsCount).getItem();
@@ -1143,7 +1123,7 @@ public final class SWF implements TreeItem, Timelined {
if (expName.contains(".")) {
expName = expName.substring(expName.lastIndexOf('.') + 1);
}
if ((ct.getClass().getName() + "_" + expName).compareTo(addNode.getItem().getClass().getName() + "_" + pathParts[pos]) > 0) {
if ((ct.getClass().getName() + "_" + expName).compareTo(addNodeName) > 0) {
break;
}
}
@@ -1157,25 +1137,15 @@ public final class SWF implements TreeItem, Timelined {
}
ret.addAll(frames);
for (int i = ret.size() - 1; i >= 0; i--) {
if (ret.get(i).getItem() instanceof DefineSpriteTag) {
((DefineSpriteTag) ret.get(i).getItem()).exportAssetsTags = exportAssetsTags;
}
if (ret.get(i).getItem() instanceof DefineButtonTag) {
((DefineButtonTag) ret.get(i).getItem()).exportAssetsTags = exportAssetsTags;
}
if (ret.get(i).getItem() instanceof DefineButton2Tag) {
((DefineButton2Tag) ret.get(i).getItem()).exportAssetsTags = exportAssetsTags;
}
/*if (ret.get(i).tag instanceof DoInitActionTag) {
//((DoInitActionTag) ret.get(i).tag).exportAssetsTags = exportAssetsTags;
}*/
if (ret.get(i).getItem() instanceof ASMSource) {
ASMSource ass = (ASMSource) ret.get(i).getItem();
TreeNode node = ret.get(i);
TreeItem item = node.getItem();
if (item instanceof ASMSource) {
ASMSource ass = (ASMSource) item;
if (ass.containsSource()) {
continue;
}
}
if (ret.get(i).subNodes.isEmpty()) {
if (node.subNodes.isEmpty()) {
ret.remove(i);
}
}
@@ -205,6 +205,7 @@ public class DoInitActionTag extends CharacterIdTag implements ASMSource {
return pathParts[pathParts.length - 1];
}
@Override
public GraphTextWriter getActionSourcePrefix(GraphTextWriter writer) {
return writer;
@@ -12,16 +12,13 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.␍ */
* License along with this library.
*/
package com.jpexs.decompiler.flash.tags.base;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.tags.ExportAssetsTag;
import com.jpexs.decompiler.flash.tags.Tag;
import com.jpexs.decompiler.flash.types.annotations.Internal;
import com.jpexs.helpers.ByteArrayRange;
import java.util.ArrayList;
import java.util.List;
/**
*
@@ -34,11 +31,7 @@ public abstract class CharacterIdTag extends Tag {
}
public abstract int getCharacterId();
/**
* List of ExportAssetsTag used for converting to String
*/
@Internal
public List<ExportAssetsTag> exportAssetsTags = new ArrayList<>();
protected String exportName;
public void setExportName(String exportName) {
@@ -12,7 +12,8 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.␍ */
* License along with this library.
*/
package com.jpexs.decompiler.flash.treeitems;
import com.jpexs.decompiler.flash.SWF;
@@ -48,7 +49,7 @@ public class FrameNodeItem implements TreeItem {
@Override
public String toString() {
return "frame " + frame;
return "frame " + (frame + 1);
}
public int getFrame() {
@@ -12,7 +12,8 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.␍ */
* License along with this library.
*/
package com.jpexs.decompiler.flash.treenodes;
import com.jpexs.decompiler.flash.AbortRetryIgnoreHandler;
@@ -51,39 +52,30 @@ public class TagNode extends ContainerNode {
return (Tag) item;
}
public static void setExport(List<TreeNode> nodeList, boolean export) {
for (TreeNode node : nodeList) {
node.export = export;
setExport(node.subNodes, export);
}
}
public static int getTagCountRecursive(List<TreeNode> nodeList) {
int count = 0;
for (TreeNode node : nodeList) {
if (node.subNodes.isEmpty()) {
if ((node.item instanceof ASMSource) && (node.export)) {
count += 1;
}
} else {
if (node.item instanceof ASMSource) {
count += 1;
}
if (!node.subNodes.isEmpty()) {
count += getTagCountRecursive(node.subNodes);
}
}
return count;
}
public static List<File> exportNodeAS(final AbortRetryIgnoreHandler handler, final List<TreeNode> nodeList, final String outdir, final ScriptExportMode exportMode, final EventListener ev) throws IOException {
public static List<File> exportNodeAS(final AbortRetryIgnoreHandler handler, final List<TreeNode> nodesList, final List<TreeNode> nodesToExport, final String outdir, final ScriptExportMode exportMode, final EventListener ev) throws IOException {
try {
List<File> result = CancellableWorker.call(new Callable<List<File>>() {
@Override
public List<File> call() throws Exception {
AtomicInteger cnt = new AtomicInteger(1);
int totalCount = TagNode.getTagCountRecursive(nodeList);
return exportNodeAS(handler, nodeList, outdir, exportMode, cnt, totalCount, ev);
int totalCount = TagNode.getTagCountRecursive(nodesToExport);
return exportNodeAS(handler, nodesList, nodesToExport, false, outdir, exportMode, cnt, totalCount, ev);
}
}, Configuration.exportTimeout.get(), TimeUnit.SECONDS);
return result;
@@ -92,14 +84,14 @@ public class TagNode extends ContainerNode {
return new ArrayList<>();
}
private static List<File> exportNodeAS(AbortRetryIgnoreHandler handler, List<TreeNode> nodeList, String outdir, ScriptExportMode exportMode, AtomicInteger index, int count, EventListener ev) throws IOException {
private static List<File> exportNodeAS(AbortRetryIgnoreHandler handler, List<TreeNode> nodesList, List<TreeNode> nodesToExport, boolean exportAll, String outdir, ScriptExportMode exportMode, AtomicInteger index, int count, EventListener ev) throws IOException {
File dir = new File(outdir);
List<File> ret = new ArrayList<>();
if (!outdir.endsWith(File.separator)) {
outdir += File.separator;
}
List<String> existingNames = new ArrayList<>();
for (TreeNode node : nodeList) {
for (TreeNode node : nodesList) {
String name = "";
if (node.item instanceof Exportable) {
name = Helper.makeFileName(((Exportable) node.item).getExportFileName());
@@ -113,76 +105,76 @@ public class TagNode extends ContainerNode {
name = baseName + "_" + i;
}
existingNames.add(name);
if (node.subNodes.isEmpty()) {
if ((node.item instanceof ASMSource) && (node.export)) {
boolean retry;
do {
retry = false;
try {
int currentIndex = index.getAndIncrement();
boolean exportNode = nodesToExport.contains(node);
if (node.item instanceof ASMSource && (exportAll || exportNode)) {
boolean retry;
do {
retry = false;
try {
int currentIndex = index.getAndIncrement();
if (!dir.exists()) {
if (!dir.mkdirs()) {
if (!dir.exists()) {
throw new IOException("Cannot create directory " + outdir);
}
}
}
String f = outdir + name + ".as";
if (ev != null) {
ev.handleEvent("exporting", "Exporting " + currentIndex + "/" + count + " " + f);
}
long startTime = System.currentTimeMillis();
File file = new File(f);
ASMSource asm = ((ASMSource) node.item);
try (FileTextWriter writer = new FileTextWriter(Configuration.getCodeFormatting(), new FileOutputStream(f))) {
if (exportMode == ScriptExportMode.HEX) {
asm.getActionSourcePrefix(writer);
asm.getActionBytesAsHex(writer);
asm.getActionSourceSuffix(writer);
} else if (exportMode != ScriptExportMode.AS) {
asm.getActionSourcePrefix(writer);
asm.getASMSource(exportMode, writer, null);
asm.getActionSourceSuffix(writer);
} else {
List<Action> as = asm.getActions();
Action.setActionsAddresses(as, 0);
Action.actionsToSource(asm, as, ""/*FIXME*/, writer);
}
}
long stopTime = System.currentTimeMillis();
if (ev != null) {
long time = stopTime - startTime;
ev.handleEvent("exported", "Exported " + currentIndex + "/" + count + " " + f + ", " + Helper.formatTimeSec(time));
}
ret.add(file);
} catch (InterruptedException ex) {
} catch (IOException | OutOfMemoryError | TranslateException | StackOverflowError ex) {
Logger.getLogger(TagNode.class.getName()).log(Level.SEVERE, "Decompilation error in file: " + name + ".as", ex);
if (handler != null) {
int action = handler.getNewInstance().handle(ex);
switch (action) {
case AbortRetryIgnoreHandler.ABORT:
throw ex;
case AbortRetryIgnoreHandler.RETRY:
retry = true;
break;
case AbortRetryIgnoreHandler.IGNORE:
retry = false;
break;
if (!dir.exists()) {
if (!dir.mkdirs()) {
if (!dir.exists()) {
throw new IOException("Cannot create directory " + outdir);
}
}
}
} while (retry);
}
} else {
ret.addAll(exportNodeAS(handler, node.subNodes, outdir + name, exportMode, index, count, ev));
String f = outdir + name + ".as";
if (ev != null) {
ev.handleEvent("exporting", "Exporting " + currentIndex + "/" + count + " " + f);
}
long startTime = System.currentTimeMillis();
File file = new File(f);
ASMSource asm = ((ASMSource) node.item);
try (FileTextWriter writer = new FileTextWriter(Configuration.getCodeFormatting(), new FileOutputStream(f))) {
if (exportMode == ScriptExportMode.HEX) {
asm.getActionSourcePrefix(writer);
asm.getActionBytesAsHex(writer);
asm.getActionSourceSuffix(writer);
} else if (exportMode != ScriptExportMode.AS) {
asm.getActionSourcePrefix(writer);
asm.getASMSource(exportMode, writer, null);
asm.getActionSourceSuffix(writer);
} else {
List<Action> as = asm.getActions();
Action.setActionsAddresses(as, 0);
Action.actionsToSource(asm, as, ""/*FIXME*/, writer);
}
}
long stopTime = System.currentTimeMillis();
if (ev != null) {
long time = stopTime - startTime;
ev.handleEvent("exported", "Exported " + currentIndex + "/" + count + " " + f + ", " + Helper.formatTimeSec(time));
}
ret.add(file);
} catch (InterruptedException ex) {
} catch (IOException | OutOfMemoryError | TranslateException | StackOverflowError ex) {
Logger.getLogger(TagNode.class.getName()).log(Level.SEVERE, "Decompilation error in file: " + name + ".as", ex);
if (handler != null) {
int action = handler.getNewInstance().handle(ex);
switch (action) {
case AbortRetryIgnoreHandler.ABORT:
throw ex;
case AbortRetryIgnoreHandler.RETRY:
retry = true;
break;
case AbortRetryIgnoreHandler.IGNORE:
retry = false;
break;
}
}
}
} while (retry);
}
if (!node.subNodes.isEmpty()) {
ret.addAll(exportNodeAS(handler, node.subNodes, nodesToExport, exportAll || exportNode, outdir + name, exportMode, index, count, ev));
}
}
@@ -12,7 +12,8 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.␍ */
* License along with this library.
*/
package com.jpexs.decompiler.flash.treenodes;
import com.jpexs.decompiler.flash.treeitems.TreeItem;
@@ -28,7 +29,6 @@ import java.util.logging.Logger;
public abstract class TreeNode {
protected TreeItem item;
public boolean export = false;
public List<TreeNode> subNodes;
public TreeNode(TreeItem item) {
@@ -51,13 +51,4 @@ public abstract class TreeNode {
}
return item.toString();
}
public List<TreeNode> getAllSubs() {
List<TreeNode> ret = new ArrayList<>();
ret.addAll(subNodes);
for (TreeNode n : subNodes) {
ret.addAll(n.getAllSubs());
}
return ret;
}
}