performance improvement

This commit is contained in:
Perfare 2020-03-28 04:24:32 +08:00
parent a0bf4f9acd
commit 06fbe69a97
3 changed files with 98 additions and 115 deletions

View File

@ -83,8 +83,8 @@
this.listSearch = new System.Windows.Forms.TextBox(); this.listSearch = new System.Windows.Forms.TextBox();
this.tabPage3 = new System.Windows.Forms.TabPage(); this.tabPage3 = new System.Windows.Forms.TabPage();
this.classesListView = new System.Windows.Forms.ListView(); this.classesListView = new System.Windows.Forms.ListView();
this.columnHeader2 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.columnHeader1 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.columnHeader1 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.columnHeader2 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.progressbarPanel = new System.Windows.Forms.Panel(); this.progressbarPanel = new System.Windows.Forms.Panel();
this.progressBar1 = new System.Windows.Forms.ProgressBar(); this.progressBar1 = new System.Windows.Forms.ProgressBar();
this.previewPanel = new System.Windows.Forms.Panel(); this.previewPanel = new System.Windows.Forms.Panel();
@ -622,16 +622,16 @@
this.classesListView.View = System.Windows.Forms.View.Details; this.classesListView.View = System.Windows.Forms.View.Details;
this.classesListView.ItemSelectionChanged += new System.Windows.Forms.ListViewItemSelectionChangedEventHandler(this.classesListView_ItemSelectionChanged); this.classesListView.ItemSelectionChanged += new System.Windows.Forms.ListViewItemSelectionChangedEventHandler(this.classesListView_ItemSelectionChanged);
// //
// columnHeader2
//
this.columnHeader2.Text = "Name";
this.columnHeader2.Width = 300;
//
// columnHeader1 // columnHeader1
// //
this.columnHeader1.Text = "ID"; this.columnHeader1.Text = "ID";
this.columnHeader1.Width = 70; this.columnHeader1.Width = 70;
// //
// columnHeader2
//
this.columnHeader2.Text = "Name";
this.columnHeader2.Width = 300;
//
// progressbarPanel // progressbarPanel
// //
this.progressbarPanel.Controls.Add(this.progressBar1); this.progressbarPanel.Controls.Add(this.progressBar1);

View File

@ -13,6 +13,7 @@ using System.Linq;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
using System.Threading.Tasks;
using System.Timers; using System.Timers;
using System.Windows.Forms; using System.Windows.Forms;
using static AssetStudioGUI.Studio; using static AssetStudioGUI.Studio;
@ -82,47 +83,49 @@ namespace AssetStudioGUI
[DllImport("gdi32.dll")] [DllImport("gdi32.dll")]
private static extern IntPtr AddFontMemResourceEx(IntPtr pbFont, uint cbFont, IntPtr pdv, [In] ref uint pcFonts); private static extern IntPtr AddFontMemResourceEx(IntPtr pbFont, uint cbFont, IntPtr pdv, [In] ref uint pcFonts);
public AssetStudioGUIForm()
{
Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
InitializeComponent();
Text = $"AssetStudioGUI v{Application.ProductVersion}";
delayTimer = new System.Timers.Timer(800);
delayTimer.Elapsed += new ElapsedEventHandler(delayTimer_Elapsed);
displayAll.Checked = Properties.Settings.Default.displayAll;
displayInfo.Checked = Properties.Settings.Default.displayInfo;
enablePreview.Checked = Properties.Settings.Default.enablePreview;
FMODinit();
private void loadFile_Click(object sender, EventArgs e) Logger.Default = new GUILogger(StatusStripUpdate);
Progress.Default = new GUIProgress(SetProgressBarValue);
Studio.StatusStripUpdate = StatusStripUpdate;
}
private async void loadFile_Click(object sender, EventArgs e)
{ {
if (openFileDialog1.ShowDialog() == DialogResult.OK) if (openFileDialog1.ShowDialog() == DialogResult.OK)
{ {
ResetForm(); ResetForm();
ThreadPool.QueueUserWorkItem(state => await Task.Run(() => assetsManager.LoadFiles(openFileDialog1.FileNames));
{ BuildAssetStructures();
assetsManager.LoadFiles(openFileDialog1.FileNames);
BuildAssetStructures();
});
} }
} }
private void loadFolder_Click(object sender, EventArgs e) private async void loadFolder_Click(object sender, EventArgs e)
{ {
var openFolderDialog = new OpenFolderDialog(); var openFolderDialog = new OpenFolderDialog();
if (openFolderDialog.ShowDialog(this) == DialogResult.OK) if (openFolderDialog.ShowDialog(this) == DialogResult.OK)
{ {
ResetForm(); ResetForm();
ThreadPool.QueueUserWorkItem(state => await Task.Run(() => assetsManager.LoadFolder(openFolderDialog.Folder));
{ BuildAssetStructures();
assetsManager.LoadFolder(openFolderDialog.Folder);
BuildAssetStructures();
});
} }
} }
private void extractFileToolStripMenuItem_Click(object sender, EventArgs e) private void extractFileToolStripMenuItem_Click(object sender, EventArgs e)
{ {
var openBundleDialog = new OpenFileDialog if (openFileDialog1.ShowDialog() == DialogResult.OK)
{ {
Filter = "All types|*.*", ExtractFile(openFileDialog1.FileNames);
FilterIndex = 1,
RestoreDirectory = true,
Multiselect = true
};
if (openBundleDialog.ShowDialog() == DialogResult.OK)
{
ExtractFile(openBundleDialog.FileNames);
} }
} }
@ -136,7 +139,7 @@ namespace AssetStudioGUI
} }
} }
private void BuildAssetStructures() private async void BuildAssetStructures()
{ {
if (assetsManager.assetsFileList.Count == 0) if (assetsManager.assetsFileList.Count == 0)
{ {
@ -144,72 +147,66 @@ namespace AssetStudioGUI
return; return;
} }
var data = BuildAssetData(); (var productName, var treeNodeCollection) = await Task.Run(() => BuildAssetData());
var productName = data.Item1; var typeMap = await Task.Run(() => BuildClassStructure());
var treeNodeCollection = data.Item2;
var typeMap = BuildClassStructure();
BeginInvoke(new Action(() => if (!string.IsNullOrEmpty(productName))
{ {
if (!string.IsNullOrEmpty(productName)) Text = $"AssetStudioGUI v{Application.ProductVersion} - {productName} - {assetsManager.assetsFileList[0].unityVersion} - {assetsManager.assetsFileList[0].m_TargetPlatform}";
{ }
Text = $"AssetStudioGUI - {productName} - {assetsManager.assetsFileList[0].unityVersion} - {assetsManager.assetsFileList[0].m_TargetPlatform}"; else
} {
else Text = $"AssetStudioGUI v{Application.ProductVersion} - no productName - {assetsManager.assetsFileList[0].unityVersion} - {assetsManager.assetsFileList[0].m_TargetPlatform}";
{ }
Text = $"AssetStudioGUI - no productName - {assetsManager.assetsFileList[0].unityVersion} - {assetsManager.assetsFileList[0].m_TargetPlatform}";
}
assetListView.VirtualListSize = visibleAssets.Count; assetListView.VirtualListSize = visibleAssets.Count;
sceneTreeView.BeginUpdate(); sceneTreeView.BeginUpdate();
sceneTreeView.Nodes.AddRange(treeNodeCollection.ToArray()); sceneTreeView.Nodes.AddRange(treeNodeCollection.ToArray());
foreach (TreeNode node in sceneTreeView.Nodes) foreach (var node in treeNodeCollection)
{ {
node.HideCheckBox(); node.HideCheckBox();
} }
sceneTreeView.EndUpdate(); sceneTreeView.EndUpdate();
treeNodeCollection.Clear(); treeNodeCollection.Clear();
classesListView.BeginUpdate(); classesListView.BeginUpdate();
foreach (var version in typeMap) foreach (var version in typeMap)
{ {
var versionGroup = new ListViewGroup(version.Key); var versionGroup = new ListViewGroup(version.Key);
classesListView.Groups.Add(versionGroup); classesListView.Groups.Add(versionGroup);
foreach (var uclass in version.Value) foreach (var uclass in version.Value)
{ {
uclass.Value.Group = versionGroup; uclass.Value.Group = versionGroup;
classesListView.Items.Add(uclass.Value); classesListView.Items.Add(uclass.Value);
}
} }
typeMap.Clear(); }
classesListView.EndUpdate(); typeMap.Clear();
classesListView.EndUpdate();
var types = exportableAssets.Select(x => x.Type).Distinct().OrderBy(x => x.ToString()).ToArray(); var types = exportableAssets.Select(x => x.Type).Distinct().OrderBy(x => x.ToString()).ToArray();
foreach (var type in types) foreach (var type in types)
{
var typeItem = new ToolStripMenuItem
{ {
var typeItem = new ToolStripMenuItem CheckOnClick = true,
{ Name = type.ToString(),
CheckOnClick = true, Size = new Size(180, 22),
Name = type.ToString(), Text = type.ToString()
Size = new Size(180, 22), };
Text = type.ToString() typeItem.Click += typeToolStripMenuItem_Click;
}; filterTypeToolStripMenuItem.DropDownItems.Add(typeItem);
typeItem.Click += typeToolStripMenuItem_Click; }
filterTypeToolStripMenuItem.DropDownItems.Add(typeItem); allToolStripMenuItem.Checked = true;
} var log = $"Finished loading {assetsManager.assetsFileList.Count} files with {assetListView.Items.Count} exportable assets";
allToolStripMenuItem.Checked = true; var m_ObjectsCount = assetsManager.assetsFileList.Sum(x => x.m_Objects.Count);
var log = $"Finished loading {assetsManager.assetsFileList.Count} files with {assetListView.Items.Count} exportable assets"; var objectsCount = assetsManager.assetsFileList.Sum(x => x.Objects.Count);
var m_ObjectsCount = assetsManager.assetsFileList.Sum(x => x.m_Objects.Count); if (m_ObjectsCount != objectsCount)
var objectsCount = assetsManager.assetsFileList.Sum(x => x.Objects.Count); {
if (m_ObjectsCount != objectsCount) log += $" and {m_ObjectsCount - objectsCount} assets failed to read";
{ }
log += $" and {m_ObjectsCount - objectsCount} assets failed to read"; StatusStripUpdate(log);
}
StatusStripUpdate(log);
treeSearch.Select();
}));
} }
private void typeToolStripMenuItem_Click(object sender, EventArgs e) private void typeToolStripMenuItem_Click(object sender, EventArgs e)
@ -1138,26 +1135,9 @@ namespace AssetStudioGUI
} }
} }
public AssetStudioGUIForm()
{
Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
InitializeComponent();
delayTimer = new System.Timers.Timer(800);
delayTimer.Elapsed += new ElapsedEventHandler(delayTimer_Elapsed);
displayAll.Checked = Properties.Settings.Default.displayAll;
displayInfo.Checked = Properties.Settings.Default.displayInfo;
enablePreview.Checked = Properties.Settings.Default.enablePreview;
FMODinit();
Logger.Default = new GUILogger(StatusStripUpdate);
Progress.Default = new GUIProgress(SetProgressBarValue);
Studio.StatusStripUpdate = StatusStripUpdate;
}
private void ResetForm() private void ResetForm()
{ {
Text = "AssetStudioGUI"; Text = $"AssetStudioGUI v{Application.ProductVersion}";
assetsManager.Clear(); assetsManager.Clear();
exportableAssets.Clear(); exportableAssets.Clear();
visibleAssets.Clear(); visibleAssets.Clear();

View File

@ -1,4 +1,5 @@
using System; using AssetStudio;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Globalization; using System.Globalization;
@ -6,7 +7,6 @@ using System.IO;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using System.Windows.Forms; using System.Windows.Forms;
using AssetStudio;
using static AssetStudioGUI.Exporter; using static AssetStudioGUI.Exporter;
using Object = AssetStudio.Object; using Object = AssetStudio.Object;
@ -96,7 +96,7 @@ namespace AssetStudioGUI
return extractedCount; return extractedCount;
} }
public static Tuple<string, List<TreeNode>> BuildAssetData() public static (string, List<TreeNode>) BuildAssetData()
{ {
StatusStripUpdate("Building asset list..."); StatusStripUpdate("Building asset list...");
@ -109,7 +109,7 @@ namespace AssetStudioGUI
foreach (var assetsFile in assetsManager.assetsFileList) foreach (var assetsFile in assetsManager.assetsFileList)
{ {
var tempExportableAssets = new List<AssetItem>(); var tempExportableAssets = new List<AssetItem>();
AssetBundle ab = null; Dictionary<long, string> containers = null;
foreach (var asset in assetsFile.Objects.Values) foreach (var asset in assetsFile.Objects.Values)
{ {
var assetItem = new AssetItem(asset); var assetItem = new AssetItem(asset);
@ -174,8 +174,8 @@ namespace AssetStudioGUI
productName = m_PlayerSettings.productName; productName = m_PlayerSettings.productName;
break; break;
case AssetBundle m_AssetBundle: case AssetBundle m_AssetBundle:
ab = m_AssetBundle; containers = m_AssetBundle.m_Container.ToDictionary(x => x.Value.asset.m_PathID, x => x.Key);
assetItem.Text = ab.m_Name; assetItem.Text = m_AssetBundle.m_Name;
break; break;
case NamedObject m_NamedObject: case NamedObject m_NamedObject:
assetItem.Text = m_NamedObject.m_Name; assetItem.Text = m_NamedObject.m_Name;
@ -200,18 +200,21 @@ namespace AssetStudioGUI
} }
foreach (var item in tempExportableAssets) foreach (var item in tempExportableAssets)
{ {
if (ab != null) if (containers != null)
{ {
var container = ab.m_Container.FirstOrDefault(y => y.Value.asset.m_PathID == item.Asset.m_PathID).Key; if (containers.TryGetValue(item.Asset.m_PathID, out var container))
if (!string.IsNullOrEmpty(container))
{ {
item.Container = container; if (!string.IsNullOrEmpty(container))
{
item.Container = container;
}
} }
} }
item.SetSubItems(); item.SetSubItems();
} }
exportableAssets.AddRange(tempExportableAssets); exportableAssets.AddRange(tempExportableAssets);
tempExportableAssets.Clear(); tempExportableAssets.Clear();
containers?.Clear();
} }
visibleAssets = exportableAssets; visibleAssets = exportableAssets;
assetsNameHash.Clear(); assetsNameHash.Clear();
@ -291,7 +294,7 @@ namespace AssetStudioGUI
objectAssetItemDic.Clear(); objectAssetItemDic.Clear();
return new Tuple<string, List<TreeNode>>(productName, treeNodeCollection); return (productName, treeNodeCollection);
} }
public static Dictionary<string, SortedDictionary<int, TypeTreeItem>> BuildClassStructure() public static Dictionary<string, SortedDictionary<int, TypeTreeItem>> BuildClassStructure()