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