Skip to content

Commit 0574d59

Browse files
committed
Merge branch 'staging' into session-mgr-cmp
2 parents 205dd1a + 4f7c35d commit 0574d59

20 files changed

Lines changed: 672 additions & 189 deletions

‎Jenkinsfile‎

Lines changed: 37 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,21 @@
1+
def packageAndArchive(buildMode, packageName, exclude) {
2+
zipFile = "bin\\${packageName}.zip"
3+
packageDir = "bin\\${packageName}\\"
4+
5+
bat "IF EXIST ${zipFile} DEL ${zipFile}"
6+
bat "IF EXIST ${packageDir} RMDIR /S /Q ${packageDir}"
7+
8+
bat "xcopy bin\\x64\\${buildMode} ${packageDir}"
9+
if (exclude.length() > 0) {
10+
bat "del ${packageDir}${exclude}"
11+
}
12+
if (buildMode == "Release") {
13+
bat "del ${packageDir}*.pdb"
14+
}
15+
powershell "Add-Type -Assembly System.IO.Compression.FileSystem; [System.IO.Compression.ZipFile]::CreateFromDirectory(\"\$PWD\\${packageDir}\", \"\$PWD\\${zipFile}\")"
16+
archiveArtifacts artifacts: zipFile, caseSensitive: false, onlyIfSuccessful: true
17+
}
18+
119
node {
220
stage('Checkout') {
321
checkout scm
@@ -16,12 +34,18 @@ node {
1634

1735
stage('Build') {
1836
currentBuild.description = bat(returnStdout: true, script: '@powershell -File Versioning/version.ps1').trim()
19-
bat "\"${tool 'MSBuild'}msbuild\" Torch.sln /p:Configuration=Release /p:Platform=x64"
37+
if (env.BRANCH_NAME == "master") {
38+
buildMode = "Release"
39+
} else {
40+
buildMode = "Debug"
41+
}
42+
bat "\"${tool 'MSBuild'}msbuild\" Torch.sln /p:Configuration=${buildMode} /p:Platform=x64 /t:Clean"
43+
bat "\"${tool 'MSBuild'}msbuild\" Torch.sln /p:Configuration=${buildMode} /p:Platform=x64"
2044
}
2145

2246
stage('Test') {
2347
bat 'IF NOT EXIST reports MKDIR reports'
24-
bat "\"packages/xunit.runner.console.2.2.0/tools/xunit.console.exe\" \"bin-test/x64/Release/Torch.Tests.dll\" \"bin-test/x64/Release/Torch.Server.Tests.dll\" \"bin-test/x64/Release/Torch.Client.Tests.dll\" -parallel none -xml \"reports/Torch.Tests.xml\""
48+
bat "\"packages/xunit.runner.console.2.2.0/tools/xunit.console.exe\" \"bin-test/x64/${buildMode}/Torch.Tests.dll\" \"bin-test/x64/${buildMode}/Torch.Server.Tests.dll\" \"bin-test/x64/${buildMode}/Torch.Client.Tests.dll\" -parallel none -xml \"reports/Torch.Tests.xml\""
2549
step([
2650
$class: 'XUnitBuilder',
2751
thresholdMode: 1,
@@ -38,29 +62,21 @@ node {
3862
}
3963

4064
stage('Archive') {
41-
bat '''IF EXIST bin\\torch-server.zip DEL bin\\torch-server.zip
42-
IF EXIST bin\\package-server RMDIR /S /Q bin\\package-server
43-
xcopy bin\\x64\\Release bin\\package-server\\
44-
del bin\\package-server\\Torch.Client*'''
45-
bat "powershell -Command \"Add-Type -Assembly System.IO.Compression.FileSystem; [System.IO.Compression.ZipFile]::CreateFromDirectory(\\\"\$PWD\\bin\\package-server\\\", \\\"\$PWD\\bin\\torch-server.zip\\\")\""
46-
archiveArtifacts artifacts: 'bin/torch-server.zip', caseSensitive: false, onlyIfSuccessful: true
65+
archiveArtifacts artifacts: "bin/x64/${buildMode}/Torch*", caseSensitive: false, fingerprint: true, onlyIfSuccessful: true
4766

48-
bat '''IF EXIST bin\\torch-client.zip DEL bin\\torch-client.zip
49-
IF EXIST bin\\package-client RMDIR /S /Q bin\\package-client
50-
xcopy bin\\x64\\Release bin\\package-client\\
51-
del bin\\package-client\\Torch.Server*'''
52-
bat "powershell -Command \"Add-Type -Assembly System.IO.Compression.FileSystem; [System.IO.Compression.ZipFile]::CreateFromDirectory(\\\"\$PWD\\bin\\package-client\\\", \\\"\$PWD\\bin\\torch-client.zip\\\")\""
53-
archiveArtifacts artifacts: 'bin/torch-client.zip', caseSensitive: false, onlyIfSuccessful: true
67+
packageAndArchive(buildMode, "torch-server", "Torch.Client*")
5468

55-
archiveArtifacts artifacts: 'bin/x64/Release/Torch*', caseSensitive: false, fingerprint: true, onlyIfSuccessful: true
69+
packageAndArchive(buildMode, "torch-client", "Torch.Server*")
5670
}
5771

58-
gitVersion = bat(returnStdout: true, script: "@git describe --tags").trim()
59-
gitSimpleVersion = bat(returnStdout: true, script: "@git describe --tags --abbrev=0").trim()
60-
if (gitVersion == gitSimpleVersion) {
61-
stage('Release') {
62-
withCredentials([usernamePassword(credentialsId: 'torch-github', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]) {
63-
powershell "& ./Jenkins/release.ps1 \"https://api.github.com/repos/TorchAPI/Torch/\" \"$gitSimpleVersion\" \"$USERNAME:$PASSWORD\" @(\"bin/torch-server.zip\", \"bin/torch-client.zip\")"
72+
if (env.BRANCH_NAME == "master") {
73+
gitVersion = bat(returnStdout: true, script: "@git describe --tags").trim()
74+
gitSimpleVersion = bat(returnStdout: true, script: "@git describe --tags --abbrev=0").trim()
75+
if (gitVersion == gitSimpleVersion) {
76+
stage('${buildMode}') {
77+
withCredentials([usernamePassword(credentialsId: 'torch-github', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]) {
78+
powershell "& ./Jenkins/${buildMode}.ps1 \"https://api.github.com/repos/TorchAPI/Torch/\" \"$gitSimpleVersion\" \"$USERNAME:$PASSWORD\" @(\"bin/torch-server.zip\", \"bin/torch-client.zip\")"
79+
}
6480
}
6581
}
6682
}

‎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<IList<ITorchPlugin>> PluginsLoaded;
17+
event Action<IReadOnlyCollection<ITorchPlugin>> PluginsLoaded;
1818

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

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

‎Torch.API/Plugins/ITorchPlugin.cs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public interface ITorchPlugin : IDisposable
1717
/// <summary>
1818
/// The version of the plugin.
1919
/// </summary>
20-
Version Version { get; }
20+
string Version { get; }
2121

2222
/// <summary>
2323
/// The name of the plugin.

‎Torch.API/Plugins/PluginAttribute.cs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ namespace Torch.API.Plugins
1010
/// <summary>
1111
/// Indicates that the given type should be loaded by the plugin manager as a plugin.
1212
/// </summary>
13+
[Obsolete("All plugin meta-information is now defined in the manifest.xml.")]
1314
[AttributeUsage(AttributeTargets.Class)]
1415
public class PluginAttribute : Attribute
1516
{

‎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(IList<ITorchPlugin> obj)
32+
private void PluginManager_PluginsLoaded(IReadOnlyCollection<ITorchPlugin> obj)
3333
{
3434
Plugins.Clear();
3535
foreach (var plugin in obj)

‎Torch.Server/Views/PluginsControl.xaml‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
</UserControl.DataContext>
1313
<Grid>
1414
<Grid.ColumnDefinitions>
15-
<ColumnDefinition Width="150"/>
15+
<ColumnDefinition Width="200"/>
1616
<ColumnDefinition/>
1717
</Grid.ColumnDefinitions>
1818
<Grid Grid.Column="0">
@@ -27,7 +27,7 @@
2727
</DataTemplate>
2828
</ListView.ItemTemplate>
2929
</ListView>
30-
<Button Grid.Row="1" Content="Open Folder" Margin="3" DockPanel.Dock="Bottom" IsEnabled="false"/>
30+
<Button Grid.Row="1" Content="Open Folder" Margin="3" DockPanel.Dock="Bottom" Click="OpenFolder_OnClick"/>
3131
</Grid>
3232
<Frame Grid.Column="1" NavigationUIVisibility="Hidden" Content="{Binding SelectedPlugin.Control}"/>
3333
</Grid>

‎Torch.Server/Views/PluginsControl.xaml.cs‎

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Collections.ObjectModel;
4+
using System.Diagnostics;
45
using System.Linq;
56
using System.Text;
67
using System.Threading.Tasks;
@@ -15,6 +16,8 @@
1516
using System.Windows.Shapes;
1617
using NLog;
1718
using Torch.API;
19+
using Torch.API.Managers;
20+
using Torch.Managers;
1821
using Torch.Server.ViewModels;
1922

2023
namespace Torch.Server.Views
@@ -24,15 +27,25 @@ namespace Torch.Server.Views
2427
/// </summary>
2528
public partial class PluginsControl : UserControl
2629
{
30+
private ITorchServer _server;
31+
private PluginManager _plugins;
32+
2733
public PluginsControl()
2834
{
2935
InitializeComponent();
3036
}
3137

3238
public void BindServer(ITorchServer server)
3339
{
34-
var pluginManager = new PluginManagerViewModel(server.Plugins);
40+
_server = server;
41+
_plugins = _server.Managers.GetManager<PluginManager>();
42+
var pluginManager = new PluginManagerViewModel(_plugins);
3543
DataContext = pluginManager;
3644
}
45+
46+
private void OpenFolder_OnClick(object sender, RoutedEventArgs e)
47+
{
48+
Process.Start("explorer.exe", _plugins.PluginDir);
49+
}
3750
}
3851
}
Lines changed: 128 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,159 @@
11
���using System;
2+
using System.Collections;
23
using System.Collections.Generic;
34
using System.Collections.Specialized;
45
using System.ComponentModel;
56
using System.Linq;
7+
using System.Runtime.CompilerServices;
68
using System.Text;
79
using System.Threading.Tasks;
810
using System.Windows.Threading;
911

1012
namespace Torch.Collections
1113
{
1214
[Serializable]
13-
public class ObservableDictionary<TKey, TValue> : Dictionary<TKey, TValue>, INotifyCollectionChanged, INotifyPropertyChanged
15+
public class ObservableDictionary<TKey, TValue> : ViewModel, IDictionary<TKey, TValue>, INotifyCollectionChanged
1416
{
17+
private IDictionary<TKey, TValue> _internalDict;
18+
19+
public ObservableDictionary()
20+
{
21+
_internalDict = new Dictionary<TKey, TValue>();
22+
}
23+
24+
public ObservableDictionary(IDictionary<TKey, TValue> dictionary)
25+
{
26+
_internalDict = new Dictionary<TKey, TValue>(dictionary);
27+
}
28+
29+
/// <summary>
30+
/// Create a <see cref="ObservableDictionary{TKey,TValue}"/> using the given dictionary by reference. The original dictionary should not be used after calling this.
31+
/// </summary>
32+
public static ObservableDictionary<TKey, TValue> ByReference(IDictionary<TKey, TValue> dictionary)
33+
{
34+
return new ObservableDictionary<TKey, TValue>
35+
{
36+
_internalDict = dictionary
37+
};
38+
}
39+
40+
/// <inheritdoc />
41+
public event NotifyCollectionChangedEventHandler CollectionChanged;
42+
43+
/// <inheritdoc />
44+
public event PropertyChangedEventHandler PropertyChanged;
45+
46+
/// <inheritdoc />
47+
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
48+
{
49+
return _internalDict.GetEnumerator();
50+
}
51+
52+
/// <inheritdoc />
53+
IEnumerator IEnumerable.GetEnumerator()
54+
{
55+
return ((IEnumerable)_internalDict).GetEnumerator();
56+
}
57+
1558
/// <inheritdoc />
16-
public new void Add(TKey key, TValue value)
59+
public void Add(KeyValuePair<TKey, TValue> item)
1760
{
18-
base.Add(key, value);
61+
Add(item.Key, item.Value);
62+
}
63+
64+
/// <inheritdoc />
65+
public bool Remove(KeyValuePair<TKey, TValue> item)
66+
{
67+
return Remove(item.Key);
68+
}
69+
70+
/// <inheritdoc />
71+
public void Clear()
72+
{
73+
_internalDict.Clear();
74+
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
75+
OnPropertyChanged(nameof(Count));
76+
}
77+
78+
/// <inheritdoc />
79+
public bool Contains(KeyValuePair<TKey, TValue> item)
80+
{
81+
return _internalDict.Contains(item);
82+
}
83+
84+
/// <inheritdoc />
85+
public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
86+
{
87+
foreach (var kv in _internalDict)
88+
{
89+
array[arrayIndex] = kv;
90+
arrayIndex++;
91+
}
92+
}
93+
94+
/// <inheritdoc />
95+
public int Count => _internalDict.Count;
96+
97+
/// <inheritdoc />
98+
public bool IsReadOnly => false;
99+
100+
/// <inheritdoc />
101+
public bool ContainsKey(TKey key)
102+
{
103+
return _internalDict.ContainsKey(key);
104+
}
105+
106+
/// <inheritdoc />
107+
public void Add(TKey key, TValue value)
108+
{
109+
_internalDict.Add(key, value);
19110
var kv = new KeyValuePair<TKey, TValue>(key, value);
20111
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, kv));
112+
OnPropertyChanged(nameof(Count));
21113
}
22114

23115
/// <inheritdoc />
24-
public new bool Remove(TKey key)
116+
public bool Remove(TKey key)
25117
{
26-
if (!ContainsKey(key))
118+
if (!_internalDict.ContainsKey(key))
27119
return false;
28120

29121
var kv = new KeyValuePair<TKey, TValue>(key, this[key]);
30-
base.Remove(key);
122+
if (!_internalDict.Remove(key))
123+
return false;
124+
31125
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, kv));
126+
OnPropertyChanged(nameof(Count));
32127
return true;
33128
}
34129

130+
/// <inheritdoc />
131+
public bool TryGetValue(TKey key, out TValue value)
132+
{
133+
return _internalDict.TryGetValue(key, out value);
134+
}
135+
136+
/// <inheritdoc />
137+
public TValue this[TKey key]
138+
{
139+
get => _internalDict[key];
140+
set
141+
{
142+
var oldKv = new KeyValuePair<TKey, TValue>(key, _internalDict[key]);
143+
var newKv = new KeyValuePair<TKey, TValue>(key, value);
144+
_internalDict[key] = value;
145+
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, newKv, oldKv));
146+
}
147+
148+
149+
}
150+
151+
/// <inheritdoc />
152+
public ICollection<TKey> Keys => _internalDict.Keys;
153+
154+
/// <inheritdoc />
155+
public ICollection<TValue> Values => _internalDict.Values;
156+
35157
private void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
36158
{
37159
NotifyCollectionChangedEventHandler collectionChanged = CollectionChanged;
@@ -52,12 +174,5 @@ private void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
52174
nh.Invoke(this, e);
53175
}
54176
}
55-
56-
57-
/// <inheritdoc />
58-
public event NotifyCollectionChangedEventHandler CollectionChanged;
59-
60-
/// <inheritdoc />
61-
public event PropertyChangedEventHandler PropertyChanged;
62177
}
63178
}

‎Torch/Commands/TorchCommands.cs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ public void Version()
106106
[Permission(MyPromoteLevel.None)]
107107
public void Plugins()
108108
{
109-
var plugins = Context.Torch.Managers.GetManager<PluginManager>()?.Plugins.Select(p => p.Name) ?? Enumerable.Empty<string>();
109+
var plugins = Context.Torch.Managers.GetManager<PluginManager>()?.Plugins.Select(p => p.Value.Name) ?? Enumerable.Empty<string>();
110110
Context.Respond($"Loaded plugins: {string.Join(", ", plugins)}");
111111
}
112112

0 commit comments

Comments
 (0)