Skip to content

Commit b7f2a62

Browse files
committed
Expose read-only collections in PluginManager instead of full collections
1 parent 1f4197c commit b7f2a62

5 files changed

Lines changed: 72 additions & 15 deletions

File tree

‎Torch.API/Managers/IPluginManager.cs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,12 @@ public interface IPluginManager : IManager, IEnumerable<ITorchPlugin>
1414
/// <summary>
1515
/// Fired when plugins are loaded.
1616
/// </summary>
17-
event Action<ICollection<ITorchPlugin>> PluginsLoaded;
17+
event Action<IReadOnlyCollection<ITorchPlugin>> PluginsLoaded;
1818

1919
/// <summary>
2020
/// Collection of loaded plugins.
2121
/// </summary>
22-
IDictionary<Guid, ITorchPlugin> Plugins { get; }
22+
IReadOnlyDictionary<Guid, ITorchPlugin> Plugins { get; }
2323

2424
/// <summary>
2525
/// Updates all loaded plugins.

‎Torch.Server/ViewModels/PluginManagerViewModel.cs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public PluginManagerViewModel(IPluginManager pluginManager)
2929
pluginManager.PluginsLoaded += PluginManager_PluginsLoaded;
3030
}
3131

32-
private void PluginManager_PluginsLoaded(ICollection<ITorchPlugin> obj)
32+
private void PluginManager_PluginsLoaded(IReadOnlyCollection<ITorchPlugin> obj)
3333
{
3434
Plugins.Clear();
3535
foreach (var plugin in obj)
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
using System;
2+
using System.Collections;
3+
using System.Collections.Generic;
4+
using System.Collections.ObjectModel;
5+
6+
namespace Torch
7+
{
8+
public static class ICollectionExtensions
9+
{
10+
/// <summary>
11+
/// Returns a read-only wrapped <see cref="ICollection{T}"/>
12+
/// </summary>
13+
public static IReadOnlyCollection<T> AsReadOnly<T>(this ICollection<T> source)
14+
{
15+
if (source == null)
16+
throw new ArgumentNullException(nameof(source));
17+
return source as IReadOnlyCollection<T> ?? new ReadOnlyCollectionAdapter<T>(source);
18+
}
19+
20+
/// <summary>
21+
/// Returns a read-only wrapped <see cref="IList{T}"/>
22+
/// </summary>
23+
public static IReadOnlyList<T> AsReadOnly<T>(this IList<T> source)
24+
{
25+
if (source == null)
26+
throw new ArgumentNullException(nameof(source));
27+
return source as IReadOnlyList<T> ?? new ReadOnlyCollection<T>(source);
28+
}
29+
30+
/// <summary>
31+
/// Returns a read-only wrapped <see cref="IDictionary{TKey, TValue}"/>
32+
/// </summary>
33+
public static IReadOnlyDictionary<TKey, TValue> AsReadOnly<TKey, TValue>(this IDictionary<TKey, TValue> source)
34+
{
35+
if (source == null)
36+
throw new ArgumentNullException(nameof(source));
37+
return source as IReadOnlyDictionary<TKey, TValue> ?? new ReadOnlyDictionary<TKey, TValue>(source);
38+
}
39+
40+
sealed class ReadOnlyCollectionAdapter<T> : IReadOnlyCollection<T>
41+
{
42+
private readonly ICollection<T> _source;
43+
44+
public ReadOnlyCollectionAdapter(ICollection<T> source)
45+
{
46+
_source = source;
47+
}
48+
49+
public int Count => _source.Count;
50+
public IEnumerator<T> GetEnumerator() => _source.GetEnumerator();
51+
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
52+
}
53+
}
54+
}

‎Torch/Plugins/PluginManager.cs‎

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Collections;
33
using System.Collections.Generic;
4+
using System.Collections.ObjectModel;
45
using System.IO;
56
using System.IO.Compression;
67
using System.Linq;
@@ -25,13 +26,14 @@ public class PluginManager : Manager, IPluginManager
2526
private static Logger _log = LogManager.GetLogger(nameof(PluginManager));
2627
private const string MANIFEST_NAME = "manifest.xml";
2728
public readonly string PluginDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Plugins");
29+
private readonly ObservableDictionary<Guid, ITorchPlugin> _plugins = new ObservableDictionary<Guid, ITorchPlugin>();
2830
[Dependency]
2931
private CommandManager _commandManager;
3032

3133
/// <inheritdoc />
32-
public IDictionary<Guid, ITorchPlugin> Plugins { get; } = new ObservableDictionary<Guid, ITorchPlugin>();
34+
public IReadOnlyDictionary<Guid, ITorchPlugin> Plugins => _plugins.AsReadOnly();
3335

34-
public event Action<ICollection<ITorchPlugin>> PluginsLoaded;
36+
public event Action<IReadOnlyCollection<ITorchPlugin>> PluginsLoaded;
3537

3638
public PluginManager(ITorchBase torchInstance) : base(torchInstance)
3739
{
@@ -44,7 +46,7 @@ public PluginManager(ITorchBase torchInstance) : base(torchInstance)
4446
/// </summary>
4547
public void UpdatePlugins()
4648
{
47-
foreach (var plugin in Plugins.Values)
49+
foreach (var plugin in _plugins.Values)
4850
plugin.Update();
4951
}
5052

@@ -53,10 +55,10 @@ public void UpdatePlugins()
5355
/// </summary>
5456
public override void Detach()
5557
{
56-
foreach (var plugin in Plugins.Values)
58+
foreach (var plugin in _plugins.Values)
5759
plugin.Dispose();
5860

59-
Plugins.Clear();
61+
_plugins.Clear();
6062
}
6163

6264
public void LoadPlugins()
@@ -75,9 +77,9 @@ public void LoadPlugins()
7577
continue;
7678
}
7779

78-
if (Plugins.ContainsKey(manifest.Guid))
80+
if (_plugins.ContainsKey(manifest.Guid))
7981
{
80-
_log.Error($"The GUID provided by {manifest.Name} ({item}) is already in use by {Plugins[manifest.Guid].Name}");
82+
_log.Error($"The GUID provided by {manifest.Name} ({item}) is already in use by {_plugins[manifest.Guid].Name}");
8183
continue;
8284
}
8385

@@ -87,9 +89,9 @@ public void LoadPlugins()
8789
LoadPluginFromFolder(path);
8890
}
8991

90-
Plugins.ForEach(x => x.Value.Init(Torch));
91-
_log.Info($"Loaded {Plugins.Count} plugins.");
92-
PluginsLoaded?.Invoke(Plugins.Values);
92+
_plugins.ForEach(x => x.Value.Init(Torch));
93+
_log.Info($"Loaded {_plugins.Count} plugins.");
94+
PluginsLoaded?.Invoke(_plugins.Values.AsReadOnly());
9395
}
9496

9597
private void DownloadPluginUpdates()
@@ -307,14 +309,14 @@ private void InstantiatePlugin(PluginManifest manifest, IEnumerable<Assembly> as
307309
plugin.Manifest = manifest;
308310
plugin.StoragePath = Torch.Config.InstancePath;
309311
plugin.Torch = Torch;
310-
Plugins.Add(manifest.Guid, plugin);
312+
_plugins.Add(manifest.Guid, plugin);
311313
_commandManager.RegisterPluginCommands(plugin);
312314
}
313315

314316
/// <inheritdoc cref="IEnumerable.GetEnumerator"/>
315317
public IEnumerator<ITorchPlugin> GetEnumerator()
316318
{
317-
return Plugins.Values.GetEnumerator();
319+
return _plugins.Values.GetEnumerator();
318320
}
319321

320322
IEnumerator IEnumerable.GetEnumerator()

‎Torch/Torch.csproj‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@
157157
<Compile Include="ChatMessage.cs" />
158158
<Compile Include="Collections\ObservableList.cs" />
159159
<Compile Include="Extensions\DispatcherExtensions.cs" />
160+
<Compile Include="Extensions\ICollectionExtensions.cs" />
160161
<Compile Include="Managers\DependencyManager.cs" />
161162
<Compile Include="Managers\PatchManager\AssemblyMemory.cs" />
162163
<Compile Include="Managers\PatchManager\DecoratedMethod.cs" />

0 commit comments

Comments
 (0)