Browse Source

Use NullSafeSimpleModelCollection where possible

pull/59/merge
Daniel Grunwald 12 years ago
parent
commit
64501c842d
  1. 3
      src/AddIns/Debugger/Debugger.AddIn/Pads/ClassBrowserSupport.cs
  2. 2
      src/AddIns/Misc/PackageManagement/Project/Src/Design/FakePackageManagementProjectService.cs
  3. 2
      src/AddIns/Misc/PackageManagement/Test/Src/Helpers/ProjectHelper.cs
  4. 2
      src/Main/Base/Project/Dom/ClassBrowser/IClassBrowser.cs
  5. 30
      src/Main/Base/Project/Dom/SimpleModelCollection.cs
  6. 13
      src/Main/Base/Project/Dom/SynchronizedModelCollection.cs
  7. 2
      src/Main/Base/Project/Src/Project/AbstractProject.cs
  8. 1
      src/Main/SharpDevelop/Dom/ClassBrowser/OpenFromGacDialog.xaml
  9. 2
      src/Main/SharpDevelop/Dom/ClassBrowser/OpenFromGacDialog.xaml.cs
  10. 2
      src/Main/SharpDevelop/Project/ProjectService.cs

3
src/AddIns/Debugger/Debugger.AddIn/Pads/ClassBrowserSupport.cs

@ -67,7 +67,8 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
if (process == null) if (process == null)
throw new ArgumentNullException("process"); throw new ArgumentNullException("process");
this.process = process; this.process = process;
this.modules = new SimpleModelCollection<Debugger.Module>(this.process.Modules); this.modules = new NullSafeSimpleModelCollection<Debugger.Module>();
this.modules.AddRange(this.process.Modules);
this.process.ModuleLoaded += ModuleLoaded; this.process.ModuleLoaded += ModuleLoaded;
this.process.ModuleUnloaded += ModuleUnloaded; this.process.ModuleUnloaded += ModuleUnloaded;
} }

2
src/AddIns/Misc/PackageManagement/Project/Src/Design/FakePackageManagementProjectService.cs

@ -40,7 +40,7 @@ namespace ICSharpCode.PackageManagement.Design
} }
} }
public readonly SimpleModelCollection<IModelCollection<IProject>> ProjectCollections = new SimpleModelCollection<IModelCollection<IProject>>(); public readonly IMutableModelCollection<IModelCollection<IProject>> ProjectCollections = new NullSafeSimpleModelCollection<IModelCollection<IProject>>();
IModelCollection<IProject> allProjects; IModelCollection<IProject> allProjects;
public IModelCollection<IProject> AllProjects { public IModelCollection<IProject> AllProjects {

2
src/AddIns/Misc/PackageManagement/Test/Src/Helpers/ProjectHelper.cs

@ -18,7 +18,7 @@ namespace PackageManagement.Tests.Helpers
SD.InitializeForUnitTests(); SD.InitializeForUnitTests();
ISolution solution = MockRepository.GenerateStrictMock<ISolution>(); ISolution solution = MockRepository.GenerateStrictMock<ISolution>();
solution.Stub(s => s.MSBuildProjectCollection).Return(new Microsoft.Build.Evaluation.ProjectCollection()); solution.Stub(s => s.MSBuildProjectCollection).Return(new Microsoft.Build.Evaluation.ProjectCollection());
solution.Stub(s => s.Projects).Return(new SimpleModelCollection<IProject>()); solution.Stub(s => s.Projects).Return(new NullSafeSimpleModelCollection<IProject>());
solution.Stub(s => s.ActiveConfiguration).Return(new ConfigurationAndPlatform("Debug", "Any CPU")); solution.Stub(s => s.ActiveConfiguration).Return(new ConfigurationAndPlatform("Debug", "Any CPU"));
//solution.Stub(s => s.FileName).Return(FileName.Create(@"d:\projects\Test\TestSolution.sln")); //solution.Stub(s => s.FileName).Return(FileName.Create(@"d:\projects\Test\TestSolution.sln"));
return solution; return solution;

2
src/Main/Base/Project/Dom/ClassBrowser/IClassBrowser.cs

@ -21,7 +21,7 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser
public AssemblyList() public AssemblyList()
{ {
Name = "<default>"; Name = "<default>";
Assemblies = new SimpleModelCollection<IAssemblyModel>(); Assemblies = new NullSafeSimpleModelCollection<IAssemblyModel>();
} }
} }
} }

30
src/Main/Base/Project/Dom/SimpleModelCollection.cs

@ -16,7 +16,7 @@ namespace ICSharpCode.SharpDevelop.Dom
/// </summary> /// </summary>
public class SimpleModelCollection<T> : IMutableModelCollection<T> public class SimpleModelCollection<T> : IMutableModelCollection<T>
{ {
readonly ModelCollectionChangedEvent<T> collectionChangedEvent; readonly ModelCollectionChangedEvent<T> collectionChangedEvent = new ModelCollectionChangedEvent<T>();
readonly List<T> list; readonly List<T> list;
List<T> addedItems; List<T> addedItems;
List<T> removedItems; List<T> removedItems;
@ -24,13 +24,13 @@ namespace ICSharpCode.SharpDevelop.Dom
public SimpleModelCollection() public SimpleModelCollection()
{ {
this.list = new List<T>(); this.list = new List<T>();
collectionChangedEvent = new ModelCollectionChangedEvent<T>();
} }
public SimpleModelCollection(IEnumerable<T> items) public SimpleModelCollection(IEnumerable<T> items)
{ {
this.list = new List<T>(items); this.list = new List<T>(items);
collectionChangedEvent = new ModelCollectionChangedEvent<T>(); // Note: intentionally not using ValidateItem(), as calling a virtual method
// from a constructor is problematic
} }
protected void CheckReentrancy() protected void CheckReentrancy()
@ -39,6 +39,9 @@ namespace ICSharpCode.SharpDevelop.Dom
throw new InvalidOperationException("Cannot modify the collection from within the CollectionChanged event."); throw new InvalidOperationException("Cannot modify the collection from within the CollectionChanged event.");
} }
/// <summary>
/// Called before an item
/// </summary>
protected virtual void ValidateItem(T item) protected virtual void ValidateItem(T item)
{ {
} }
@ -182,15 +185,20 @@ namespace ICSharpCode.SharpDevelop.Dom
if (items == null) if (items == null)
throw new ArgumentNullException("items"); throw new ArgumentNullException("items");
CheckReentrancy(); CheckReentrancy();
List<T> itemsList = items.ToList(); try {
for (int i = 0; i < itemsList.Count; i++) { foreach (T item in items) {
ValidateItem(itemsList[i]); // Add each item before validating the next,
} // this is necessary because ValidateItem() might be checking
for (int i = 0; i < itemsList.Count; i++) { // for duplicates (e.g. KeyedModelCollection<,>)
OnAdd(itemsList[i]); ValidateItem(item);
OnAdd(item);
list.Add(item);
}
} finally {
// In case validation fails, we still need to raise the event
// for the items that were added successfully.
RaiseEventIfNotInBatch();
} }
list.AddRange(itemsList);
RaiseEventIfNotInBatch();
} }
public bool Remove(T item) public bool Remove(T item)

13
src/Main/Base/Project/Dom/SynchronizedModelCollection.cs

@ -31,10 +31,17 @@ namespace ICSharpCode.SharpDevelop.Dom
this.syncRoot = syncRoot; this.syncRoot = syncRoot;
} }
// Event registration is thread-safe on the underlying collection
public event ModelCollectionChangedEventHandler<T> CollectionChanged { public event ModelCollectionChangedEventHandler<T> CollectionChanged {
add { underlyingCollection.CollectionChanged += value; } add {
remove { underlyingCollection.CollectionChanged -= value; } lock (syncRoot) {
underlyingCollection.CollectionChanged += value;
}
}
remove {
lock (syncRoot) {
underlyingCollection.CollectionChanged -= value;
}
}
} }
#region IMutableModelCollection implementation #region IMutableModelCollection implementation

2
src/Main/Base/Project/Src/Project/AbstractProject.cs

@ -196,7 +196,7 @@ namespace ICSharpCode.SharpDevelop.Project
#endregion #endregion
#region ProjectSections #region ProjectSections
SimpleModelCollection<SolutionSection> projectSections = new SimpleModelCollection<SolutionSection>(); SimpleModelCollection<SolutionSection> projectSections = new NullSafeSimpleModelCollection<SolutionSection>();
[Browsable(false)] [Browsable(false)]
public IMutableModelCollection<SolutionSection> ProjectSections { public IMutableModelCollection<SolutionSection> ProjectSections {

1
src/Main/SharpDevelop/Dom/ClassBrowser/OpenFromGacDialog.xaml

@ -1,5 +1,6 @@
<Window <Window
x:Class="ICSharpCode.SharpDevelop.Dom.ClassBrowser.OpenFromGacDialog" x:Class="ICSharpCode.SharpDevelop.Dom.ClassBrowser.OpenFromGacDialog"
x:ClassModifier="internal"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:core="http://icsharpcode.net/sharpdevelop/core" xmlns:core="http://icsharpcode.net/sharpdevelop/core"

2
src/Main/SharpDevelop/Dom/ClassBrowser/OpenFromGacDialog.xaml.cs

@ -35,7 +35,7 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser
/// <summary> /// <summary>
/// Interaction logic for OpenFromGacDialog.xaml /// Interaction logic for OpenFromGacDialog.xaml
/// </summary> /// </summary>
public partial class OpenFromGacDialog : Window internal partial class OpenFromGacDialog : Window
{ {
ObservableCollection<GacEntry> gacEntries = new ObservableCollection<GacEntry>(); ObservableCollection<GacEntry> gacEntries = new ObservableCollection<GacEntry>();
ObservableCollection<GacEntry> filteredEntries = new ObservableCollection<GacEntry>(); ObservableCollection<GacEntry> filteredEntries = new ObservableCollection<GacEntry>();

2
src/Main/SharpDevelop/Project/ProjectService.cs

@ -17,7 +17,7 @@ namespace ICSharpCode.SharpDevelop.Project
{ {
public SDProjectService() public SDProjectService()
{ {
allSolutions = new SimpleModelCollection<ISolution>(); allSolutions = new NullSafeSimpleModelCollection<ISolution>();
allProjects = allSolutions.SelectMany(s => s.Projects); allProjects = allSolutions.SelectMany(s => s.Projects);
SD.GetFutureService<IWorkbench>().ContinueWith(t => t.Result.ActiveViewContentChanged += ActiveViewContentChanged); SD.GetFutureService<IWorkbench>().ContinueWith(t => t.Result.ActiveViewContentChanged += ActiveViewContentChanged);

Loading…
Cancel
Save