Browse Source

Move assembly loading from constructor to Loaded event.

pull/1/head
Daniel Grunwald 15 years ago
parent
commit
a4af0a46f2
  1. 3
      ICSharpCode.Decompiler/FlowAnalysis/ControlStructureDetector.cs
  2. 16
      ILSpy/AssemblyList.cs
  3. 3
      ILSpy/ILSpy.csproj
  4. 29
      ILSpy/MainWindow.xaml.cs
  5. 10
      ILSpy/TextView/DecompilerTextView.cs
  6. 7
      ILSpy/TreeNodes/ILSpyTreeNode.cs

3
ICSharpCode.Decompiler/FlowAnalysis/ControlStructureDetector.cs

@ -123,6 +123,9 @@ namespace ICSharpCode.Decompiler.FlowAnalysis
// This algorithm is applied recursively for any substructures (both detected loops and exception blocks) // This algorithm is applied recursively for any substructures (both detected loops and exception blocks)
// But maybe we should get rid of this complex stuff and instead treat every backward jump as a loop?
// That should still work with the IL produced by compilers, and has the advantage that the detected loop bodies are consecutive IL regions.
static void DetectLoops(ControlFlowGraph g, ControlStructure current, CancellationToken cancellationToken) static void DetectLoops(ControlFlowGraph g, ControlStructure current, CancellationToken cancellationToken)
{ {
g.ResetVisited(); g.ResetVisited();

16
ILSpy/AssemblyList.cs

@ -30,7 +30,7 @@ using Mono.Cecil;
namespace ICSharpCode.ILSpy namespace ICSharpCode.ILSpy
{ {
/// <summary> /// <summary>
/// Describes a list of assemblies. /// A list of assemblies.
/// </summary> /// </summary>
class AssemblyList class AssemblyList
{ {
@ -57,6 +57,13 @@ namespace ICSharpCode.ILSpy
Assemblies.Select(asm => new XElement("Assembly", asm.FileName)) Assemblies.Select(asm => new XElement("Assembly", asm.FileName))
); );
} }
public bool Dirty { get; set; }
public string ListName { get; set; }
public readonly ObservableCollection<AssemblyTreeNode> Assemblies = new ObservableCollection<AssemblyTreeNode>();
ConcurrentDictionary<TypeDefinition, TypeTreeNode> typeDict = new ConcurrentDictionary<TypeDefinition, TypeTreeNode>();
void Assemblies_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) void Assemblies_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{ {
@ -73,13 +80,6 @@ namespace ICSharpCode.ILSpy
); );
} }
public bool Dirty { get; set; }
public string ListName { get; set; }
public readonly ObservableCollection<AssemblyTreeNode> Assemblies = new ObservableCollection<AssemblyTreeNode>();
ConcurrentDictionary<TypeDefinition, TypeTreeNode> typeDict = new ConcurrentDictionary<TypeDefinition, TypeTreeNode>();
public void RegisterTypeNode(TypeTreeNode node) public void RegisterTypeNode(TypeTreeNode node)
{ {
// called on background loading thread, so we need to use a ConcurrentDictionary // called on background loading thread, so we need to use a ConcurrentDictionary

3
ILSpy/ILSpy.csproj

@ -202,5 +202,8 @@
<Folder Include="TreeNodes" /> <Folder Include="TreeNodes" />
<Folder Include="TextView" /> <Folder Include="TextView" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Content Include="ProfilingSessions\Session20110206_031358.sdps" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" /> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" />
</Project> </Project>

29
ILSpy/MainWindow.xaml.cs

@ -40,6 +40,7 @@ namespace ICSharpCode.ILSpy
/// </summary> /// </summary>
public partial class MainWindow : Window public partial class MainWindow : Window
{ {
ILSpySettings spySettings;
SessionSettings sessionSettings; SessionSettings sessionSettings;
AssemblyListManager assemblyListManager; AssemblyListManager assemblyListManager;
AssemblyList assemblyList; AssemblyList assemblyList;
@ -47,10 +48,9 @@ namespace ICSharpCode.ILSpy
public MainWindow() public MainWindow()
{ {
ILSpySettings spySettings = ILSpySettings.Load(); spySettings = ILSpySettings.Load();
this.sessionSettings = new SessionSettings(spySettings); this.sessionSettings = new SessionSettings(spySettings);
this.assemblyListManager = new AssemblyListManager(spySettings); this.assemblyListManager = new AssemblyListManager(spySettings);
this.assemblyList = assemblyListManager.LoadList(spySettings, sessionSettings.ActiveAssemblyList);
this.DataContext = sessionSettings; this.DataContext = sessionSettings;
this.Left = sessionSettings.WindowBounds.Left; this.Left = sessionSettings.WindowBounds.Left;
@ -63,11 +63,25 @@ namespace ICSharpCode.ILSpy
InitializeComponent(); InitializeComponent();
decompilerTextView.mainWindow = this; decompilerTextView.mainWindow = this;
sessionSettings.FilterSettings.PropertyChanged += filterSettings_PropertyChanged;
#if DEBUG
AddDebugItemsToToolbar();
#endif
this.Loaded += new RoutedEventHandler(MainWindow_Loaded);
}
void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
// Load AssemblyList only in Loaded event so that WPF is initialized before we start the CPU-heavy stuff.
// This makes the UI come up a bit faster.
this.assemblyList = assemblyListManager.LoadList(this.spySettings, sessionSettings.ActiveAssemblyList);
this.spySettings = null;
assemblyListTreeNode = new AssemblyListTreeNode(assemblyList); assemblyListTreeNode = new AssemblyListTreeNode(assemblyList);
assemblyListTreeNode.FilterSettings = sessionSettings.FilterSettings.Clone(); assemblyListTreeNode.FilterSettings = sessionSettings.FilterSettings.Clone();
sessionSettings.FilterSettings.PropertyChanged += new PropertyChangedEventHandler(filterSettings_PropertyChanged);
treeView.Root = assemblyListTreeNode;
assemblyListTreeNode.Select = SelectNode; assemblyListTreeNode.Select = SelectNode;
treeView.Root = assemblyListTreeNode;
string[] args = Environment.GetCommandLineArgs(); string[] args = Environment.GetCommandLineArgs();
for (int i = 1; i < args.Length; i++) { for (int i = 1; i < args.Length; i++) {
@ -77,10 +91,6 @@ namespace ICSharpCode.ILSpy
LoadInitialAssemblies(); LoadInitialAssemblies();
SelectNode(FindNodeByPath(sessionSettings.ActiveTreeViewPath)); SelectNode(FindNodeByPath(sessionSettings.ActiveTreeViewPath));
#if DEBUG
AddDebugItemsToToolbar();
#endif
} }
void LoadInitialAssemblies() void LoadInitialAssemblies()
@ -109,7 +119,8 @@ namespace ICSharpCode.ILSpy
// filterSettings is mutable; but the ILSpyTreeNode filtering assumes that filter settings are immutable. // filterSettings is mutable; but the ILSpyTreeNode filtering assumes that filter settings are immutable.
// Thus, the main window will use one mutable instance (for data-binding), and assign a new clone to the ILSpyTreeNodes whenever the main // Thus, the main window will use one mutable instance (for data-binding), and assign a new clone to the ILSpyTreeNodes whenever the main
// mutable instance changes. // mutable instance changes.
assemblyListTreeNode.FilterSettings = sessionSettings.FilterSettings.Clone(); if (assemblyListTreeNode != null)
assemblyListTreeNode.FilterSettings = sessionSettings.FilterSettings.Clone();
if (e.PropertyName == "Language") { if (e.PropertyName == "Language") {
TreeView_SelectionChanged(null, null); TreeView_SelectionChanged(null, null);
} }

10
ILSpy/TextView/DecompilerTextView.cs

@ -120,10 +120,20 @@ namespace ICSharpCode.ILSpy.TextView
static Task<SmartTextOutput> RunDecompiler(ILSpy.Language language, ILSpyTreeNodeBase[] nodes, DecompilationOptions options) static Task<SmartTextOutput> RunDecompiler(ILSpy.Language language, ILSpyTreeNodeBase[] nodes, DecompilationOptions options)
{ {
if (nodes.Length == 0) {
// If there's nothing to be decompiled, don't bother starting up a thread.
// (Improves perf in some cases since we don't have to wait for the thread-pool to accept our task)
TaskCompletionSource<SmartTextOutput> tcs = new TaskCompletionSource<SmartTextOutput>();
tcs.SetResult(new SmartTextOutput());
return tcs.Task;
}
return Task.Factory.StartNew( return Task.Factory.StartNew(
delegate { delegate {
SmartTextOutput textOutput = new SmartTextOutput(); SmartTextOutput textOutput = new SmartTextOutput();
bool first = true;
foreach (var node in nodes) { foreach (var node in nodes) {
if (first) first = false; else textOutput.WriteLine();
options.CancellationToken.ThrowIfCancellationRequested(); options.CancellationToken.ThrowIfCancellationRequested();
node.Decompile(language, textOutput, options); node.Decompile(language, textOutput, options);
} }

7
ILSpy/TreeNodes/ILSpyTreeNode.cs

@ -118,6 +118,13 @@ namespace ICSharpCode.ILSpy.TreeNodes
} else { } else {
goto default; goto default;
} }
case NotifyCollectionChangedAction.Remove:
if (e.OldItems.Count == 1) {
visibleChildren.Remove((T)e.OldItems[0]);
break;
} else {
goto default;
}
default: default:
ResetChildren(); ResetChildren();
break; break;

Loading…
Cancel
Save