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 @@ -123,6 +123,9 @@ namespace ICSharpCode.Decompiler.FlowAnalysis
// 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)
{
g.ResetVisited();

16
ILSpy/AssemblyList.cs

@ -30,7 +30,7 @@ using Mono.Cecil; @@ -30,7 +30,7 @@ using Mono.Cecil;
namespace ICSharpCode.ILSpy
{
/// <summary>
/// Describes a list of assemblies.
/// A list of assemblies.
/// </summary>
class AssemblyList
{
@ -57,6 +57,13 @@ namespace ICSharpCode.ILSpy @@ -57,6 +57,13 @@ namespace ICSharpCode.ILSpy
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)
{
@ -73,13 +80,6 @@ namespace ICSharpCode.ILSpy @@ -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)
{
// called on background loading thread, so we need to use a ConcurrentDictionary

3
ILSpy/ILSpy.csproj

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

29
ILSpy/MainWindow.xaml.cs

@ -40,6 +40,7 @@ namespace ICSharpCode.ILSpy @@ -40,6 +40,7 @@ namespace ICSharpCode.ILSpy
/// </summary>
public partial class MainWindow : Window
{
ILSpySettings spySettings;
SessionSettings sessionSettings;
AssemblyListManager assemblyListManager;
AssemblyList assemblyList;
@ -47,10 +48,9 @@ namespace ICSharpCode.ILSpy @@ -47,10 +48,9 @@ namespace ICSharpCode.ILSpy
public MainWindow()
{
ILSpySettings spySettings = ILSpySettings.Load();
spySettings = ILSpySettings.Load();
this.sessionSettings = new SessionSettings(spySettings);
this.assemblyListManager = new AssemblyListManager(spySettings);
this.assemblyList = assemblyListManager.LoadList(spySettings, sessionSettings.ActiveAssemblyList);
this.DataContext = sessionSettings;
this.Left = sessionSettings.WindowBounds.Left;
@ -63,11 +63,25 @@ namespace ICSharpCode.ILSpy @@ -63,11 +63,25 @@ namespace ICSharpCode.ILSpy
InitializeComponent();
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.FilterSettings = sessionSettings.FilterSettings.Clone();
sessionSettings.FilterSettings.PropertyChanged += new PropertyChangedEventHandler(filterSettings_PropertyChanged);
treeView.Root = assemblyListTreeNode;
assemblyListTreeNode.Select = SelectNode;
treeView.Root = assemblyListTreeNode;
string[] args = Environment.GetCommandLineArgs();
for (int i = 1; i < args.Length; i++) {
@ -77,10 +91,6 @@ namespace ICSharpCode.ILSpy @@ -77,10 +91,6 @@ namespace ICSharpCode.ILSpy
LoadInitialAssemblies();
SelectNode(FindNodeByPath(sessionSettings.ActiveTreeViewPath));
#if DEBUG
AddDebugItemsToToolbar();
#endif
}
void LoadInitialAssemblies()
@ -109,7 +119,8 @@ namespace ICSharpCode.ILSpy @@ -109,7 +119,8 @@ namespace ICSharpCode.ILSpy
// 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
// mutable instance changes.
assemblyListTreeNode.FilterSettings = sessionSettings.FilterSettings.Clone();
if (assemblyListTreeNode != null)
assemblyListTreeNode.FilterSettings = sessionSettings.FilterSettings.Clone();
if (e.PropertyName == "Language") {
TreeView_SelectionChanged(null, null);
}

10
ILSpy/TextView/DecompilerTextView.cs

@ -120,10 +120,20 @@ namespace ICSharpCode.ILSpy.TextView @@ -120,10 +120,20 @@ namespace ICSharpCode.ILSpy.TextView
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(
delegate {
SmartTextOutput textOutput = new SmartTextOutput();
bool first = true;
foreach (var node in nodes) {
if (first) first = false; else textOutput.WriteLine();
options.CancellationToken.ThrowIfCancellationRequested();
node.Decompile(language, textOutput, options);
}

7
ILSpy/TreeNodes/ILSpyTreeNode.cs

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

Loading…
Cancel
Save