diff options
Diffstat (limited to 'main/src')
11 files changed, 75 insertions, 36 deletions
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ChainedExtension.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ChainedExtension.cs index eabec7455b..1b8b3f282b 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ChainedExtension.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ChainedExtension.cs @@ -106,7 +106,7 @@ namespace MonoDevelop.Projects public virtual void Dispose () { if (chain != null) - chain.DisposeExtension (this); + chain.RemoveExtension (this); } } } diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/DotNetProject.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/DotNetProject.cs index 5513ee6f5b..ece99c73fb 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/DotNetProject.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/DotNetProject.cs @@ -109,9 +109,9 @@ namespace MonoDevelop.Projects usePartialTypes = SupportsPartialTypes; } - protected override void SetShared () + protected override void OnSetShared () { - base.SetShared (); + base.OnSetShared (); projectReferences.SetShared (); } diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ExtensionChain.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ExtensionChain.cs index 60eae48ceb..09fe6e5566 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ExtensionChain.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ExtensionChain.cs @@ -25,13 +25,14 @@ // THE SOFTWARE. using System; using System.Collections.Generic; +using System.Linq; namespace MonoDevelop.Projects { public class ExtensionChain { - ChainedExtension first; Dictionary<Type,ChainedExtension> chains = new Dictionary<Type, ChainedExtension> (); + ChainedExtension[] extensions; public static ExtensionChain Create<T> (T[] extensions) where T:ChainedExtension { @@ -40,7 +41,7 @@ namespace MonoDevelop.Projects for (int n = extensions.Length - 2; n >= 0; n--) extensions [n].InitChain (c, extensions [n + 1]); - c.first = extensions [0]; + c.extensions = extensions; return c; } @@ -49,7 +50,7 @@ namespace MonoDevelop.Projects ChainedExtension e; if (!chains.TryGetValue (typeof(T), out e)) { e = new T (); - e.InitChain (this, ChainedExtension.FindNextImplementation<T> (first)); + e.InitChain (this, ChainedExtension.FindNextImplementation<T> (extensions[0])); chains [typeof(T)] = e; } return (T)e; @@ -57,32 +58,37 @@ namespace MonoDevelop.Projects public IEnumerable<ChainedExtension> GetAllExtensions () { - var e = first; - while (e != null) { - yield return e; - e = e.Next; - } + return extensions; } - internal void DisposeExtension (ChainedExtension ext) + internal void AddExtension (ChainedExtension ext) { - var e = first; - var extensions = new List<ChainedExtension> (); - while (e != null) { - if (e != ext) - extensions.Add (e); - e = e.Next; - } - for (int n = extensions.Count - 2; n >= 0; n--) + Array.Resize (ref extensions, extensions.Length + 1); + extensions [extensions.Length - 1] = ext; + Rechain (); + } + + internal void RemoveExtension (ChainedExtension ext) + { + extensions = extensions.Where (e => e != ext).ToArray (); + Rechain (); + } + + void Rechain () + { + // Re-chain every extension + for (int n = extensions.Length - 2; n >= 0; n--) extensions [n].InitChain (this, extensions [n + 1]); - first = extensions [0]; + + // The first extension object in type-specific chains is a placeholder extension used only to hold + // a reference to the real first extension. foreach (var fex in chains) - fex.Value.InitChain (this, ChainedExtension.FindNextImplementation (fex.Key, first)); + fex.Value.InitChain (this, ChainedExtension.FindNextImplementation (fex.Key, extensions[0])); } public void Dispose () { - first.DisposeChain (); + extensions[0].DisposeChain (); } } } diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Project.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Project.cs index efa8b59602..ac075fbc43 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Project.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Project.cs @@ -101,9 +101,9 @@ namespace MonoDevelop.Projects } } - protected override void SetShared () + protected override void OnSetShared () { - base.SetShared (); + base.OnSetShared (); items.SetShared (); files.SetShared (); } diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Solution.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Solution.cs index 32cbc108c0..7133ba3907 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Solution.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Solution.cs @@ -815,6 +815,9 @@ namespace MonoDevelop.Projects internal /*protected virtual*/ void OnSolutionItemAdded (SolutionItemChangeEventArgs args) { + if (IsShared) + args.Solution.SetShared (); + solutionItems = null; SolutionFolder sf = args.SolutionItem as SolutionFolder; diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionItem.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionItem.cs index 2e4e1dbad9..d92d5e02d8 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionItem.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionItem.cs @@ -174,7 +174,6 @@ namespace MonoDevelop.Projects /// </remarks> protected virtual void OnItemReady () { - SetShared (); } internal void NotifyItemReady () @@ -183,9 +182,9 @@ namespace MonoDevelop.Projects OnItemReady (); } - protected override void SetShared () + protected override void OnSetShared () { - base.SetShared (); + base.OnSetShared (); configurations.SetShared (); } diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Workspace.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Workspace.cs index 1d9bc6d680..6736849caa 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Workspace.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Workspace.cs @@ -55,9 +55,9 @@ namespace MonoDevelop.Projects return MD1FileFormat.Instance.WriteFile (FileName, this, monitor); } - protected override void SetShared () + protected override void OnSetShared () { - base.SetShared (); + base.OnSetShared (); items.SetShared (); } diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/WorkspaceItem.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/WorkspaceItem.cs index b0809682b7..697460852b 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/WorkspaceItem.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/WorkspaceItem.cs @@ -319,7 +319,6 @@ namespace MonoDevelop.Projects /// </remarks> protected virtual void OnItemReady () { - SetShared (); } internal void NotifyItemReady () diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/WorkspaceObject.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/WorkspaceObject.cs index 2060a57b8d..53a974ac55 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/WorkspaceObject.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/WorkspaceObject.cs @@ -78,7 +78,24 @@ namespace MonoDevelop.Projects Runtime.AssertMainThread (); } - protected virtual void SetShared () + /// <summary> + /// Gets a value indicating whether this instance is shared. + /// </summary> + /// <remarks>Shared objects can only be modified in the main thread</remarks> + public bool IsShared { + get { return isShared; } + } + + /// <summary> + /// Sets this object as shared, which means that it is accessible from several threads for reading, + /// but it can only be modified in the main thread + /// </summary> + public void SetShared () + { + OnSetShared (); + } + + protected virtual void OnSetShared () { isShared = true; ItemExtension.NotifyShared (); @@ -267,6 +284,19 @@ namespace MonoDevelop.Projects } } + public void AttachExtension (WorkspaceObjectExtension ext) + { + AssertMainThread (); + ExtensionChain.AddExtension (ext); + ext.Init (this); + } + + public void DetachExtension (WorkspaceObjectExtension ext) + { + AssertMainThread (); + ExtensionChain.RemoveExtension (ext); + } + void InitializeExtensionChain () { // Create an initial empty extension chain. This avoid crashes in case a call to SupportsObject ends diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/WorkspaceObjectExtension.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/WorkspaceObjectExtension.cs index 6babc2842d..a1a5dbc03b 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/WorkspaceObjectExtension.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/WorkspaceObjectExtension.cs @@ -73,12 +73,12 @@ namespace MonoDevelop.Projects internal void NotifyShared () { - SetShared (); + OnSetShared (); if (next != null) - next.SetShared (); + next.OnSetShared (); } - protected virtual void SetShared () + protected virtual void OnSetShared () { } diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/RootWorkspace.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/RootWorkspace.cs index 7bfd13a306..37146a2fce 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/RootWorkspace.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/RootWorkspace.cs @@ -558,8 +558,10 @@ namespace MonoDevelop.Ide using (monitor) { try { // Add the item in the GUI thread. It is not safe to do it in the background thread. - if (!monitor.CancellationToken.IsCancellationRequested) + if (!monitor.CancellationToken.IsCancellationRequested) { + item.SetShared (); Items.Add (item); + } else { item.Dispose (); return false; |