Expose read-only collections in PluginManager instead of full collections
This commit is contained in:
@@ -14,12 +14,12 @@ namespace Torch.API.Managers
|
||||
/// <summary>
|
||||
/// Fired when plugins are loaded.
|
||||
/// </summary>
|
||||
event Action<ICollection<ITorchPlugin>> PluginsLoaded;
|
||||
event Action<IReadOnlyCollection<ITorchPlugin>> PluginsLoaded;
|
||||
|
||||
/// <summary>
|
||||
/// Collection of loaded plugins.
|
||||
/// </summary>
|
||||
IDictionary<Guid, ITorchPlugin> Plugins { get; }
|
||||
IReadOnlyDictionary<Guid, ITorchPlugin> Plugins { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Updates all loaded plugins.
|
||||
|
@@ -29,7 +29,7 @@ namespace Torch.Server.ViewModels
|
||||
pluginManager.PluginsLoaded += PluginManager_PluginsLoaded;
|
||||
}
|
||||
|
||||
private void PluginManager_PluginsLoaded(ICollection<ITorchPlugin> obj)
|
||||
private void PluginManager_PluginsLoaded(IReadOnlyCollection<ITorchPlugin> obj)
|
||||
{
|
||||
Plugins.Clear();
|
||||
foreach (var plugin in obj)
|
||||
|
54
Torch/Extensions/ICollectionExtensions.cs
Normal file
54
Torch/Extensions/ICollectionExtensions.cs
Normal file
@@ -0,0 +1,54 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
namespace Torch
|
||||
{
|
||||
public static class ICollectionExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns a read-only wrapped <see cref="ICollection{T}"/>
|
||||
/// </summary>
|
||||
public static IReadOnlyCollection<T> AsReadOnly<T>(this ICollection<T> source)
|
||||
{
|
||||
if (source == null)
|
||||
throw new ArgumentNullException(nameof(source));
|
||||
return source as IReadOnlyCollection<T> ?? new ReadOnlyCollectionAdapter<T>(source);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a read-only wrapped <see cref="IList{T}"/>
|
||||
/// </summary>
|
||||
public static IReadOnlyList<T> AsReadOnly<T>(this IList<T> source)
|
||||
{
|
||||
if (source == null)
|
||||
throw new ArgumentNullException(nameof(source));
|
||||
return source as IReadOnlyList<T> ?? new ReadOnlyCollection<T>(source);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a read-only wrapped <see cref="IDictionary{TKey, TValue}"/>
|
||||
/// </summary>
|
||||
public static IReadOnlyDictionary<TKey, TValue> AsReadOnly<TKey, TValue>(this IDictionary<TKey, TValue> source)
|
||||
{
|
||||
if (source == null)
|
||||
throw new ArgumentNullException(nameof(source));
|
||||
return source as IReadOnlyDictionary<TKey, TValue> ?? new ReadOnlyDictionary<TKey, TValue>(source);
|
||||
}
|
||||
|
||||
sealed class ReadOnlyCollectionAdapter<T> : IReadOnlyCollection<T>
|
||||
{
|
||||
private readonly ICollection<T> _source;
|
||||
|
||||
public ReadOnlyCollectionAdapter(ICollection<T> source)
|
||||
{
|
||||
_source = source;
|
||||
}
|
||||
|
||||
public int Count => _source.Count;
|
||||
public IEnumerator<T> GetEnumerator() => _source.GetEnumerator();
|
||||
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
@@ -25,13 +26,14 @@ namespace Torch.Managers
|
||||
private static Logger _log = LogManager.GetLogger(nameof(PluginManager));
|
||||
private const string MANIFEST_NAME = "manifest.xml";
|
||||
public readonly string PluginDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Plugins");
|
||||
private readonly ObservableDictionary<Guid, ITorchPlugin> _plugins = new ObservableDictionary<Guid, ITorchPlugin>();
|
||||
[Dependency]
|
||||
private CommandManager _commandManager;
|
||||
|
||||
/// <inheritdoc />
|
||||
public IDictionary<Guid, ITorchPlugin> Plugins { get; } = new ObservableDictionary<Guid, ITorchPlugin>();
|
||||
public IReadOnlyDictionary<Guid, ITorchPlugin> Plugins => _plugins.AsReadOnly();
|
||||
|
||||
public event Action<ICollection<ITorchPlugin>> PluginsLoaded;
|
||||
public event Action<IReadOnlyCollection<ITorchPlugin>> PluginsLoaded;
|
||||
|
||||
public PluginManager(ITorchBase torchInstance) : base(torchInstance)
|
||||
{
|
||||
@@ -44,7 +46,7 @@ namespace Torch.Managers
|
||||
/// </summary>
|
||||
public void UpdatePlugins()
|
||||
{
|
||||
foreach (var plugin in Plugins.Values)
|
||||
foreach (var plugin in _plugins.Values)
|
||||
plugin.Update();
|
||||
}
|
||||
|
||||
@@ -53,10 +55,10 @@ namespace Torch.Managers
|
||||
/// </summary>
|
||||
public override void Detach()
|
||||
{
|
||||
foreach (var plugin in Plugins.Values)
|
||||
foreach (var plugin in _plugins.Values)
|
||||
plugin.Dispose();
|
||||
|
||||
Plugins.Clear();
|
||||
_plugins.Clear();
|
||||
}
|
||||
|
||||
public void LoadPlugins()
|
||||
@@ -75,9 +77,9 @@ namespace Torch.Managers
|
||||
continue;
|
||||
}
|
||||
|
||||
if (Plugins.ContainsKey(manifest.Guid))
|
||||
if (_plugins.ContainsKey(manifest.Guid))
|
||||
{
|
||||
_log.Error($"The GUID provided by {manifest.Name} ({item}) is already in use by {Plugins[manifest.Guid].Name}");
|
||||
_log.Error($"The GUID provided by {manifest.Name} ({item}) is already in use by {_plugins[manifest.Guid].Name}");
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -87,9 +89,9 @@ namespace Torch.Managers
|
||||
LoadPluginFromFolder(path);
|
||||
}
|
||||
|
||||
Plugins.ForEach(x => x.Value.Init(Torch));
|
||||
_log.Info($"Loaded {Plugins.Count} plugins.");
|
||||
PluginsLoaded?.Invoke(Plugins.Values);
|
||||
_plugins.ForEach(x => x.Value.Init(Torch));
|
||||
_log.Info($"Loaded {_plugins.Count} plugins.");
|
||||
PluginsLoaded?.Invoke(_plugins.Values.AsReadOnly());
|
||||
}
|
||||
|
||||
private void DownloadPluginUpdates()
|
||||
@@ -307,14 +309,14 @@ namespace Torch.Managers
|
||||
plugin.Manifest = manifest;
|
||||
plugin.StoragePath = Torch.Config.InstancePath;
|
||||
plugin.Torch = Torch;
|
||||
Plugins.Add(manifest.Guid, plugin);
|
||||
_plugins.Add(manifest.Guid, plugin);
|
||||
_commandManager.RegisterPluginCommands(plugin);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IEnumerable.GetEnumerator"/>
|
||||
public IEnumerator<ITorchPlugin> GetEnumerator()
|
||||
{
|
||||
return Plugins.Values.GetEnumerator();
|
||||
return _plugins.Values.GetEnumerator();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
|
@@ -157,6 +157,7 @@
|
||||
<Compile Include="ChatMessage.cs" />
|
||||
<Compile Include="Collections\ObservableList.cs" />
|
||||
<Compile Include="Extensions\DispatcherExtensions.cs" />
|
||||
<Compile Include="Extensions\ICollectionExtensions.cs" />
|
||||
<Compile Include="Managers\DependencyManager.cs" />
|
||||
<Compile Include="Managers\PatchManager\AssemblyMemory.cs" />
|
||||
<Compile Include="Managers\PatchManager\DecoratedMethod.cs" />
|
||||
|
Reference in New Issue
Block a user