Merge branch 'release/1.4'
15
PettingZoo.Benchmark/PettingZoo.Benchmark.csproj
Normal file
@ -0,0 +1,15 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="BenchmarkDotNet" Version="0.14.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
138
PettingZoo.Benchmark/Program.cs
Normal file
@ -0,0 +1,138 @@
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using BenchmarkDotNet.Attributes;
|
||||
using BenchmarkDotNet.Running;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace PettingZoo.Benchmark
|
||||
{
|
||||
/*
|
||||
|
||||
|
||||
Small JSON
|
||||
|
||||
|
||||
| Method | Mean | Error | StdDev | Gen 0 | Allocated |
|
||||
|----------------- |----------:|----------:|----------:|-------:|----------:|
|
||||
| TestJsonConvert | 13.226 us | 0.1808 us | 0.1603 us | 3.6316 | 15 KB |
|
||||
| TestJTokenParse | 12.360 us | 0.2453 us | 0.5010 us | 3.6011 | 15 KB |
|
||||
| TestReaderWriter | 6.398 us | 0.1260 us | 0.1294 us | 2.0294 | 8 KB |
|
||||
| TestJsonDocument | 4.400 us | 0.0758 us | 0.0902 us | 2.1019 | 9 KB |
|
||||
|
||||
|
||||
|
||||
Large JSON (25 MB)
|
||||
|
||||
| Method | Mean | Error | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
|
||||
|----------------- |-----------:|---------:|---------:|-----------:|-----------:|----------:|----------:|
|
||||
| TestJsonConvert | 1,331.6 ms | 20.36 ms | 19.05 ms | 57000.0000 | 21000.0000 | 3000.0000 | 390 MB |
|
||||
| TestJTokenParse | 1,411.0 ms | 27.28 ms | 24.18 ms | 62000.0000 | 23000.0000 | 4000.0000 | 415 MB |
|
||||
| TestReaderWriter | 298.6 ms | 5.89 ms | 9.34 ms | 25000.0000 | 8000.0000 | 2000.0000 | 199 MB |
|
||||
| TestJsonDocument | 278.5 ms | 5.29 ms | 6.30 ms | - | - | - | 246 MB |
|
||||
|
||||
|
||||
*/
|
||||
[MemoryDiagnoser]
|
||||
public class JsonPrettyPrint
|
||||
{
|
||||
// Small Json file, which is likely to be typical for most RabbitMQ messages.
|
||||
private const string Json = "{\"glossary\":{\"title\":\"example glossary\",\"GlossDiv\":{\"title\":\"S\",\"GlossList\":{\"GlossEntry\":{\"ID\":\"SGML\",\"SortAs\":\"SGML\",\"GlossTerm\":\"Standard Generalized Markup Language\",\"Acronym\":\"SGML\",\"Abbrev\":\"ISO 8879:1986\",\"GlossDef\":{\"para\":\"A meta-markup language, used to create markup languages such as DocBook.\",\"GlossSeeAlso\":[\"GML\",\"XML\"]},\"GlossSee\":\"markup\"}}}}}";
|
||||
|
||||
// To test with a large file instead, specify the file name here.
|
||||
// For example, I've benchmarked it with this 25 MB JSON file: https://raw.githubusercontent.com/json-iterator/test-data/master/large-file.json
|
||||
//private const string JsonFilename = "";
|
||||
private const string JsonFilename = "D:\\Temp\\large-file.json";
|
||||
|
||||
|
||||
private readonly string testJson;
|
||||
|
||||
|
||||
public JsonPrettyPrint()
|
||||
{
|
||||
testJson = string.IsNullOrEmpty(JsonFilename)
|
||||
? Json
|
||||
: File.ReadAllText(JsonFilename);
|
||||
}
|
||||
|
||||
|
||||
[Benchmark]
|
||||
public string TestJsonConvert()
|
||||
{
|
||||
var obj = JsonConvert.DeserializeObject(testJson);
|
||||
return JsonConvert.SerializeObject(obj, Formatting.Indented);
|
||||
}
|
||||
|
||||
|
||||
[Benchmark]
|
||||
public string TestJTokenParse()
|
||||
{
|
||||
var obj = JToken.Parse(testJson);
|
||||
return obj.ToString(Formatting.Indented);
|
||||
}
|
||||
|
||||
|
||||
[Benchmark]
|
||||
public string TestReaderWriter()
|
||||
{
|
||||
using var stringReader = new StringReader(testJson);
|
||||
using var jsonTextReader = new JsonTextReader(stringReader);
|
||||
using var stringWriter = new StringWriter();
|
||||
using var jsonWriter = new JsonTextWriter(stringWriter);
|
||||
|
||||
jsonWriter.Formatting = Formatting.Indented;
|
||||
|
||||
while (jsonTextReader.Read())
|
||||
jsonWriter.WriteToken(jsonTextReader);
|
||||
|
||||
jsonWriter.Flush();
|
||||
return stringWriter.ToString();
|
||||
}
|
||||
|
||||
|
||||
[Benchmark]
|
||||
public string TestJsonDocument()
|
||||
{
|
||||
var doc = JsonDocument.Parse(testJson);
|
||||
|
||||
using var stream = new MemoryStream();
|
||||
var writer = new Utf8JsonWriter(stream, new JsonWriterOptions { Indented = true });
|
||||
doc.WriteTo(writer);
|
||||
writer.Flush();
|
||||
|
||||
return Encoding.UTF8.GetString(stream.ToArray());
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public class Program
|
||||
{
|
||||
public static void Main()
|
||||
{
|
||||
BenchmarkRunner.Run<JsonPrettyPrint>();
|
||||
|
||||
// To prove they all provide the correct output
|
||||
/*
|
||||
var prettyPrint = new JsonPrettyPrint();
|
||||
Console.WriteLine("JsonConvert");
|
||||
Console.WriteLine("-----------");
|
||||
Console.WriteLine(prettyPrint.TestJsonConvert());
|
||||
|
||||
Console.WriteLine("JToken");
|
||||
Console.WriteLine("------");
|
||||
Console.WriteLine(prettyPrint.TestJTokenParse());
|
||||
|
||||
Console.WriteLine("ReaderWriter");
|
||||
Console.WriteLine("------------");
|
||||
Console.WriteLine(prettyPrint.TestReaderWriter());
|
||||
|
||||
Console.WriteLine("JsonDocument");
|
||||
Console.WriteLine("------------");
|
||||
Console.WriteLine(prettyPrint.TestJsonDocument());
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
@ -17,5 +17,11 @@
|
||||
Username = username;
|
||||
Password = password;
|
||||
}
|
||||
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{Host}:{Port}{VirtualHost}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
100
PettingZoo.Core/Connection/DynamicConnection.cs
Normal file
@ -0,0 +1,100 @@
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace PettingZoo.Core.Connection
|
||||
{
|
||||
public class DynamicConnection : IConnection
|
||||
{
|
||||
public Guid ConnectionId => currentConnection?.ConnectionId ?? Guid.Empty;
|
||||
public ConnectionParams? ConnectionParams { get; private set; }
|
||||
public ConnectionStatus Status { get; private set; } = ConnectionStatus.Disconnected;
|
||||
public event EventHandler<StatusChangedEventArgs>? StatusChanged;
|
||||
|
||||
|
||||
private IConnection? currentConnection;
|
||||
|
||||
|
||||
public async ValueTask DisposeAsync()
|
||||
{
|
||||
if (currentConnection != null)
|
||||
await currentConnection.DisposeAsync();
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
|
||||
public void Connect()
|
||||
{
|
||||
CheckConnection();
|
||||
currentConnection.Connect();
|
||||
|
||||
}
|
||||
|
||||
public async ValueTask Disconnect()
|
||||
{
|
||||
if (currentConnection == null)
|
||||
return;
|
||||
|
||||
var disconnectedConnectionId = currentConnection.ConnectionId;
|
||||
await currentConnection.DisposeAsync();
|
||||
currentConnection = null;
|
||||
|
||||
ConnectionStatusChanged(this, new StatusChangedEventArgs(disconnectedConnectionId, ConnectionStatus.Disconnected));
|
||||
}
|
||||
|
||||
|
||||
public void SetConnection(IConnection connection)
|
||||
{
|
||||
if (currentConnection != null)
|
||||
{
|
||||
currentConnection.StatusChanged -= ConnectionStatusChanged;
|
||||
ConnectionStatusChanged(this, new StatusChangedEventArgs(currentConnection.ConnectionId, ConnectionStatus.Disconnected));
|
||||
}
|
||||
|
||||
currentConnection = connection;
|
||||
|
||||
// Assume we get the new connection before Connect is called, thus before the status changes
|
||||
if (currentConnection != null)
|
||||
currentConnection.StatusChanged += ConnectionStatusChanged;
|
||||
}
|
||||
|
||||
|
||||
public ISubscriber Subscribe(string exchange, string routingKey)
|
||||
{
|
||||
CheckConnection();
|
||||
return currentConnection.Subscribe(exchange, routingKey);
|
||||
}
|
||||
|
||||
|
||||
public ISubscriber Subscribe()
|
||||
{
|
||||
CheckConnection();
|
||||
return currentConnection.Subscribe();
|
||||
}
|
||||
|
||||
|
||||
public Task Publish(PublishMessageInfo messageInfo)
|
||||
{
|
||||
CheckConnection();
|
||||
return currentConnection.Publish(messageInfo);
|
||||
}
|
||||
|
||||
|
||||
private void ConnectionStatusChanged(object? sender, StatusChangedEventArgs e)
|
||||
{
|
||||
ConnectionParams = e.ConnectionParams;
|
||||
Status = e.Status;
|
||||
|
||||
StatusChanged?.Invoke(sender, e);
|
||||
}
|
||||
|
||||
|
||||
[MemberNotNull(nameof(currentConnection))]
|
||||
private void CheckConnection()
|
||||
{
|
||||
if (currentConnection == null)
|
||||
throw new InvalidOperationException("No current connection");
|
||||
}
|
||||
}
|
||||
}
|
@ -5,8 +5,15 @@ namespace PettingZoo.Core.Connection
|
||||
{
|
||||
public interface IConnection : IAsyncDisposable
|
||||
{
|
||||
Guid ConnectionId { get; }
|
||||
ConnectionParams? ConnectionParams { get; }
|
||||
ConnectionStatus Status { get; }
|
||||
|
||||
event EventHandler<StatusChangedEventArgs> StatusChanged;
|
||||
|
||||
|
||||
void Connect();
|
||||
|
||||
ISubscriber Subscribe(string exchange, string routingKey);
|
||||
ISubscriber Subscribe();
|
||||
|
||||
@ -25,14 +32,18 @@ namespace PettingZoo.Core.Connection
|
||||
|
||||
public class StatusChangedEventArgs : EventArgs
|
||||
{
|
||||
public Guid ConnectionId { get; }
|
||||
public ConnectionStatus Status { get; }
|
||||
public string? Context { get; }
|
||||
public ConnectionParams? ConnectionParams { get; }
|
||||
public Exception? Exception { get; }
|
||||
|
||||
|
||||
public StatusChangedEventArgs(ConnectionStatus status, string? context)
|
||||
public StatusChangedEventArgs(Guid connectionId, ConnectionStatus status, ConnectionParams? connectionParams = null, Exception? exception = null)
|
||||
{
|
||||
ConnectionId = connectionId;
|
||||
Status = status;
|
||||
Context = context;
|
||||
ConnectionParams = connectionParams;
|
||||
Exception = exception;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
201
PettingZoo.Core/ExportImport/Publisher/PublisherMessage.cs
Normal file
@ -0,0 +1,201 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using PettingZoo.Core.Connection;
|
||||
|
||||
namespace PettingZoo.Core.ExportImport.Publisher
|
||||
{
|
||||
public enum PublisherMessageType
|
||||
{
|
||||
Raw,
|
||||
Tapeti
|
||||
}
|
||||
|
||||
|
||||
|
||||
public class PublisherMessage : IEquatable<PublisherMessage>
|
||||
{
|
||||
public PublisherMessageType MessageType { get; init; }
|
||||
public bool SendToExchange { get; init; }
|
||||
public string? Exchange { get; init; }
|
||||
public string? RoutingKey { get; init; }
|
||||
public string? Queue { get; init; }
|
||||
public bool ReplyToNewSubscriber { get; init; }
|
||||
public string? ReplyTo { get; init; }
|
||||
|
||||
public RawPublisherMessage? RawPublisherMessage { get; init; }
|
||||
public TapetiPublisherMessage? TapetiPublisherMessage { get; init; }
|
||||
|
||||
|
||||
public bool Equals(PublisherMessage? other)
|
||||
{
|
||||
if (other == null) return false;
|
||||
if (ReferenceEquals(this, other)) return true;
|
||||
|
||||
return MessageType == other.MessageType &&
|
||||
SendToExchange == other.SendToExchange &&
|
||||
Exchange == other.Exchange &&
|
||||
RoutingKey == other.RoutingKey &&
|
||||
Queue == other.Queue &&
|
||||
ReplyToNewSubscriber == other.ReplyToNewSubscriber &&
|
||||
ReplyTo == other.ReplyTo &&
|
||||
Equals(RawPublisherMessage, other.RawPublisherMessage) &&
|
||||
Equals(TapetiPublisherMessage, other.TapetiPublisherMessage);
|
||||
}
|
||||
|
||||
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
if (obj == null) return false;
|
||||
if (ReferenceEquals(this, obj)) return true;
|
||||
|
||||
return obj is PublisherMessage publisherMessage && Equals(publisherMessage);
|
||||
}
|
||||
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
var hashCode = new HashCode();
|
||||
hashCode.Add((int)MessageType);
|
||||
hashCode.Add(SendToExchange);
|
||||
hashCode.Add(Exchange);
|
||||
hashCode.Add(RoutingKey);
|
||||
hashCode.Add(Queue);
|
||||
hashCode.Add(ReplyToNewSubscriber);
|
||||
hashCode.Add(ReplyTo);
|
||||
hashCode.Add(RawPublisherMessage);
|
||||
hashCode.Add(TapetiPublisherMessage);
|
||||
return hashCode.ToHashCode();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class RawPublisherMessage : IEquatable<RawPublisherMessage>
|
||||
{
|
||||
public MessageDeliveryMode DeliveryMode { get; init; }
|
||||
|
||||
public string? ContentType { get; init; }
|
||||
public string? CorrelationId { get; init; }
|
||||
public string? AppId { get; init; }
|
||||
public string? ContentEncoding { get; init; }
|
||||
public string? Expiration { get; init; }
|
||||
public string? MessageId { get; init; }
|
||||
public string? Priority { get; init; }
|
||||
public string? Timestamp { get; init; }
|
||||
public string? TypeProperty { get; init; }
|
||||
public string? UserId { get; init; }
|
||||
public string? Payload { get; init; }
|
||||
public bool EnableMacros { get; init; }
|
||||
|
||||
public Dictionary<string, string>? Headers { get; init; }
|
||||
|
||||
|
||||
public bool Equals(RawPublisherMessage? other)
|
||||
{
|
||||
if (other == null) return false;
|
||||
if (ReferenceEquals(this, other)) return true;
|
||||
|
||||
return DeliveryMode == other.DeliveryMode &&
|
||||
ContentType == other.ContentType &&
|
||||
CorrelationId == other.CorrelationId &&
|
||||
AppId == other.AppId &&
|
||||
ContentEncoding == other.ContentEncoding &&
|
||||
Expiration == other.Expiration &&
|
||||
MessageId == other.MessageId &&
|
||||
Priority == other.Priority &&
|
||||
Timestamp == other.Timestamp &&
|
||||
TypeProperty == other.TypeProperty &&
|
||||
UserId == other.UserId &&
|
||||
Payload == other.Payload &&
|
||||
EnableMacros == other.EnableMacros &&
|
||||
HeadersEquals(other.Headers);
|
||||
}
|
||||
|
||||
|
||||
private bool HeadersEquals(Dictionary<string, string>? other)
|
||||
{
|
||||
if (other == null)
|
||||
return Headers == null || Headers.Count == 0;
|
||||
|
||||
if (Headers == null)
|
||||
return other.Count == 0;
|
||||
|
||||
return other.OrderBy(h => h.Key).SequenceEqual(Headers.OrderBy(h => h.Key));
|
||||
}
|
||||
|
||||
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
if (obj == null) return false;
|
||||
if (ReferenceEquals(this, obj)) return true;
|
||||
|
||||
return obj is RawPublisherMessage rawPublisherMessage && Equals(rawPublisherMessage);
|
||||
}
|
||||
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
var hashCode = new HashCode();
|
||||
hashCode.Add((int)DeliveryMode);
|
||||
hashCode.Add(ContentType);
|
||||
hashCode.Add(CorrelationId);
|
||||
hashCode.Add(AppId);
|
||||
hashCode.Add(ContentEncoding);
|
||||
hashCode.Add(Expiration);
|
||||
hashCode.Add(MessageId);
|
||||
hashCode.Add(Priority);
|
||||
hashCode.Add(Timestamp);
|
||||
hashCode.Add(TypeProperty);
|
||||
hashCode.Add(UserId);
|
||||
hashCode.Add(Payload);
|
||||
hashCode.Add(EnableMacros);
|
||||
|
||||
if (Headers != null)
|
||||
foreach (var (key, value) in Headers)
|
||||
{
|
||||
hashCode.Add(key);
|
||||
hashCode.Add(value);
|
||||
}
|
||||
|
||||
return hashCode.ToHashCode();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class TapetiPublisherMessage : IEquatable<TapetiPublisherMessage>
|
||||
{
|
||||
public string? CorrelationId { get; init; }
|
||||
public string? Payload { get; init; }
|
||||
public bool EnableMacros { get; init; }
|
||||
public string? ClassName { get; init; }
|
||||
public string? AssemblyName { get; init; }
|
||||
|
||||
|
||||
public bool Equals(TapetiPublisherMessage? other)
|
||||
{
|
||||
if (other == null) return false;
|
||||
if (ReferenceEquals(this, other)) return true;
|
||||
|
||||
return CorrelationId == other.CorrelationId &&
|
||||
Payload == other.Payload &&
|
||||
EnableMacros == other.EnableMacros &&
|
||||
ClassName == other.ClassName &&
|
||||
AssemblyName == other.AssemblyName;
|
||||
}
|
||||
|
||||
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
if (obj == null) return false;
|
||||
if (ReferenceEquals(this, obj)) return true;
|
||||
|
||||
return obj is TapetiPublisherMessage tapetiPublisherMessage && Equals(tapetiPublisherMessage);
|
||||
}
|
||||
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return HashCode.Combine(CorrelationId, Payload, EnableMacros, ClassName, AssemblyName);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
using System;
|
||||
|
||||
namespace PettingZoo.Core.ExportImport
|
||||
namespace PettingZoo.Core.ExportImport.Subscriber
|
||||
{
|
||||
public abstract class BaseProgressDecorator
|
||||
{
|
@ -1,7 +1,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace PettingZoo.Core.ExportImport
|
||||
namespace PettingZoo.Core.ExportImport.Subscriber
|
||||
{
|
||||
public class ExportImportFormatProvider : IExportImportFormatProvider
|
||||
{
|
@ -4,7 +4,7 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using PettingZoo.Core.Connection;
|
||||
|
||||
namespace PettingZoo.Core.ExportImport
|
||||
namespace PettingZoo.Core.ExportImport.Subscriber
|
||||
{
|
||||
public interface IExportImportFormat
|
||||
{
|
@ -1,6 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace PettingZoo.Core.ExportImport
|
||||
namespace PettingZoo.Core.ExportImport.Subscriber
|
||||
{
|
||||
public interface IExportImportFormatProvider
|
||||
{
|
@ -3,7 +3,7 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using PettingZoo.Core.Connection;
|
||||
|
||||
namespace PettingZoo.Core.ExportImport
|
||||
namespace PettingZoo.Core.ExportImport.Subscriber
|
||||
{
|
||||
public class ImportSubscriber : ISubscriber
|
||||
{
|
@ -2,7 +2,7 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace PettingZoo.Core.ExportImport
|
||||
namespace PettingZoo.Core.ExportImport.Subscriber
|
||||
{
|
||||
public class ListEnumerableProgressDecorator<T> : BaseProgressDecorator, IEnumerable<T>
|
||||
{
|
@ -3,7 +3,7 @@ using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace PettingZoo.Core.ExportImport
|
||||
namespace PettingZoo.Core.ExportImport.Subscriber
|
||||
{
|
||||
public class StreamProgressDecorator : BaseProgressDecorator
|
||||
{
|
@ -7,8 +7,8 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
<PackageReference Include="Serilog" Version="2.10.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="Serilog" Version="4.1.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
@ -26,8 +27,18 @@ namespace PettingZoo.Core.Rendering
|
||||
var bodyText = Encoding.UTF8.GetString(body);
|
||||
try
|
||||
{
|
||||
var obj = JsonConvert.DeserializeObject(bodyText);
|
||||
return JsonConvert.SerializeObject(obj, Formatting.Indented);
|
||||
using var stringReader = new StringReader(bodyText);
|
||||
using var jsonTextReader = new JsonTextReader(stringReader);
|
||||
using var stringWriter = new StringWriter();
|
||||
using var jsonWriter = new JsonTextWriter(stringWriter);
|
||||
|
||||
jsonWriter.Formatting = Formatting.Indented;
|
||||
|
||||
while (jsonTextReader.Read())
|
||||
jsonWriter.WriteToken(jsonTextReader);
|
||||
|
||||
jsonWriter.Flush();
|
||||
return stringWriter.ToString();
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
33
PettingZoo.Core/Settings/IPublisherMessagesRepository.cs
Normal file
@ -0,0 +1,33 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using PettingZoo.Core.ExportImport.Publisher;
|
||||
|
||||
namespace PettingZoo.Core.Settings
|
||||
{
|
||||
public interface IPublisherMessagesRepository
|
||||
{
|
||||
// For now read everything into memory, you need quite a few and/or huge messsages before that becomes an issue
|
||||
Task<IEnumerable<StoredPublisherMessage>> GetStored();
|
||||
|
||||
Task<StoredPublisherMessage> Add(string displayName, PublisherMessage message);
|
||||
Task<StoredPublisherMessage> Update(Guid id, string displayName, PublisherMessage message);
|
||||
Task Delete(Guid id);
|
||||
}
|
||||
|
||||
|
||||
public class StoredPublisherMessage
|
||||
{
|
||||
public Guid Id { get; }
|
||||
public string DisplayName { get; }
|
||||
public PublisherMessage Message { get; }
|
||||
|
||||
|
||||
public StoredPublisherMessage(Guid id, string displayName, PublisherMessage message)
|
||||
{
|
||||
Id = id;
|
||||
DisplayName = displayName;
|
||||
Message = message;
|
||||
}
|
||||
}
|
||||
}
|
@ -7,9 +7,9 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
<PackageReference Include="RabbitMQ.Client" Version="6.2.2" />
|
||||
<PackageReference Include="Serilog" Version="2.10.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="RabbitMQ.Client" Version="6.5.0" />
|
||||
<PackageReference Include="Serilog" Version="4.1.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -3,51 +3,56 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using PettingZoo.Core.Connection;
|
||||
using RabbitMQ.Client;
|
||||
using IConnection = RabbitMQ.Client.IConnection;
|
||||
|
||||
namespace PettingZoo.RabbitMQ
|
||||
{
|
||||
public class RabbitMQClientConnection : Core.Connection.IConnection
|
||||
{
|
||||
public Guid ConnectionId { get; } = Guid.NewGuid();
|
||||
public ConnectionParams? ConnectionParams { get; }
|
||||
public ConnectionStatus Status { get; set; }
|
||||
public event EventHandler<StatusChangedEventArgs>? StatusChanged;
|
||||
|
||||
|
||||
private const int ConnectRetryDelay = 5000;
|
||||
|
||||
private readonly CancellationTokenSource connectionTaskToken = new();
|
||||
private readonly Task connectionTask;
|
||||
private Task? connectionTask;
|
||||
private readonly object connectionLock = new();
|
||||
private global::RabbitMQ.Client.IConnection? connection;
|
||||
private IModel? model;
|
||||
|
||||
|
||||
public event EventHandler<StatusChangedEventArgs>? StatusChanged;
|
||||
private IConnection? connection;
|
||||
|
||||
|
||||
public RabbitMQClientConnection(ConnectionParams connectionParams)
|
||||
{
|
||||
connectionTask = Task.Factory.StartNew(() => TryConnection(connectionParams, connectionTaskToken.Token), CancellationToken.None);
|
||||
ConnectionParams = connectionParams;
|
||||
}
|
||||
|
||||
|
||||
public async ValueTask DisposeAsync()
|
||||
{
|
||||
GC.SuppressFinalize(this);
|
||||
if (connectionTask == null)
|
||||
return;
|
||||
|
||||
connectionTaskToken.Cancel();
|
||||
if (!connectionTask.IsCompleted)
|
||||
await connectionTask;
|
||||
|
||||
lock (connectionLock)
|
||||
{
|
||||
if (model != null)
|
||||
{
|
||||
model.Dispose();
|
||||
model = null;
|
||||
}
|
||||
|
||||
if (connection != null)
|
||||
{
|
||||
connection.Dispose();
|
||||
connection = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
|
||||
public void Connect()
|
||||
{
|
||||
connectionTask = Task.Factory.StartNew(() => TryConnection(ConnectionParams!, connectionTaskToken.Token), CancellationToken.None);
|
||||
}
|
||||
|
||||
|
||||
@ -67,6 +72,7 @@ namespace PettingZoo.RabbitMQ
|
||||
{
|
||||
lock (connectionLock)
|
||||
{
|
||||
var model = connection?.CreateModel();
|
||||
var subscriber = new RabbitMQClientSubscriber(model, exchange, routingKey);
|
||||
if (model != null)
|
||||
return subscriber;
|
||||
@ -79,10 +85,10 @@ namespace PettingZoo.RabbitMQ
|
||||
|
||||
lock (connectionLock)
|
||||
{
|
||||
if (model == null)
|
||||
if (connection == null)
|
||||
return;
|
||||
|
||||
subscriber.Connected(model);
|
||||
subscriber.Connected(connection.CreateModel());
|
||||
}
|
||||
|
||||
StatusChanged -= ConnectSubscriber;
|
||||
@ -97,12 +103,30 @@ namespace PettingZoo.RabbitMQ
|
||||
|
||||
public Task Publish(PublishMessageInfo messageInfo)
|
||||
{
|
||||
if (model == null)
|
||||
IConnection? lockedConnection;
|
||||
|
||||
lock (connectionLock)
|
||||
{
|
||||
lockedConnection = connection;
|
||||
}
|
||||
|
||||
if (lockedConnection == null)
|
||||
throw new InvalidOperationException("Not connected");
|
||||
|
||||
using (var model = lockedConnection.CreateModel())
|
||||
{
|
||||
try
|
||||
{
|
||||
model.BasicPublish(messageInfo.Exchange, messageInfo.RoutingKey, false,
|
||||
RabbitMQClientPropertiesConverter.Convert(messageInfo.Properties, model.CreateBasicProperties()),
|
||||
RabbitMQClientPropertiesConverter.Convert(messageInfo.Properties,
|
||||
model.CreateBasicProperties()),
|
||||
messageInfo.Body);
|
||||
}
|
||||
finally
|
||||
{
|
||||
model.Close();
|
||||
}
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
@ -119,22 +143,22 @@ namespace PettingZoo.RabbitMQ
|
||||
Password = connectionParams.Password
|
||||
};
|
||||
|
||||
var statusContext = $"{connectionParams.Host}:{connectionParams.Port}{connectionParams.VirtualHost}";
|
||||
|
||||
while (!cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
DoStatusChanged(ConnectionStatus.Connecting, statusContext);
|
||||
DoStatusChanged(ConnectionStatus.Connecting);
|
||||
try
|
||||
{
|
||||
lock (connectionLock)
|
||||
{
|
||||
connection = factory.CreateConnection();
|
||||
model = connection.CreateModel();
|
||||
}
|
||||
|
||||
DoStatusChanged(ConnectionStatus.Connected, statusContext);
|
||||
DoStatusChanged(ConnectionStatus.Connected);
|
||||
break;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
DoStatusChanged(ConnectionStatus.Error, e.Message);
|
||||
DoStatusChanged(ConnectionStatus.Error, e);
|
||||
|
||||
try
|
||||
{
|
||||
@ -148,9 +172,10 @@ namespace PettingZoo.RabbitMQ
|
||||
}
|
||||
|
||||
|
||||
private void DoStatusChanged(ConnectionStatus status, string? context = null)
|
||||
private void DoStatusChanged(ConnectionStatus status, Exception? exception = null)
|
||||
{
|
||||
StatusChanged?.Invoke(this, new StatusChangedEventArgs(status, context));
|
||||
Status = status;
|
||||
StatusChanged?.Invoke(this, new StatusChangedEventArgs(ConnectionId, status, ConnectionParams, exception));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,80 @@
|
||||
using PettingZoo.Core.ExportImport.Publisher;
|
||||
using PettingZoo.Core.Settings;
|
||||
|
||||
namespace PettingZoo.Settings.LiteDB
|
||||
{
|
||||
public class LiteDBPublisherMessagesRepository : BaseLiteDBRepository, IPublisherMessagesRepository
|
||||
{
|
||||
private const string CollectionMessages = "messages";
|
||||
|
||||
|
||||
public LiteDBPublisherMessagesRepository() : base(@"publisherMessages")
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
public async Task<IEnumerable<StoredPublisherMessage>> GetStored()
|
||||
{
|
||||
using var database = GetDatabase();
|
||||
var collection = database.GetCollection<PublisherMessageRecord>(CollectionMessages);
|
||||
|
||||
return (await collection.FindAllAsync())
|
||||
.Select(r => new StoredPublisherMessage(r.Id, r.DisplayName, r.Message))
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
|
||||
public async Task<StoredPublisherMessage> Add(string displayName, PublisherMessage message)
|
||||
{
|
||||
using var database = GetDatabase();
|
||||
var collection = database.GetCollection<PublisherMessageRecord>(CollectionMessages);
|
||||
|
||||
var id = Guid.NewGuid();
|
||||
await collection.InsertAsync(PublisherMessageRecord.FromPublisherMessage(id, displayName, message));
|
||||
|
||||
return new StoredPublisherMessage(id, displayName, message);
|
||||
}
|
||||
|
||||
|
||||
public async Task<StoredPublisherMessage> Update(Guid id, string displayName, PublisherMessage message)
|
||||
{
|
||||
using var database = GetDatabase();
|
||||
var collection = database.GetCollection<PublisherMessageRecord>(CollectionMessages);
|
||||
|
||||
await collection.UpdateAsync(PublisherMessageRecord.FromPublisherMessage(id, displayName, message));
|
||||
return new StoredPublisherMessage(id, displayName, message);
|
||||
}
|
||||
|
||||
|
||||
public async Task Delete(Guid id)
|
||||
{
|
||||
using var database = GetDatabase();
|
||||
var collection = database.GetCollection<PublisherMessageRecord>(CollectionMessages);
|
||||
|
||||
await collection.DeleteAsync(id);
|
||||
}
|
||||
|
||||
|
||||
// ReSharper disable MemberCanBePrivate.Local - for LiteDB
|
||||
// ReSharper disable PropertyCanBeMadeInitOnly.Local
|
||||
private class PublisherMessageRecord
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public string DisplayName { get; set; } = null!;
|
||||
public PublisherMessage Message { get; set; } = null!;
|
||||
|
||||
|
||||
public static PublisherMessageRecord FromPublisherMessage(Guid id, string displayName, PublisherMessage message)
|
||||
{
|
||||
return new PublisherMessageRecord
|
||||
{
|
||||
Id = id,
|
||||
DisplayName = displayName,
|
||||
Message = message
|
||||
};
|
||||
}
|
||||
}
|
||||
// ReSharper restore PropertyCanBeMadeInitOnly.Local
|
||||
// ReSharper restore MemberCanBePrivate.Local
|
||||
}
|
||||
}
|
@ -7,9 +7,9 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="LiteDB" Version="5.0.11" />
|
||||
<PackageReference Include="LiteDB.Async" Version="0.0.11" />
|
||||
<PackageReference Include="Serilog" Version="2.10.0" />
|
||||
<PackageReference Include="LiteDB" Version="5.0.21" />
|
||||
<PackageReference Include="LiteDB.Async" Version="0.1.8" />
|
||||
<PackageReference Include="Serilog" Version="4.1.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -1,8 +1,8 @@
|
||||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PettingZoo.Core.ExportImport;
|
||||
using PettingZoo.Core.ExportImport.Subscriber;
|
||||
|
||||
namespace PettingZoo.Tapeti.Export
|
||||
namespace PettingZoo.Tapeti.ExportImport
|
||||
{
|
||||
public abstract class BaseTapetiCmdExportImportFormat : IExportImportFormat
|
||||
{
|
@ -8,10 +8,9 @@ using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PettingZoo.Core.Connection;
|
||||
using PettingZoo.Core.ExportImport;
|
||||
using PettingZoo.Core.ExportImport.Subscriber;
|
||||
|
||||
|
||||
namespace PettingZoo.Tapeti.Export
|
||||
namespace PettingZoo.Tapeti.ExportImport
|
||||
{
|
||||
public class TapetiCmdExportFormat : BaseTapetiCmdExportImportFormat, IExportFormat
|
||||
{
|
@ -8,7 +8,7 @@
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace PettingZoo.Tapeti.Export {
|
||||
namespace PettingZoo.Tapeti.ExportImport {
|
||||
using System;
|
||||
|
||||
|
||||
@ -39,7 +39,7 @@ namespace PettingZoo.Tapeti.Export {
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("PettingZoo.Tapeti.Export.TapetiCmdImportExportStrings", typeof(TapetiCmdImportExportStrings).Assembly);
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("PettingZoo.Tapeti.ExportImport.TapetiCmdImportExportStrings", typeof(TapetiCmdImportExportStrings).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
@ -7,9 +7,9 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
using PettingZoo.Core.Connection;
|
||||
using PettingZoo.Core.ExportImport;
|
||||
using PettingZoo.Core.ExportImport.Subscriber;
|
||||
|
||||
namespace PettingZoo.Tapeti.Export
|
||||
namespace PettingZoo.Tapeti.ExportImport
|
||||
{
|
||||
public class TapetiCmdImportFormat : BaseTapetiCmdExportImportFormat, IImportFormat
|
||||
{
|
@ -8,18 +8,19 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
<PackageReference Include="NuGet.PackageManagement" Version="6.0.0" />
|
||||
<PackageReference Include="NuGet.Packaging" Version="6.0.0" />
|
||||
<PackageReference Include="NuGet.Protocol" Version="6.0.0" />
|
||||
<PackageReference Include="Serilog" Version="2.10.0" />
|
||||
<PackageReference Include="SharpVectors" Version="1.7.7" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="NuGet.PackageManagement" Version="6.11.1" />
|
||||
<PackageReference Include="NuGet.Packaging" Version="6.11.1" />
|
||||
<PackageReference Include="NuGet.Protocol" Version="6.11.1" />
|
||||
<PackageReference Include="RabbitMQ.Client" Version="6.5.0" />
|
||||
<PackageReference Include="Serilog" Version="4.1.0" />
|
||||
<PackageReference Include="SharpVectors" Version="1.8.4.2" />
|
||||
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
|
||||
<PackageReference Include="System.Reactive" Version="5.0.0" />
|
||||
<PackageReference Include="System.Reflection.MetadataLoadContext" Version="6.0.0" />
|
||||
<PackageReference Include="Tapeti" Version="2.8.2" />
|
||||
<PackageReference Include="Tapeti.Annotations" Version="3.0.0" />
|
||||
<PackageReference Include="Tapeti.DataAnnotations.Extensions" Version="3.0.0" />
|
||||
<PackageReference Include="System.Reactive" Version="6.0.1" />
|
||||
<PackageReference Include="System.Reflection.MetadataLoadContext" Version="8.0.1" />
|
||||
<PackageReference Include="Tapeti" Version="3.1.4" />
|
||||
<PackageReference Include="Tapeti.Annotations" Version="3.1.0" />
|
||||
<PackageReference Include="Tapeti.DataAnnotations.Extensions" Version="3.2.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@ -33,7 +34,7 @@
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>AssemblyParserStrings.resx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Export\TapetiCmdImportExportStrings.Designer.cs">
|
||||
<Compile Update="ExportImport\TapetiCmdImportExportStrings.Designer.cs">
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>TapetiCmdImportExportStrings.resx</DependentUpon>
|
||||
@ -60,7 +61,7 @@
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>AssemblyParserStrings.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Update="Export\TapetiCmdImportExportStrings.resx">
|
||||
<EmbeddedResource Update="ExportImport\TapetiCmdImportExportStrings.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>TapetiCmdImportExportStrings.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
|
@ -1,325 +0,0 @@
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<AssemblyName>PettingZoo.Tapeti</AssemblyName>
|
||||
<IntermediateOutputPath>obj\Debug\</IntermediateOutputPath>
|
||||
<BaseIntermediateOutputPath>obj\</BaseIntermediateOutputPath>
|
||||
<MSBuildProjectExtensionsPath>P:\Development\PettingZoo\PettingZoo.Tapeti\obj\</MSBuildProjectExtensionsPath>
|
||||
<_TargetAssemblyProjectName>PettingZoo.Tapeti</_TargetAssemblyProjectName>
|
||||
</PropertyGroup>
|
||||
<Import Project="Sdk.props" Sdk="Microsoft.NET.Sdk" />
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0-windows</TargetFramework>
|
||||
<Version>0.1</Version>
|
||||
<UseWpf>true</UseWpf>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
<PackageReference Include="NuGet.PackageManagement" Version="6.0.0" />
|
||||
<PackageReference Include="NuGet.Packaging" Version="6.0.0" />
|
||||
<PackageReference Include="NuGet.Protocol" Version="6.0.0" />
|
||||
<PackageReference Include="Serilog" Version="2.10.0" />
|
||||
<PackageReference Include="SharpVectors" Version="1.7.7" />
|
||||
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
|
||||
<PackageReference Include="System.Reactive" Version="5.0.0" />
|
||||
<PackageReference Include="System.Reflection.MetadataLoadContext" Version="6.0.0" />
|
||||
<PackageReference Include="Tapeti.Annotations" Version="3.0.0" />
|
||||
<PackageReference Include="Tapeti.DataAnnotations.Extensions" Version="3.0.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\PettingZoo.Core\PettingZoo.Core.csproj" />
|
||||
<ProjectReference Include="..\PettingZoo.WPF\PettingZoo.WPF.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Update="AssemblyParser\AssemblyParserStrings.Designer.cs">
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>AssemblyParserStrings.resx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Export\TapetiCmdImportExportStrings.Designer.cs">
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>TapetiCmdImportExportStrings.resx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="TapetiClassLibraryExampleGeneratorStrings.Designer.cs">
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>TapetiClassLibraryExampleGeneratorStrings.resx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="UI\ClassSelection\ClassSelectionStrings.Designer.cs">
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>ClassSelectionStrings.resx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="UI\PackageSelection\PackageSelectionStrings.Designer.cs">
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>PackageSelectionStrings.resx</DependentUpon>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Update="AssemblyParser\AssemblyParserStrings.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>AssemblyParserStrings.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Update="Export\TapetiCmdImportExportStrings.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>TapetiCmdImportExportStrings.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Update="TapetiClassLibraryExampleGeneratorStrings.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>TapetiClassLibraryExampleGeneratorStrings.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Update="UI\ClassSelection\ClassSelectionStrings.resx">
|
||||
<Generator>PublicResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>ClassSelectionStrings.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Update="UI\PackageSelection\PackageSelectionStrings.resx">
|
||||
<Generator>PublicResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>PackageSelectionStrings.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\Accessibility.dll" />
|
||||
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\avalonedit\6.1.3.50\lib\net6.0-windows7.0\ICSharpCode.AvalonEdit.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\Microsoft.CSharp.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\Microsoft.VisualBasic.Core.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\Microsoft.VisualBasic.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\Microsoft.VisualBasic.Forms.dll" />
|
||||
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\microsoft.web.xdt\3.0.0\lib\netstandard2.0\Microsoft.Web.XmlTransform.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\Microsoft.Win32.Primitives.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\Microsoft.Win32.Registry.AccessControl.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\Microsoft.Win32.Registry.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\Microsoft.Win32.SystemEvents.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\mscorlib.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\netstandard.dll" />
|
||||
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\newtonsoft.json\13.0.1\lib\netstandard2.0\Newtonsoft.Json.dll" />
|
||||
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\nuget.commands\6.0.0\lib\net5.0\NuGet.Commands.dll" />
|
||||
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\nuget.common\6.0.0\lib\netstandard2.0\NuGet.Common.dll" />
|
||||
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\nuget.configuration\6.0.0\lib\netstandard2.0\NuGet.Configuration.dll" />
|
||||
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\nuget.credentials\6.0.0\lib\net5.0\NuGet.Credentials.dll" />
|
||||
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\nuget.dependencyresolver.core\6.0.0\lib\net5.0\NuGet.DependencyResolver.Core.dll" />
|
||||
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\nuget.frameworks\6.0.0\lib\netstandard2.0\NuGet.Frameworks.dll" />
|
||||
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\nuget.librarymodel\6.0.0\lib\netstandard2.0\NuGet.LibraryModel.dll" />
|
||||
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\nuget.packagemanagement\6.0.0\lib\netstandard2.0\NuGet.PackageManagement.dll" />
|
||||
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\nuget.packaging\6.0.0\lib\net5.0\NuGet.Packaging.dll" />
|
||||
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\nuget.projectmodel\6.0.0\lib\net5.0\NuGet.ProjectModel.dll" />
|
||||
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\nuget.protocol\6.0.0\lib\net5.0\NuGet.Protocol.dll" />
|
||||
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\nuget.resolver\6.0.0\lib\net5.0\NuGet.Resolver.dll" />
|
||||
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\nuget.versioning\6.0.0\lib\netstandard2.0\NuGet.Versioning.dll" />
|
||||
<ReferencePath Include="P:\Development\PettingZoo\PettingZoo.Core\bin\Debug\net6.0\PettingZoo.Core.dll" />
|
||||
<ReferencePath Include="P:\Development\PettingZoo\PettingZoo.WPF\bin\Debug\net6.0-windows\PettingZoo.WPF.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\PresentationCore.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\PresentationFramework.Aero.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\PresentationFramework.Aero2.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\PresentationFramework.AeroLite.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\PresentationFramework.Classic.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\PresentationFramework.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\PresentationFramework.Luna.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\PresentationFramework.Royale.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\PresentationUI.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\ReachFramework.dll" />
|
||||
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\serilog\2.10.0\lib\netstandard2.1\Serilog.dll" />
|
||||
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\sharpvectors\1.7.7\lib\net5.0-windows\SharpVectors.Converters.Wpf.dll" />
|
||||
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\sharpvectors\1.7.7\lib\net5.0-windows\SharpVectors.Core.dll" />
|
||||
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\sharpvectors\1.7.7\lib\net5.0-windows\SharpVectors.Css.dll" />
|
||||
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\sharpvectors\1.7.7\lib\net5.0-windows\SharpVectors.Dom.dll" />
|
||||
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\sharpvectors\1.7.7\lib\net5.0-windows\SharpVectors.Model.dll" />
|
||||
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\sharpvectors\1.7.7\lib\net5.0-windows\SharpVectors.Rendering.Gdi.dll" />
|
||||
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\sharpvectors\1.7.7\lib\net5.0-windows\SharpVectors.Rendering.Wpf.dll" />
|
||||
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\sharpvectors\1.7.7\lib\net5.0-windows\SharpVectors.Runtime.Wpf.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.AppContext.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Buffers.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.CodeDom.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Collections.Concurrent.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Collections.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Collections.Immutable.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Collections.NonGeneric.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Collections.Specialized.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.ComponentModel.Annotations.dll" />
|
||||
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\system.componentmodel.composition\4.5.0\ref\netstandard2.0\System.ComponentModel.Composition.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.ComponentModel.DataAnnotations.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.ComponentModel.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.ComponentModel.EventBasedAsync.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.ComponentModel.Primitives.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.ComponentModel.TypeConverter.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.Configuration.ConfigurationManager.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Configuration.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Console.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Core.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Data.Common.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Data.DataSetExtensions.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Data.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.Design.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Diagnostics.Contracts.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Diagnostics.Debug.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Diagnostics.DiagnosticSource.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.Diagnostics.EventLog.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Diagnostics.FileVersionInfo.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.Diagnostics.PerformanceCounter.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Diagnostics.Process.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Diagnostics.StackTrace.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Diagnostics.TextWriterTraceListener.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Diagnostics.Tools.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Diagnostics.TraceSource.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Diagnostics.Tracing.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.DirectoryServices.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.Drawing.Common.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.Drawing.Design.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.Drawing.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Drawing.Primitives.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Dynamic.Runtime.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Formats.Asn1.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Globalization.Calendars.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Globalization.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Globalization.Extensions.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.IO.Compression.Brotli.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.IO.Compression.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.IO.Compression.FileSystem.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.IO.Compression.ZipFile.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.IO.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.IO.FileSystem.AccessControl.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.IO.FileSystem.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.IO.FileSystem.DriveInfo.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.IO.FileSystem.Primitives.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.IO.FileSystem.Watcher.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.IO.IsolatedStorage.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.IO.MemoryMappedFiles.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.IO.Packaging.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.IO.Pipes.AccessControl.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.IO.Pipes.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.IO.UnmanagedMemoryStream.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Linq.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Linq.Expressions.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Linq.Parallel.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Linq.Queryable.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Memory.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Net.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Net.Http.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Net.Http.Json.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Net.HttpListener.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Net.Mail.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Net.NameResolution.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Net.NetworkInformation.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Net.Ping.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Net.Primitives.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Net.Requests.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Net.Security.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Net.ServicePoint.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Net.Sockets.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Net.WebClient.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Net.WebHeaderCollection.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Net.WebProxy.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Net.WebSockets.Client.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Net.WebSockets.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Numerics.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Numerics.Vectors.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.ObjectModel.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.Printing.dll" />
|
||||
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\system.reactive\5.0.0\lib\net5.0\System.Reactive.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Reflection.DispatchProxy.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Reflection.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Reflection.Emit.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Reflection.Emit.ILGeneration.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Reflection.Emit.Lightweight.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Reflection.Extensions.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Reflection.Metadata.dll" />
|
||||
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\system.reflection.metadataloadcontext\6.0.0\lib\net6.0\System.Reflection.MetadataLoadContext.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Reflection.Primitives.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Reflection.TypeExtensions.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.Resources.Extensions.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Resources.Reader.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Resources.ResourceManager.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Resources.Writer.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Runtime.CompilerServices.Unsafe.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Runtime.CompilerServices.VisualC.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Runtime.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Runtime.Extensions.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Runtime.Handles.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Runtime.InteropServices.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Runtime.InteropServices.RuntimeInformation.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Runtime.Intrinsics.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Runtime.Loader.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Runtime.Numerics.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Runtime.Serialization.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Runtime.Serialization.Formatters.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Runtime.Serialization.Json.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Runtime.Serialization.Primitives.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Runtime.Serialization.Xml.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Security.AccessControl.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Security.Claims.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Security.Cryptography.Algorithms.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Security.Cryptography.Cng.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Security.Cryptography.Csp.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Security.Cryptography.Encoding.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Security.Cryptography.OpenSsl.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.Security.Cryptography.Pkcs.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Security.Cryptography.Primitives.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.Security.Cryptography.ProtectedData.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Security.Cryptography.X509Certificates.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.Security.Cryptography.Xml.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Security.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.Security.Permissions.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Security.Principal.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Security.Principal.Windows.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Security.SecureString.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.ServiceModel.Web.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.ServiceProcess.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Text.Encoding.CodePages.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Text.Encoding.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Text.Encoding.Extensions.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Text.Encodings.Web.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Text.Json.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Text.RegularExpressions.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.Threading.AccessControl.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Threading.Channels.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Threading.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Threading.Overlapped.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Threading.Tasks.Dataflow.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Threading.Tasks.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Threading.Tasks.Extensions.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Threading.Tasks.Parallel.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Threading.Thread.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Threading.ThreadPool.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Threading.Timer.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Transactions.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Transactions.Local.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.ValueTuple.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Web.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Web.HttpUtility.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.Windows.Controls.Ribbon.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Windows.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.Windows.Extensions.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.Windows.Forms.Design.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.Windows.Forms.Design.Editors.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.Windows.Forms.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.Windows.Forms.Primitives.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.Windows.Input.Manipulations.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.Windows.Presentation.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\System.Xaml.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Xml.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Xml.Linq.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Xml.ReaderWriter.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Xml.Serialization.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Xml.XDocument.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Xml.XmlDocument.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Xml.XmlSerializer.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Xml.XPath.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.1\ref\net6.0\System.Xml.XPath.XDocument.dll" />
|
||||
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\tapeti.annotations\3.0.0\lib\netstandard2.0\Tapeti.Annotations.dll" />
|
||||
<ReferencePath Include="C:\Users\PsychoMark\.nuget\packages\tapeti.dataannotations.extensions\3.0.0\lib\netstandard2.0\Tapeti.DataAnnotations.Extensions.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\UIAutomationClient.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\UIAutomationClientSideProviders.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\UIAutomationProvider.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\UIAutomationTypes.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\WindowsBase.dll" />
|
||||
<ReferencePath Include="C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\WindowsFormsIntegration.dll" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="P:\Development\PettingZoo\PettingZoo.Tapeti\obj\Debug\net6.0-windows\UI\ClassSelection\ClassSelectionWindow.g.cs" />
|
||||
<Compile Include="P:\Development\PettingZoo\PettingZoo.Tapeti\obj\Debug\net6.0-windows\UI\PackageSelection\PackageSelectionWindow.g.cs" />
|
||||
<Compile Include="P:\Development\PettingZoo\PettingZoo.Tapeti\obj\Debug\net6.0-windows\GeneratedInternalTypeHelper.g.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" />
|
||||
</Project>
|
@ -7,11 +7,11 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="FluentAssertions" Version="6.2.0" />
|
||||
<PackageReference Include="FluentAssertions.Json" Version="6.0.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" />
|
||||
<PackageReference Include="xunit" Version="2.4.1" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
|
||||
<PackageReference Include="FluentAssertions" Version="6.12.1" />
|
||||
<PackageReference Include="FluentAssertions.Json" Version="6.1.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
|
||||
<PackageReference Include="xunit" Version="2.9.2" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
|
26
PettingZoo.WPF/Controls/AutoOverflowToolBar.cs
Normal file
@ -0,0 +1,26 @@
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace PettingZoo.WPF.Controls
|
||||
{
|
||||
public class AutoOverflowToolBar : ToolBar
|
||||
{
|
||||
public AutoOverflowToolBar()
|
||||
{
|
||||
Loaded += (_, _) =>
|
||||
{
|
||||
// Hide overflow arrow on the right side of the toolbar when not required
|
||||
if (Template.FindName("OverflowButton", this) is not FrameworkElement overflowButton)
|
||||
return;
|
||||
|
||||
if (!overflowButton.IsEnabled)
|
||||
overflowButton.Visibility = Visibility.Hidden;
|
||||
|
||||
overflowButton.IsEnabledChanged += (_, _) =>
|
||||
{
|
||||
overflowButton.Visibility = overflowButton.IsEnabled ? Visibility.Visible : Visibility.Hidden;
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -7,7 +7,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AvalonEdit" Version="6.1.3.50" />
|
||||
<PackageReference Include="AvalonEdit" Version="6.3.0.90" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
20
PettingZoo.WPF/ValueConverters/SameReferenceConverter.cs
Normal file
@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace PettingZoo.WPF.ValueConverters
|
||||
{
|
||||
public class SameReferenceConverter : IMultiValueConverter
|
||||
{
|
||||
public object Convert(object?[] values, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
return ReferenceEquals(values[0], values[1]);
|
||||
}
|
||||
|
||||
|
||||
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
}
|
@ -20,7 +20,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PettingZoo.Settings.LiteDB"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PettingZoo.WPF", "PettingZoo.WPF\PettingZoo.WPF.csproj", "{E6617B69-2AC4-4056-B801-DD32E2374B71}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PettingZoo.Test", "PettingZoo.Test\PettingZoo.Test.csproj", "{3DD7F8D5-2CEE-414D-AC9C-9F395568B79F}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PettingZoo.Test", "PettingZoo.Test\PettingZoo.Test.csproj", "{3DD7F8D5-2CEE-414D-AC9C-9F395568B79F}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PettingZoo.Benchmark", "PettingZoo.Benchmark\PettingZoo.Benchmark.csproj", "{C25BC83A-D302-46D2-97F6-5F888B824E2D}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
@ -56,6 +58,10 @@ Global
|
||||
{3DD7F8D5-2CEE-414D-AC9C-9F395568B79F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{3DD7F8D5-2CEE-414D-AC9C-9F395568B79F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{3DD7F8D5-2CEE-414D-AC9C-9F395568B79F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{C25BC83A-D302-46D2-97F6-5F888B824E2D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C25BC83A-D302-46D2-97F6-5F888B824E2D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C25BC83A-D302-46D2-97F6-5F888B824E2D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C25BC83A-D302-46D2-97F6-5F888B824E2D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
22
PettingZoo/Images/Delete.svg
Normal file
@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 58 58" style="enable-background:new 0 0 58 58;" xml:space="preserve">
|
||||
<g>
|
||||
<g>
|
||||
<polygon style="fill:#EFEBDE;" points="46.5,14 32.5,0 1.5,0 1.5,58 46.5,58 "/>
|
||||
<g>
|
||||
<path style="fill:#D5D0BB;" d="M11.5,23h25c0.552,0,1-0.447,1-1s-0.448-1-1-1h-25c-0.552,0-1,0.447-1,1S10.948,23,11.5,23z"/>
|
||||
<path style="fill:#D5D0BB;" d="M11.5,15h10c0.552,0,1-0.447,1-1s-0.448-1-1-1h-10c-0.552,0-1,0.447-1,1S10.948,15,11.5,15z"/>
|
||||
<path style="fill:#D5D0BB;" d="M36.5,29h-25c-0.552,0-1,0.447-1,1s0.448,1,1,1h25c0.552,0,1-0.447,1-1S37.052,29,36.5,29z"/>
|
||||
<path style="fill:#D5D0BB;" d="M36.5,37h-25c-0.552,0-1,0.447-1,1s0.448,1,1,1h25c0.552,0,1-0.447,1-1S37.052,37,36.5,37z"/>
|
||||
<path style="fill:#D5D0BB;" d="M36.5,45h-25c-0.552,0-1,0.447-1,1s0.448,1,1,1h25c0.552,0,1-0.447,1-1S37.052,45,36.5,45z"/>
|
||||
</g>
|
||||
<polygon style="fill:#D5D0BB;" points="32.5,0 32.5,14 46.5,14 "/>
|
||||
</g>
|
||||
<g>
|
||||
<circle style="fill:#F29C21;" cx="44.5" cy="46" r="12"/>
|
||||
<path style="fill:#FFFFFF;" d="M50.5,47h-12c-0.552,0-1-0.448-1-1s0.448-1,1-1h12c0.552,0,1,0.448,1,1S51.052,47,50.5,47z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.3 KiB |
@ -1,32 +1,53 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 58.707 58.707" style="enable-background:new 0 0 58.707 58.707;" xml:space="preserve">
|
||||
<g>
|
||||
<g>
|
||||
<polygon style="fill:#EFEBDE;" points="46.072,14 32.072,0 1.072,0 1.072,58 46.072,58 "/>
|
||||
<g>
|
||||
<path style="fill:#D5D0BB;" d="M11.072,23h25c0.552,0,1-0.447,1-1s-0.448-1-1-1h-25c-0.552,0-1,0.447-1,1S10.52,23,11.072,23z"/>
|
||||
<path style="fill:#D5D0BB;" d="M11.072,15h10c0.552,0,1-0.447,1-1s-0.448-1-1-1h-10c-0.552,0-1,0.447-1,1S10.52,15,11.072,15z"/>
|
||||
<path style="fill:#D5D0BB;" d="M36.072,29h-25c-0.552,0-1,0.447-1,1s0.448,1,1,1h25c0.552,0,1-0.447,1-1S36.624,29,36.072,29z"/>
|
||||
<path style="fill:#D5D0BB;" d="M36.072,37h-25c-0.552,0-1,0.447-1,1s0.448,1,1,1h25c0.552,0,1-0.447,1-1S36.624,37,36.072,37z"/>
|
||||
<path style="fill:#D5D0BB;" d="M36.072,45h-25c-0.552,0-1,0.447-1,1s0.448,1,1,1h25c0.552,0,1-0.447,1-1S36.624,45,36.072,45z"/>
|
||||
</g>
|
||||
<polygon style="fill:#D5D0BB;" points="32.072,0 32.072,14 46.072,14 "/>
|
||||
</g>
|
||||
<g>
|
||||
<polygon style="fill:#EDDCC7;" points="36.201,49.214 36.194,49.222 34.205,56.511 38.852,51.865 "/>
|
||||
<path style="fill:#D75A4A;" d="M55.451,35.266l-1.247-1.247c-0.775-0.775-2.032-0.775-2.807,0L47.815,37.6l2.651,2.651
|
||||
L55.451,35.266z"/>
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
version="1.1"
|
||||
viewBox="0 0 25.2705 25.269251"
|
||||
xml:space="preserve"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<g
|
||||
id="g18"
|
||||
transform="translate(-32.36475,-33.43775)">
|
||||
<g
|
||||
id="g16">
|
||||
<polygon
|
||||
style="fill:#eddcc7"
|
||||
points="34.205,56.511 38.852,51.865 36.201,49.214 36.194,49.222 "
|
||||
id="polygon2" />
|
||||
<path
|
||||
style="fill:#d75a4a"
|
||||
d="m 55.451,35.266 -1.247,-1.247 c -0.775,-0.775 -2.032,-0.775 -2.807,0 l -3.582,3.581 2.651,2.651 z"
|
||||
id="path4" />
|
||||
|
||||
<rect x="41.459" y="36.521" transform="matrix(0.7071 0.7071 -0.7071 0.7071 44.3228 -17.5395)" style="fill:#F29C21;" width="3.749" height="16.424"/>
|
||||
<polygon style="fill:#D6C4B1;" points="41.85,54.879 41.858,54.871 38.852,51.865 34.205,56.511 34.072,57 "/>
|
||||
<path style="fill:#A34740;" d="M53.472,43.257l3.582-3.582c0.775-0.775,0.775-2.032,0-2.807l-1.602-1.602l-4.985,4.985
|
||||
L53.472,43.257z"/>
|
||||
<rect
|
||||
x="41.459"
|
||||
y="36.521"
|
||||
transform="matrix(0.7071,0.7071,-0.7071,0.7071,44.3228,-17.5395)"
|
||||
style="fill:#f29c21"
|
||||
width="3.7490001"
|
||||
height="16.424"
|
||||
id="rect6" />
|
||||
<polygon
|
||||
style="fill:#d6c4b1"
|
||||
points="38.852,51.865 34.205,56.511 34.072,57 41.85,54.879 41.858,54.871 "
|
||||
id="polygon8" />
|
||||
<path
|
||||
style="fill:#a34740"
|
||||
d="m 53.472,43.257 3.582,-3.582 c 0.775,-0.775 0.775,-2.032 0,-2.807 l -1.602,-1.602 -4.985,4.985 z"
|
||||
id="path10" />
|
||||
|
||||
<rect x="44.036" y="39.349" transform="matrix(-0.7071 -0.7071 0.7071 -0.7071 45.1717 113.8333)" style="fill:#E18C25;" width="4.251" height="16.424"/>
|
||||
<path style="fill:#5E5E5E;" d="M33.365,58.707c-0.256,0-0.512-0.098-0.707-0.293c-0.391-0.391-0.391-1.023,0-1.414l2.207-2.207
|
||||
c0.391-0.391,1.023-0.391,1.414,0s0.391,1.023,0,1.414l-2.207,2.207C33.877,58.609,33.621,58.707,33.365,58.707z"/>
|
||||
<rect
|
||||
x="44.035999"
|
||||
y="39.348999"
|
||||
transform="matrix(-0.7071,-0.7071,0.7071,-0.7071,45.1717,113.8333)"
|
||||
style="fill:#e18c25"
|
||||
width="4.2509999"
|
||||
height="16.424"
|
||||
id="rect12" />
|
||||
<path
|
||||
style="fill:#5e5e5e"
|
||||
d="m 33.365,58.707 c -0.256,0 -0.512,-0.098 -0.707,-0.293 -0.391,-0.391 -0.391,-1.023 0,-1.414 l 2.207,-2.207 c 0.391,-0.391 1.023,-0.391 1.414,0 0.391,0.391 0.391,1.023 0,1.414 l -2.207,2.207 c -0.195,0.195 -0.451,0.293 -0.707,0.293 z"
|
||||
id="path14" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 1.5 KiB |
24
PettingZoo/Images/Save.svg
Normal file
@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 58 58" style="enable-background:new 0 0 58 58;" xml:space="preserve">
|
||||
<g>
|
||||
<g>
|
||||
<polygon style="fill:#EFEBDE;" points="46.5,14 32.5,0 1.5,0 1.5,58 46.5,58 "/>
|
||||
<g>
|
||||
<path style="fill:#D5D0BB;" d="M11.5,23h25c0.552,0,1-0.447,1-1s-0.448-1-1-1h-25c-0.552,0-1,0.447-1,1S10.948,23,11.5,23z"/>
|
||||
<path style="fill:#D5D0BB;" d="M11.5,15h10c0.552,0,1-0.447,1-1s-0.448-1-1-1h-10c-0.552,0-1,0.447-1,1S10.948,15,11.5,15z"/>
|
||||
<path style="fill:#D5D0BB;" d="M36.5,29h-25c-0.552,0-1,0.447-1,1s0.448,1,1,1h25c0.552,0,1-0.447,1-1S37.052,29,36.5,29z"/>
|
||||
<path style="fill:#D5D0BB;" d="M36.5,37h-25c-0.552,0-1,0.447-1,1s0.448,1,1,1h25c0.552,0,1-0.447,1-1S37.052,37,36.5,37z"/>
|
||||
<path style="fill:#D5D0BB;" d="M36.5,45h-25c-0.552,0-1,0.447-1,1s0.448,1,1,1h25c0.552,0,1-0.447,1-1S37.052,45,36.5,45z"/>
|
||||
</g>
|
||||
<polygon style="fill:#D5D0BB;" points="32.5,0 32.5,14 46.5,14 "/>
|
||||
</g>
|
||||
<g>
|
||||
<circle style="fill:#26B999;" cx="44.5" cy="46" r="12"/>
|
||||
<path style="fill:#FFFFFF;" d="M51.071,40.179c-0.455-0.316-1.077-0.204-1.392,0.25l-5.596,8.04l-3.949-3.242
|
||||
c-0.426-0.351-1.057-0.288-1.407,0.139c-0.351,0.427-0.289,1.057,0.139,1.407l4.786,3.929c0.18,0.147,0.404,0.227,0.634,0.227
|
||||
c0.045,0,0.091-0.003,0.137-0.009c0.276-0.039,0.524-0.19,0.684-0.419l6.214-8.929C51.636,41.118,51.524,40.495,51.071,40.179z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.6 KiB |
24
PettingZoo/Images/SaveAs.svg
Normal file
@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 58 58" style="enable-background:new 0 0 58 58;" xml:space="preserve">
|
||||
<g>
|
||||
<g>
|
||||
<polygon style="fill:#EFEBDE;" points="47.222,14 33.222,0 2.222,0 2.222,58 47.222,58 "/>
|
||||
<g>
|
||||
<path style="fill:#D5D0BB;" d="M12.222,23h25c0.552,0,1-0.447,1-1s-0.448-1-1-1h-25c-0.552,0-1,0.447-1,1S11.669,23,12.222,23z"
|
||||
/>
|
||||
<path style="fill:#D5D0BB;" d="M12.222,15h10c0.552,0,1-0.447,1-1s-0.448-1-1-1h-10c-0.552,0-1,0.447-1,1S11.669,15,12.222,15z"
|
||||
/>
|
||||
<path style="fill:#D5D0BB;" d="M37.222,29h-25c-0.552,0-1,0.447-1,1s0.448,1,1,1h25c0.552,0,1-0.447,1-1S37.774,29,37.222,29z"/>
|
||||
<path style="fill:#D5D0BB;" d="M37.222,37h-25c-0.552,0-1,0.447-1,1s0.448,1,1,1h25c0.552,0,1-0.447,1-1S37.774,37,37.222,37z"/>
|
||||
<path style="fill:#D5D0BB;" d="M37.222,45h-25c-0.552,0-1,0.447-1,1s0.448,1,1,1h25c0.552,0,1-0.447,1-1S37.774,45,37.222,45z"/>
|
||||
</g>
|
||||
<polygon style="fill:#D5D0BB;" points="33.222,0 33.222,14 47.222,14 "/>
|
||||
</g>
|
||||
<g>
|
||||
<path style="fill:#3D324C;" d="M55.485,55.293l-6.797-6.797l6.483-3.241l-17.637-6.498l6.499,17.637l3.241-6.484l6.797,6.797
|
||||
C54.267,56.902,54.522,57,54.778,57s0.512-0.098,0.707-0.293C55.876,56.316,55.876,55.684,55.485,55.293z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.4 KiB |
@ -1,32 +1,29 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 58.195 58.195" style="enable-background:new 0 0 58.195 58.195;" xml:space="preserve">
|
||||
<g>
|
||||
<g>
|
||||
<polygon style="fill:#EFEBDE;" points="45,14.097 31,0.097 0,0.097 0,58.097 45,58.097 "/>
|
||||
<g>
|
||||
<path style="fill:#D5D0BB;" d="M10,23.097h25c0.552,0,1-0.447,1-1s-0.448-1-1-1H10c-0.552,0-1,0.447-1,1S9.448,23.097,10,23.097z
|
||||
"/>
|
||||
<path style="fill:#D5D0BB;" d="M10,15.097h10c0.552,0,1-0.447,1-1s-0.448-1-1-1H10c-0.552,0-1,0.447-1,1S9.448,15.097,10,15.097z
|
||||
"/>
|
||||
<path style="fill:#D5D0BB;" d="M35,29.097H10c-0.552,0-1,0.447-1,1s0.448,1,1,1h25c0.552,0,1-0.447,1-1S35.552,29.097,35,29.097z
|
||||
"/>
|
||||
<path style="fill:#D5D0BB;" d="M35,37.097H10c-0.552,0-1,0.447-1,1s0.448,1,1,1h25c0.552,0,1-0.447,1-1S35.552,37.097,35,37.097z
|
||||
"/>
|
||||
<path style="fill:#D5D0BB;" d="M35,45.097H10c-0.552,0-1,0.447-1,1s0.448,1,1,1h25c0.552,0,1-0.447,1-1S35.552,45.097,35,45.097z
|
||||
"/>
|
||||
</g>
|
||||
<polygon style="fill:#D5D0BB;" points="31,0.097 31,14.097 45,14.097 "/>
|
||||
</g>
|
||||
<g>
|
||||
<path style="fill:#FFFFFF;" d="M57,48.289l-0.107,0.163c-7.121,10.876-18.773,10.876-25.893,0l0,0l0.107-0.163
|
||||
C38.227,37.412,49.879,37.412,57,48.289L57,48.289z"/>
|
||||
<circle style="fill:#556080;" cx="43.764" cy="46.007" r="5.909"/>
|
||||
<path style="fill:#8697CB;" d="M43.947,57.609c-5.254,0-10.148-3.058-13.783-8.609l-0.358-0.547l0.465-0.711
|
||||
c3.635-5.552,8.53-8.609,13.784-8.609c5.253,0,10.148,3.057,13.783,8.609l0.358,0.547l-0.465,0.711
|
||||
C54.095,54.552,49.2,57.609,43.947,57.609z M32.203,48.448c3.206,4.624,7.356,7.161,11.744,7.161c4.436,0,8.63-2.594,11.85-7.317
|
||||
c-3.206-4.624-7.356-7.161-11.743-7.161C39.617,41.132,35.423,43.725,32.203,48.448z"/>
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
version="1.1"
|
||||
viewBox="0 0 28.39 18.476"
|
||||
xml:space="preserve"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<g
|
||||
id="g10"
|
||||
transform="translate(-29.806,-39.133)">
|
||||
<g
|
||||
id="g8">
|
||||
<path
|
||||
style="fill:#ffffff"
|
||||
d="m 57,48.289 -0.107,0.163 c -7.121,10.876 -18.773,10.876 -25.893,0 v 0 l 0.107,-0.163 c 7.12,-10.877 18.772,-10.877 25.893,0 z"
|
||||
id="path2" />
|
||||
<circle
|
||||
style="fill:#556080"
|
||||
cx="43.764"
|
||||
cy="46.007"
|
||||
r="5.9089999"
|
||||
id="circle4" />
|
||||
<path
|
||||
style="fill:#8697cb"
|
||||
d="m 43.947,57.609 c -5.254,0 -10.148,-3.058 -13.783,-8.609 l -0.358,-0.547 0.465,-0.711 c 3.635,-5.552 8.53,-8.609 13.784,-8.609 5.253,0 10.148,3.057 13.783,8.609 l 0.358,0.547 -0.465,0.711 c -3.636,5.552 -8.531,8.609 -13.784,8.609 z m -11.744,-9.161 c 3.206,4.624 7.356,7.161 11.744,7.161 4.436,0 8.63,-2.594 11.85,-7.317 -3.206,-4.624 -7.356,-7.161 -11.743,-7.161 -4.437,10e-4 -8.631,2.594 -11.851,7.317 z"
|
||||
id="path6" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.0 KiB |
@ -20,6 +20,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="Images\Busy.svg" />
|
||||
<None Remove="Images\Delete.svg" />
|
||||
<None Remove="Images\Dock.svg" />
|
||||
<None Remove="Images\Error.svg" />
|
||||
<None Remove="Images\Example.svg" />
|
||||
@ -29,6 +30,8 @@
|
||||
<None Remove="Images\Ok.svg" />
|
||||
<None Remove="Images\PublishSend.svg" />
|
||||
<None Remove="Images\RabbitMQ.svg" />
|
||||
<None Remove="Images\Save.svg" />
|
||||
<None Remove="Images\SaveAs.svg" />
|
||||
<None Remove="Images\Tapeti.png" />
|
||||
<None Remove="Images\Undock.svg" />
|
||||
</ItemGroup>
|
||||
@ -36,6 +39,7 @@
|
||||
<ItemGroup>
|
||||
<Resource Include="Images\Clear.svg" />
|
||||
<Resource Include="Images\Connect.svg" />
|
||||
<Resource Include="Images\Delete.svg" />
|
||||
<Resource Include="Images\Disconnect.svg" />
|
||||
<Resource Include="Images\Dock.svg" />
|
||||
<Resource Include="Images\Error.svg" />
|
||||
@ -47,17 +51,19 @@
|
||||
<Resource Include="Images\Publish.svg" />
|
||||
<Resource Include="Images\PublishSend.svg" />
|
||||
<Resource Include="Images\RabbitMQ.svg" />
|
||||
<Resource Include="Images\Save.svg" />
|
||||
<Resource Include="Images\SaveAs.svg" />
|
||||
<Resource Include="Images\Subscribe.svg" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AvalonEdit" Version="6.1.3.50" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
<PackageReference Include="Serilog" Version="2.10.0" />
|
||||
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
|
||||
<PackageReference Include="SharpVectors" Version="1.7.7" />
|
||||
<PackageReference Include="SimpleInjector" Version="5.3.2" />
|
||||
<PackageReference Include="System.Reactive" Version="5.0.0" />
|
||||
<PackageReference Include="AvalonEdit" Version="6.3.0.90" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="Serilog" Version="4.1.0" />
|
||||
<PackageReference Include="Serilog.Sinks.File" Version="6.0.0" />
|
||||
<PackageReference Include="SharpVectors" Version="1.8.4.2" />
|
||||
<PackageReference Include="SimpleInjector" Version="5.5.0" />
|
||||
<PackageReference Include="System.Reactive" Version="6.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@ -75,10 +81,10 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Update="UI\Connection\ConnectionDisplayNameStrings.Designer.cs">
|
||||
<Compile Update="UI\InputDialogStrings.Designer.cs">
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>ConnectionDisplayNameStrings.resx</DependentUpon>
|
||||
<DependentUpon>InputDialogStrings.resx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="UI\Connection\ConnectionWindowStrings.Designer.cs">
|
||||
<DependentUpon>ConnectionWindowStrings.resx</DependentUpon>
|
||||
@ -100,6 +106,11 @@
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>PayloadEditorStrings.resx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="UI\Tab\Publisher\StoredPublisherMessagesStrings.Designer.cs">
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>StoredPublisherMessagesStrings.resx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="UI\Tab\Publisher\TapetiPublisherViewStrings.Designer.cs">
|
||||
<DependentUpon>TapetiPublisherViewStrings.resx</DependentUpon>
|
||||
<DesignTime>True</DesignTime>
|
||||
@ -131,9 +142,9 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Update="UI\Connection\ConnectionDisplayNameStrings.resx">
|
||||
<EmbeddedResource Update="UI\InputDialogStrings.resx">
|
||||
<Generator>PublicResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>ConnectionDisplayNameStrings.Designer.cs</LastGenOutput>
|
||||
<LastGenOutput>InputDialogStrings.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Update="UI\Connection\ConnectionWindowStrings.resx">
|
||||
<LastGenOutput>ConnectionWindowStrings.Designer.cs</LastGenOutput>
|
||||
@ -151,6 +162,10 @@
|
||||
<Generator>PublicResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>PayloadEditorStrings.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Update="UI\Tab\Publisher\StoredPublisherMessagesStrings.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>StoredPublisherMessagesStrings.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Update="UI\Tab\Publisher\TapetiPublisherViewStrings.resx">
|
||||
<LastGenOutput>TapetiPublisherViewStrings.Designer.cs</LastGenOutput>
|
||||
<Generator>PublicResXFileCodeGenerator</Generator>
|
||||
|
@ -4,18 +4,19 @@ using System.IO;
|
||||
using System.Windows;
|
||||
using System.Windows.Markup;
|
||||
using PettingZoo.Core.Connection;
|
||||
using PettingZoo.Core.ExportImport;
|
||||
using PettingZoo.Core.ExportImport.Subscriber;
|
||||
using PettingZoo.Core.Generator;
|
||||
using PettingZoo.Core.Macros;
|
||||
using PettingZoo.Core.Settings;
|
||||
using PettingZoo.RabbitMQ;
|
||||
using PettingZoo.Settings.LiteDB;
|
||||
using PettingZoo.Tapeti;
|
||||
using PettingZoo.Tapeti.Export;
|
||||
using PettingZoo.Tapeti.ExportImport;
|
||||
using PettingZoo.UI.Connection;
|
||||
using PettingZoo.UI.Main;
|
||||
using PettingZoo.UI.Subscribe;
|
||||
using PettingZoo.UI.Tab;
|
||||
using PettingZoo.UI.Tab.Publisher;
|
||||
using Serilog;
|
||||
using SimpleInjector;
|
||||
|
||||
@ -82,10 +83,12 @@ namespace PettingZoo
|
||||
container.Register<ISubscribeDialog, WindowSubscribeDialog>();
|
||||
container.Register<IConnectionSettingsRepository, LiteDBConnectionSettingsRepository>();
|
||||
container.Register<IUISettingsRepository, LiteDBUISettingsRepository>();
|
||||
container.RegisterSingleton<IPublisherMessagesRepository, LiteDBPublisherMessagesRepository>();
|
||||
container.Register<IExampleGenerator, TapetiClassLibraryExampleGenerator>();
|
||||
container.RegisterSingleton<ITabHostProvider, TabHostProvider>();
|
||||
container.Register<ITabFactory, ViewTabFactory>();
|
||||
container.RegisterSingleton<IPayloadMacroProcessor, PayloadMacroProcessor>();
|
||||
container.RegisterSingleton<StoredPublisherMessagesViewModel>();
|
||||
|
||||
container.RegisterInstance<IExportImportFormatProvider>(new ExportImportFormatProvider(
|
||||
new TapetiCmdExportFormat(),
|
||||
|
@ -8,5 +8,4 @@ Should-have
|
||||
|
||||
Nice-to-have
|
||||
------------
|
||||
- Save / load publisher messages (either as templates or to disk)
|
||||
- Tapeti: fetch NuGet dependencies to improve the chances of succesfully loading the assembly, instead of the current "extraAssembliesPaths" workaround
|
||||
|
@ -1,25 +0,0 @@
|
||||
<Window x:Class="PettingZoo.UI.Connection.ConnectionDisplayNameDialog"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:local="clr-namespace:PettingZoo.UI.Connection"
|
||||
mc:Ignorable="d"
|
||||
Width="400"
|
||||
SizeToContent="Height"
|
||||
ResizeMode="NoResize"
|
||||
WindowStyle="ToolWindow"
|
||||
WindowStartupLocation="CenterOwner"
|
||||
Style="{StaticResource WindowStyle}"
|
||||
Title="{x:Static local:ConnectionDisplayNameStrings.WindowTitle}"
|
||||
FocusManager.FocusedElement="{Binding ElementName=DisplayNameTextBox}"
|
||||
d:DataContext="{d:DesignInstance local:ConnectionDisplayNameViewModel}">
|
||||
<StackPanel Margin="8">
|
||||
<TextBox Name="DisplayNameTextBox" Text="{Binding DisplayName, UpdateSourceTrigger=PropertyChanged}" />
|
||||
|
||||
<UniformGrid HorizontalAlignment="Right" Rows="1" Columns="2" Style="{StaticResource FooterPanel}">
|
||||
<Button IsDefault="True" Content="{x:Static local:ConnectionDisplayNameStrings.ButtonOK}" Style="{StaticResource FooterButton}" Command="{Binding OkCommand}"/>
|
||||
<Button IsCancel="True" Content="{x:Static local:ConnectionDisplayNameStrings.ButtonCancel}" Style="{StaticResource FooterButton}"/>
|
||||
</UniformGrid>
|
||||
</StackPanel>
|
||||
</Window>
|
@ -262,7 +262,7 @@ namespace PettingZoo.UI.Connection
|
||||
// TODO create and enforce unique name?
|
||||
var displayName = SelectedStoredConnection != null && SelectedStoredConnection.Id != Guid.Empty ? SelectedStoredConnection.DisplayName : "";
|
||||
|
||||
if (!ConnectionDisplayNameDialog.Execute(ref displayName))
|
||||
if (!InputDialog.Execute(ref displayName, ConnectionWindowStrings.ProfileNameDialogTitle))
|
||||
return;
|
||||
|
||||
var storedConnectionSettings = await connectionSettingsRepository.Add(displayName, StorePassword, ToModel());
|
||||
|
@ -213,6 +213,15 @@ namespace PettingZoo.UI.Connection {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Profile name.
|
||||
/// </summary>
|
||||
public static string ProfileNameDialogTitle {
|
||||
get {
|
||||
return ResourceManager.GetString("ProfileNameDialogTitle", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Connection parameters.
|
||||
/// </summary>
|
||||
|
@ -112,10 +112,10 @@
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="ButtonCancel" xml:space="preserve">
|
||||
<value>Cancel</value>
|
||||
@ -168,6 +168,9 @@
|
||||
<data name="LastUsedDisplayName" xml:space="preserve">
|
||||
<value><New connection></value>
|
||||
</data>
|
||||
<data name="ProfileNameDialogTitle" xml:space="preserve">
|
||||
<value>Profile name</value>
|
||||
</data>
|
||||
<data name="WindowTitle" xml:space="preserve">
|
||||
<value>Connection parameters</value>
|
||||
</data>
|
||||
|
25
PettingZoo/UI/InputDialog.xaml
Normal file
@ -0,0 +1,25 @@
|
||||
<Window x:Class="PettingZoo.UI.InputDialog"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:local="clr-namespace:PettingZoo.UI"
|
||||
mc:Ignorable="d"
|
||||
Width="400"
|
||||
SizeToContent="Height"
|
||||
ResizeMode="NoResize"
|
||||
WindowStyle="ToolWindow"
|
||||
WindowStartupLocation="CenterOwner"
|
||||
Style="{StaticResource WindowStyle}"
|
||||
Title="{Binding Title}"
|
||||
FocusManager.FocusedElement="{Binding ElementName=ValueTextBox}"
|
||||
d:DataContext="{d:DesignInstance local:InputDialogViewModel}">
|
||||
<StackPanel Margin="8">
|
||||
<TextBox Name="ValueTextBox" Text="{Binding Value, UpdateSourceTrigger=PropertyChanged}" />
|
||||
|
||||
<UniformGrid HorizontalAlignment="Right" Rows="1" Columns="2" Style="{StaticResource FooterPanel}">
|
||||
<Button IsDefault="True" Content="{x:Static local:InputDialogStrings.ButtonOK}" Style="{StaticResource FooterButton}" Command="{Binding OkCommand}"/>
|
||||
<Button IsCancel="True" Content="{x:Static local:InputDialogStrings.ButtonCancel}" Style="{StaticResource FooterButton}"/>
|
||||
</UniformGrid>
|
||||
</StackPanel>
|
||||
</Window>
|
@ -1,18 +1,19 @@
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
|
||||
namespace PettingZoo.UI.Connection
|
||||
namespace PettingZoo.UI
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for ConnectionDisplayNameDialog.xaml
|
||||
/// Interaction logic for InputDialog.xaml
|
||||
/// </summary>
|
||||
public partial class ConnectionDisplayNameDialog
|
||||
public partial class InputDialog
|
||||
{
|
||||
public static bool Execute(ref string displayName)
|
||||
public static bool Execute(ref string value, string title)
|
||||
{
|
||||
var viewModel = new ConnectionDisplayNameViewModel
|
||||
var viewModel = new InputDialogViewModel
|
||||
{
|
||||
DisplayName = displayName
|
||||
Value = value,
|
||||
Title = title
|
||||
};
|
||||
|
||||
|
||||
@ -20,7 +21,7 @@ namespace PettingZoo.UI.Connection
|
||||
.Cast<Window>()
|
||||
.FirstOrDefault(applicationWindow => applicationWindow.IsActive);
|
||||
|
||||
var window = new ConnectionDisplayNameDialog(viewModel)
|
||||
var window = new InputDialog(viewModel)
|
||||
{
|
||||
Owner = activeWindow ?? Application.Current.MainWindow
|
||||
};
|
||||
@ -28,12 +29,12 @@ namespace PettingZoo.UI.Connection
|
||||
if (!window.ShowDialog().GetValueOrDefault())
|
||||
return false;
|
||||
|
||||
displayName = viewModel.DisplayName;
|
||||
value = viewModel.Value;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public ConnectionDisplayNameDialog(ConnectionDisplayNameViewModel viewModel)
|
||||
public InputDialog(InputDialogViewModel viewModel)
|
||||
{
|
||||
viewModel.OkClick += (_, _) =>
|
||||
{
|
||||
@ -43,7 +44,7 @@ namespace PettingZoo.UI.Connection
|
||||
DataContext = viewModel;
|
||||
InitializeComponent();
|
||||
|
||||
DisplayNameTextBox.CaretIndex = DisplayNameTextBox.Text.Length;
|
||||
ValueTextBox.CaretIndex = ValueTextBox.Text.Length;
|
||||
}
|
||||
}
|
||||
}
|
@ -8,7 +8,7 @@
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace PettingZoo.UI.Connection {
|
||||
namespace PettingZoo.UI {
|
||||
using System;
|
||||
|
||||
|
||||
@ -22,14 +22,14 @@ namespace PettingZoo.UI.Connection {
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
public class ConnectionDisplayNameStrings {
|
||||
public class InputDialogStrings {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal ConnectionDisplayNameStrings() {
|
||||
internal InputDialogStrings() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -39,7 +39,7 @@ namespace PettingZoo.UI.Connection {
|
||||
public static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("PettingZoo.UI.Connection.ConnectionDisplayNameStrings", typeof(ConnectionDisplayNameStrings).Assembly);
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("PettingZoo.UI.InputDialogStrings", typeof(InputDialogStrings).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
@ -77,14 +77,5 @@ namespace PettingZoo.UI.Connection {
|
||||
return ResourceManager.GetString("ButtonOK", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Profile name.
|
||||
/// </summary>
|
||||
public static string WindowTitle {
|
||||
get {
|
||||
return ResourceManager.GetString("WindowTitle", resourceCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -112,10 +112,10 @@
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="ButtonCancel" xml:space="preserve">
|
||||
<value>Cancel</value>
|
||||
@ -123,7 +123,4 @@
|
||||
<data name="ButtonOK" xml:space="preserve">
|
||||
<value>OK</value>
|
||||
</data>
|
||||
<data name="WindowTitle" xml:space="preserve">
|
||||
<value>Profile name</value>
|
||||
</data>
|
||||
</root>
|
@ -2,27 +2,36 @@
|
||||
using System.Windows.Input;
|
||||
using PettingZoo.WPF.ViewModel;
|
||||
|
||||
namespace PettingZoo.UI.Connection
|
||||
namespace PettingZoo.UI
|
||||
{
|
||||
public class ConnectionDisplayNameViewModel : BaseViewModel
|
||||
public class InputDialogViewModel : BaseViewModel
|
||||
{
|
||||
private string displayName = "";
|
||||
private string title = "";
|
||||
private string value = "";
|
||||
|
||||
private readonly DelegateCommand okCommand;
|
||||
|
||||
|
||||
public string DisplayName
|
||||
public string Title
|
||||
{
|
||||
get => displayName;
|
||||
set => SetField(ref displayName, value, delegateCommandsChanged: new [] { okCommand });
|
||||
get => title;
|
||||
set => SetField(ref title, value);
|
||||
}
|
||||
|
||||
|
||||
public string Value
|
||||
{
|
||||
get => value;
|
||||
set => SetField(ref this.value, value, delegateCommandsChanged: new [] { okCommand });
|
||||
}
|
||||
|
||||
|
||||
public ICommand OkCommand => okCommand;
|
||||
|
||||
public event EventHandler? OkClick;
|
||||
|
||||
|
||||
public ConnectionDisplayNameViewModel()
|
||||
public InputDialogViewModel()
|
||||
{
|
||||
okCommand = new DelegateCommand(OkExecute, OkCanExecute);
|
||||
}
|
||||
@ -36,7 +45,7 @@ namespace PettingZoo.UI.Connection
|
||||
|
||||
private bool OkCanExecute()
|
||||
{
|
||||
return !string.IsNullOrWhiteSpace(DisplayName);
|
||||
return !string.IsNullOrWhiteSpace(Value);
|
||||
}
|
||||
}
|
||||
}
|
@ -7,6 +7,7 @@
|
||||
xmlns:tab="clr-namespace:PettingZoo.UI.Tab"
|
||||
xmlns:svgc="http://sharpvectors.codeplex.com/svgc/"
|
||||
xmlns:ui="clr-namespace:PettingZoo.UI"
|
||||
xmlns:controls="clr-namespace:PettingZoo.WPF.Controls;assembly=PettingZoo.WPF"
|
||||
mc:Ignorable="d"
|
||||
d:DataContext="{d:DesignInstance main:DesignTimeMainWindowViewModel, IsDesignTimeCreatable=True}"
|
||||
Width="800"
|
||||
@ -24,7 +25,7 @@
|
||||
<ui:BindingProxy x:Key="ContextMenuProxy" Data="{Binding}" />
|
||||
</Window.Resources>
|
||||
<DockPanel>
|
||||
<ToolBar DockPanel.Dock="Top" ToolBarTray.IsLocked="True" Loaded="Toolbar_Loaded">
|
||||
<controls:AutoOverflowToolBar DockPanel.Dock="Top" ToolBarTray.IsLocked="True">
|
||||
<Button Command="{Binding ConnectCommand}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Image Source="{svgc:SvgImage Source=/Images/Connect.svg, AppName=PettingZoo}" Width="16" Height="16" Style="{StaticResource ToolbarIcon}"/>
|
||||
@ -82,7 +83,7 @@
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</ToolBar>
|
||||
</controls:AutoOverflowToolBar>
|
||||
<StatusBar DockPanel.Dock="Bottom">
|
||||
<StatusBarItem>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
|
@ -5,7 +5,7 @@ using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using PettingZoo.Core.Connection;
|
||||
using PettingZoo.Core.ExportImport;
|
||||
using PettingZoo.Core.ExportImport.Subscriber;
|
||||
using PettingZoo.UI.Connection;
|
||||
using PettingZoo.UI.Subscribe;
|
||||
using PettingZoo.UI.Tab;
|
||||
@ -139,18 +139,6 @@ namespace PettingZoo.UI.Main
|
||||
|
||||
public double TabWidth => SubscriberTabs.ActualWidth;
|
||||
public double TabHeight => SubscriberTabs.ActualHeight;
|
||||
|
||||
private void Toolbar_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
// Hide arrow on the right side of the toolbar
|
||||
var toolBar = sender as ToolBar;
|
||||
|
||||
if (toolBar?.Template.FindName("OverflowGrid", toolBar) is FrameworkElement overflowGrid)
|
||||
overflowGrid.Visibility = Visibility.Collapsed;
|
||||
|
||||
if (toolBar?.Template.FindName("MainPanelBorder", toolBar) is FrameworkElement mainPanelBorder)
|
||||
mainPanelBorder.Margin = new Thickness(0);
|
||||
}
|
||||
}
|
||||
#pragma warning restore CA1001
|
||||
}
|
||||
|
2
PettingZoo/UI/Main/MainWindowStrings.Designer.cs
generated
@ -160,7 +160,7 @@ namespace PettingZoo.UI.Main {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Connected.
|
||||
/// Looks up a localized string similar to Connected to {0}.
|
||||
/// </summary>
|
||||
public static string StatusConnected {
|
||||
get {
|
||||
|
@ -151,7 +151,7 @@
|
||||
<value>Importing messages...</value>
|
||||
</data>
|
||||
<data name="StatusConnected" xml:space="preserve">
|
||||
<value>Connected</value>
|
||||
<value>Connected to {0}</value>
|
||||
</data>
|
||||
<data name="StatusConnecting" xml:space="preserve">
|
||||
<value>Connecting to {0}...</value>
|
||||
|
@ -9,7 +9,7 @@ using System.Windows;
|
||||
using System.Windows.Forms;
|
||||
using System.Windows.Input;
|
||||
using PettingZoo.Core.Connection;
|
||||
using PettingZoo.Core.ExportImport;
|
||||
using PettingZoo.Core.ExportImport.Subscriber;
|
||||
using PettingZoo.UI.Connection;
|
||||
using PettingZoo.UI.Subscribe;
|
||||
using PettingZoo.UI.Tab;
|
||||
@ -43,7 +43,7 @@ namespace PettingZoo.UI.Main
|
||||
private readonly IExportImportFormatProvider exportImportFormatProvider;
|
||||
|
||||
private SubscribeDialogParams? subscribeDialogParams;
|
||||
private IConnection? connection;
|
||||
private readonly DynamicConnection connection = new();
|
||||
private string connectionStatus;
|
||||
private ITab? activeTab;
|
||||
private readonly Dictionary<ITab, Window> undockedTabs = new();
|
||||
@ -141,14 +141,14 @@ namespace PettingZoo.UI.Main
|
||||
closeTabCommand = new DelegateCommand(CloseTabExecute, HasActiveTabCanExecute);
|
||||
undockTabCommand = new DelegateCommand(UndockTabExecute, HasActiveTabCanExecute);
|
||||
importCommand = new DelegateCommand(ImportExecute);
|
||||
|
||||
connection.StatusChanged += ConnectionStatusChanged;
|
||||
}
|
||||
|
||||
|
||||
public async ValueTask DisposeAsync()
|
||||
{
|
||||
GC.SuppressFinalize(this);
|
||||
|
||||
if (connection != null)
|
||||
await connection.DisposeAsync();
|
||||
}
|
||||
|
||||
@ -159,13 +159,9 @@ namespace PettingZoo.UI.Main
|
||||
if (connectionSettings == null)
|
||||
return;
|
||||
|
||||
if (connection != null)
|
||||
await connection.DisposeAsync();
|
||||
|
||||
connection = connectionFactory.CreateConnection(new ConnectionParams(
|
||||
connection.SetConnection(connectionFactory.CreateConnection(new ConnectionParams(
|
||||
connectionSettings.Host, connectionSettings.VirtualHost, connectionSettings.Port,
|
||||
connectionSettings.Username, connectionSettings.Password));
|
||||
connection.StatusChanged += ConnectionStatusChanged;
|
||||
connectionSettings.Username, connectionSettings.Password)));
|
||||
|
||||
if (connectionSettings.Subscribe)
|
||||
{
|
||||
@ -173,38 +169,20 @@ namespace PettingZoo.UI.Main
|
||||
tabFactory.CreateSubscriberTab(connection, subscriber);
|
||||
}
|
||||
|
||||
connection.Connect();
|
||||
ConnectionChanged();
|
||||
}
|
||||
|
||||
|
||||
private async void DisconnectExecute()
|
||||
{
|
||||
Tabs.Clear();
|
||||
|
||||
var capturedUndockedTabs = undockedTabs.ToList();
|
||||
undockedTabs.Clear();
|
||||
|
||||
foreach (var undockedTab in capturedUndockedTabs)
|
||||
undockedTab.Value.Close();
|
||||
|
||||
RaisePropertyChanged(nameof(NoTabsVisibility));
|
||||
undockTabCommand.RaiseCanExecuteChanged();
|
||||
|
||||
if (connection != null)
|
||||
{
|
||||
await connection.DisposeAsync();
|
||||
connection = null;
|
||||
}
|
||||
|
||||
ConnectionStatus = GetConnectionStatus(null);
|
||||
ConnectionStatusType = ConnectionStatusType.Error;
|
||||
ConnectionChanged();
|
||||
await connection.Disconnect();
|
||||
}
|
||||
|
||||
|
||||
private void SubscribeExecute()
|
||||
{
|
||||
if (connection == null)
|
||||
if (connection.Status != Core.Connection.ConnectionStatus.Connected)
|
||||
return;
|
||||
|
||||
var newParams = subscribeDialog.Show(subscribeDialogParams);
|
||||
@ -220,7 +198,7 @@ namespace PettingZoo.UI.Main
|
||||
|
||||
private void PublishExecute()
|
||||
{
|
||||
if (connection == null)
|
||||
if (connection.Status != Core.Connection.ConnectionStatus.Connected)
|
||||
return;
|
||||
|
||||
tabFactory.CreatePublisherTab(connection);
|
||||
@ -229,7 +207,7 @@ namespace PettingZoo.UI.Main
|
||||
|
||||
private bool IsConnectedCanExecute()
|
||||
{
|
||||
return connection != null;
|
||||
return connection.Status == Core.Connection.ConnectionStatus.Connected;
|
||||
}
|
||||
|
||||
|
||||
@ -419,6 +397,8 @@ namespace PettingZoo.UI.Main
|
||||
Core.Connection.ConnectionStatus.Connecting => ConnectionStatusType.Connecting,
|
||||
_ => ConnectionStatusType.Error
|
||||
};
|
||||
|
||||
Application.Current.Dispatcher.BeginInvoke(ConnectionChanged);
|
||||
}
|
||||
|
||||
|
||||
@ -427,9 +407,9 @@ namespace PettingZoo.UI.Main
|
||||
{
|
||||
return args?.Status switch
|
||||
{
|
||||
Core.Connection.ConnectionStatus.Connecting => string.Format(MainWindowStrings.StatusConnecting, args.Context),
|
||||
Core.Connection.ConnectionStatus.Connected => string.Format(MainWindowStrings.StatusConnected, args.Context),
|
||||
Core.Connection.ConnectionStatus.Error => string.Format(MainWindowStrings.StatusError, args.Context),
|
||||
Core.Connection.ConnectionStatus.Connecting => string.Format(MainWindowStrings.StatusConnecting, args.ConnectionParams),
|
||||
Core.Connection.ConnectionStatus.Connected => string.Format(MainWindowStrings.StatusConnected, args.ConnectionParams),
|
||||
Core.Connection.ConnectionStatus.Error => string.Format(MainWindowStrings.StatusError, args.Exception?.Message),
|
||||
Core.Connection.ConnectionStatus.Disconnected => MainWindowStrings.StatusDisconnected,
|
||||
_ => MainWindowStrings.StatusDisconnected
|
||||
};
|
||||
|
@ -4,7 +4,7 @@ namespace PettingZoo.UI.Tab
|
||||
{
|
||||
public interface ITabFactory
|
||||
{
|
||||
void CreateSubscriberTab(IConnection? connection, ISubscriber subscriber);
|
||||
void CreateSubscriberTab(IConnection connection, ISubscriber subscriber);
|
||||
string CreateReplySubscriberTab(IConnection connection);
|
||||
void CreatePublisherTab(IConnection connection, ReceivedMessageInfo? fromReceivedMessage = null);
|
||||
}
|
||||
|
@ -123,16 +123,15 @@ namespace PettingZoo.UI.Tab.Publisher
|
||||
}
|
||||
|
||||
|
||||
private IPayloadMacroProcessor? macroProcessor;
|
||||
public IPayloadMacroProcessor? MacroProcessor
|
||||
{
|
||||
get => macroProcessor;
|
||||
get => viewModel.MacroProcessor;
|
||||
set
|
||||
{
|
||||
if (value == macroProcessor)
|
||||
if (value == viewModel.MacroProcessor)
|
||||
return;
|
||||
|
||||
macroProcessor = value;
|
||||
viewModel.MacroProcessor = value;
|
||||
UpdateMacroContextMenu();
|
||||
}
|
||||
}
|
||||
@ -266,10 +265,10 @@ namespace PettingZoo.UI.Tab.Publisher
|
||||
{
|
||||
ContextMenuInsertMacro.Items.Clear();
|
||||
|
||||
if (macroProcessor == null)
|
||||
if (MacroProcessor == null)
|
||||
return;
|
||||
|
||||
foreach (var macro in macroProcessor.Macros)
|
||||
foreach (var macro in MacroProcessor.Macros)
|
||||
{
|
||||
var macroMenuItem = new MenuItem
|
||||
{
|
||||
|
@ -2,10 +2,10 @@
|
||||
using System.ComponentModel;
|
||||
using System.Reactive.Linq;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
using ICSharpCode.AvalonEdit.Highlighting;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PettingZoo.Core.Macros;
|
||||
using PettingZoo.Core.Validation;
|
||||
using PettingZoo.WPF.ViewModel;
|
||||
|
||||
@ -159,6 +159,7 @@ namespace PettingZoo.UI.Tab.Publisher
|
||||
|
||||
|
||||
public IPayloadValidator? Validator { get; set; }
|
||||
public IPayloadMacroProcessor? MacroProcessor { get; set; }
|
||||
|
||||
|
||||
public PayloadEditorViewModel()
|
||||
@ -166,7 +167,7 @@ namespace PettingZoo.UI.Tab.Publisher
|
||||
var observable = Observable.FromEventPattern<PropertyChangedEventHandler, PropertyChangedEventArgs>(
|
||||
h => PropertyChanged += h,
|
||||
h => PropertyChanged -= h)
|
||||
.Where(e => e.EventArgs.PropertyName == nameof(Payload));
|
||||
.Where(e => e.EventArgs.PropertyName is nameof(Payload) or nameof(EnableMacros));
|
||||
|
||||
observable
|
||||
.Subscribe(_ => ValidatingPayload());
|
||||
@ -204,14 +205,18 @@ namespace PettingZoo.UI.Tab.Publisher
|
||||
{
|
||||
if (!string.IsNullOrEmpty(Payload))
|
||||
{
|
||||
var validatePayload = EnableMacros && MacroProcessor != null
|
||||
? MacroProcessor.Apply(Payload)
|
||||
: Payload;
|
||||
|
||||
if (Validator != null && Validator.CanValidate())
|
||||
{
|
||||
Validator.Validate(payload);
|
||||
Validator.Validate(validatePayload);
|
||||
ValidationInfo = new ValidationInfo(ValidationStatus.Ok);
|
||||
}
|
||||
else
|
||||
{
|
||||
JToken.Parse(Payload);
|
||||
JToken.Parse(validatePayload);
|
||||
ValidationInfo = new ValidationInfo(ValidationStatus.OkSyntax);
|
||||
}
|
||||
}
|
||||
|
@ -6,12 +6,20 @@
|
||||
xmlns:res="clr-namespace:PettingZoo.UI.Tab.Publisher"
|
||||
xmlns:controls="clr-namespace:PettingZoo.WPF.Controls;assembly=PettingZoo.WPF"
|
||||
xmlns:svgc="http://sharpvectors.codeplex.com/svgc/"
|
||||
xmlns:valueConverters="clr-namespace:PettingZoo.WPF.ValueConverters;assembly=PettingZoo.WPF"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450"
|
||||
d:DesignHeight="1200"
|
||||
d:DesignWidth="800"
|
||||
d:DataContext="{d:DesignInstance res:DesignTimePublisherViewModel, IsDesignTimeCreatable=True}"
|
||||
Background="White">
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="350" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<ScrollViewer Grid.Column="0" VerticalScrollBarVisibility="Auto">
|
||||
<controls:GridLayout Style="{StaticResource Form}" Margin="4" Grid.IsSharedSizeScope="True">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
@ -26,6 +34,7 @@
|
||||
<RowDefinition Height="16" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" SharedSizeGroup="Label" />
|
||||
@ -73,6 +82,92 @@
|
||||
<ContentControl Grid.Row="10" Grid.Column="0" Grid.ColumnSpan="2" Margin="0 8 0 0" Content="{Binding MessageTypeControl}" />
|
||||
|
||||
<Button Grid.Row="11" Grid.Column="1" Command="{Binding PublishCommand}" Content="{x:Static res:PublisherViewStrings.CommandPublish}" HorizontalAlignment="Left" />
|
||||
<TextBlock Grid.Row="12" Grid.Column="1" Text="{x:Static res:PublisherViewStrings.Published}" Visibility="{Binding PublishedVisibility}" />
|
||||
</controls:GridLayout>
|
||||
</ScrollViewer>
|
||||
|
||||
<GridSplitter Width="5" Grid.Column="1" Grid.Row="0" HorizontalAlignment="Stretch"/>
|
||||
|
||||
<Grid Grid.Column="2" Grid.Row="0">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Label Grid.Row="0" Style="{StaticResource HeaderLabel}" Content="{x:Static res:PublisherViewStrings.PanelTitleMessages}"/>
|
||||
|
||||
<controls:AutoOverflowToolBar Grid.Row="1" ToolBarTray.IsLocked="True" Margin="0,0,0,4">
|
||||
<!-- TODO load button in addition to double-click. I don't like hidden-only functionality -->
|
||||
<Button Command="{Binding SaveCommand}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Image Source="{svgc:SvgImage Source=/Images/Save.svg, AppName=PettingZoo}" Width="16" Height="16" Style="{StaticResource ToolbarIcon}"/>
|
||||
<TextBlock Margin="3,0,0,0" Text="{x:Static res:PublisherViewStrings.ToolbarSave}" />
|
||||
</StackPanel>
|
||||
</Button>
|
||||
<Button Command="{Binding SaveAsCommand}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Image Source="{svgc:SvgImage Source=/Images/SaveAs.svg, AppName=PettingZoo}" Width="16" Height="16" Style="{StaticResource ToolbarIcon}"/>
|
||||
<TextBlock Margin="3,0,0,0" Text="{x:Static res:PublisherViewStrings.ToolbarSaveAs}" />
|
||||
</StackPanel>
|
||||
</Button>
|
||||
<Separator Style="{StaticResource {x:Static ToolBar.SeparatorStyleKey}}" />
|
||||
<Button Command="{Binding DeleteCommand}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Image Source="{svgc:SvgImage Source=/Images/Delete.svg, AppName=PettingZoo}" Width="16" Height="16" Style="{StaticResource ToolbarIcon}"/>
|
||||
<TextBlock Margin="3,0,0,0" Text="{x:Static res:PublisherViewStrings.ToolbarDelete}" />
|
||||
</StackPanel>
|
||||
</Button>
|
||||
<Separator Style="{StaticResource {x:Static ToolBar.SeparatorStyleKey}}" />
|
||||
<Button Command="{Binding ExportCommand}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Image Source="{svgc:SvgImage Source=/Images/Export.svg, AppName=PettingZoo}" Width="16" Height="16" Style="{StaticResource ToolbarIcon}"/>
|
||||
<TextBlock Margin="3,0,0,0" Text="{x:Static res:PublisherViewStrings.ToolbarExport}" />
|
||||
</StackPanel>
|
||||
</Button>
|
||||
<Button Command="{Binding ImportCommand}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Image Source="{svgc:SvgImage Source=/Images/Import.svg, AppName=PettingZoo}" Width="16" Height="16" Style="{StaticResource ToolbarIcon}"/>
|
||||
<TextBlock Margin="3,0,0,0" Text="{x:Static res:PublisherViewStrings.ToolbarImport}" />
|
||||
</StackPanel>
|
||||
</Button>
|
||||
<!-- TODO export / import -->
|
||||
</controls:AutoOverflowToolBar>
|
||||
|
||||
<ListBox Grid.Row="2" ItemsSource="{Binding StoredMessages}" SelectedValue="{Binding SelectedStoredMessage}">
|
||||
<ListBox.Resources>
|
||||
<valueConverters:SameReferenceConverter x:Key="SameReferenceConverter" />
|
||||
</ListBox.Resources>
|
||||
<ListBox.ItemContainerStyle>
|
||||
<Style TargetType="ListBoxItem">
|
||||
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
|
||||
</Style>
|
||||
</ListBox.ItemContainerStyle>
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{Binding DisplayName}">
|
||||
<TextBlock.Style>
|
||||
<Style TargetType="{x:Type TextBlock}">
|
||||
<Style.Triggers>
|
||||
<DataTrigger Value="True">
|
||||
<DataTrigger.Binding>
|
||||
<MultiBinding Converter="{StaticResource SameReferenceConverter}">
|
||||
<Binding RelativeSource="{RelativeSource AncestorType={x:Type ListBoxItem}}" Path="DataContext" />
|
||||
<Binding RelativeSource="{RelativeSource AncestorType={x:Type ListBox}}" Path="DataContext.ActiveStoredMessage" />
|
||||
</MultiBinding>
|
||||
</DataTrigger.Binding>
|
||||
<Setter Property="FontWeight" Value="Bold" />
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</TextBlock.Style>
|
||||
<TextBlock.InputBindings>
|
||||
<MouseBinding MouseAction="LeftDoubleClick" Command="{Binding DataContext.LoadStoredMessageCommand, RelativeSource={RelativeSource AncestorType={x:Type ListBox}}}" />
|
||||
</TextBlock.InputBindings>
|
||||
</TextBlock>
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
</ListBox>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
|
@ -1,27 +1,33 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Forms;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Threading;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using PettingZoo.Core.Connection;
|
||||
using PettingZoo.Core.ExportImport.Publisher;
|
||||
using PettingZoo.Core.Generator;
|
||||
using PettingZoo.Core.Macros;
|
||||
using PettingZoo.Core.Settings;
|
||||
using PettingZoo.WPF.ViewModel;
|
||||
using Application = System.Windows.Application;
|
||||
using UserControl = System.Windows.Controls.UserControl;
|
||||
|
||||
namespace PettingZoo.UI.Tab.Publisher
|
||||
{
|
||||
public enum MessageType
|
||||
{
|
||||
Raw,
|
||||
Tapeti
|
||||
}
|
||||
|
||||
|
||||
public class PublisherViewModel : BaseViewModel, ITabToolbarCommands, ITabHostWindowNotify, IPublishDestination
|
||||
public class PublisherViewModel : BaseViewModel, IDisposable, ITabToolbarCommands, ITabHostWindowNotify, IPublishDestination
|
||||
{
|
||||
private readonly IConnection connection;
|
||||
private readonly IExampleGenerator exampleGenerator;
|
||||
private readonly IPayloadMacroProcessor payloadMacroProcessor;
|
||||
private readonly StoredPublisherMessagesViewModel storedPublisherMessagesViewModel;
|
||||
private readonly ITabFactory tabFactory;
|
||||
|
||||
private bool sendToExchange = true;
|
||||
@ -29,26 +35,41 @@ namespace PettingZoo.UI.Tab.Publisher
|
||||
private string routingKey = "";
|
||||
private string queue = "";
|
||||
private string replyTo = "";
|
||||
private bool replyToSpecified = true;
|
||||
private bool replyToNewSubscriber;
|
||||
|
||||
private MessageType messageType;
|
||||
private StoredPublisherMessage? selectedStoredMessage;
|
||||
private StoredPublisherMessage? activeStoredMessage;
|
||||
|
||||
private PublisherMessageType messageType;
|
||||
private UserControl? messageTypeControl;
|
||||
private ICommand? messageTypePublishCommand;
|
||||
|
||||
private RawPublisherViewModel? rawPublisherViewModel;
|
||||
private UserControl? rawPublisherView;
|
||||
|
||||
private TapetiPublisherViewModel? tapetiPublisherViewModel;
|
||||
private UserControl? tapetiPublisherView;
|
||||
|
||||
private readonly DelegateCommand publishCommand;
|
||||
private readonly DelegateCommand saveCommand;
|
||||
private readonly DelegateCommand saveAsCommand;
|
||||
private readonly DelegateCommand deleteCommand;
|
||||
private readonly DelegateCommand loadStoredMessageCommand;
|
||||
private readonly DelegateCommand exportCommand;
|
||||
private readonly DelegateCommand importCommand;
|
||||
|
||||
private readonly TabToolbarCommand[] toolbarCommands;
|
||||
private Window? tabHostWindow;
|
||||
private bool disableCheckCanSave;
|
||||
|
||||
|
||||
public bool SendToExchange
|
||||
{
|
||||
get => sendToExchange;
|
||||
set => SetField(ref sendToExchange, value,
|
||||
delegateCommandsChanged: new [] { publishCommand },
|
||||
otherPropertiesChanged: new[] { nameof(SendToQueue), nameof(ExchangeVisibility), nameof(QueueVisibility), nameof(Title) });
|
||||
delegateCommandsChanged: new[] { publishCommand },
|
||||
otherPropertiesChanged: new[]
|
||||
{ nameof(SendToQueue), nameof(ExchangeVisibility), nameof(QueueVisibility), nameof(Title) });
|
||||
}
|
||||
|
||||
|
||||
@ -69,14 +90,16 @@ namespace PettingZoo.UI.Tab.Publisher
|
||||
public string RoutingKey
|
||||
{
|
||||
get => routingKey;
|
||||
set => SetField(ref routingKey, value, delegateCommandsChanged: new[] { publishCommand }, otherPropertiesChanged: new[] { nameof(Title) });
|
||||
set => SetField(ref routingKey, value, delegateCommandsChanged: new[] { publishCommand },
|
||||
otherPropertiesChanged: new[] { nameof(Title) });
|
||||
}
|
||||
|
||||
|
||||
public string Queue
|
||||
{
|
||||
get => queue;
|
||||
set => SetField(ref queue, value, delegateCommandsChanged: new[] { publishCommand }, otherPropertiesChanged: new[] { nameof(Title) });
|
||||
set => SetField(ref queue, value, delegateCommandsChanged: new[] { publishCommand },
|
||||
otherPropertiesChanged: new[] { nameof(Title) });
|
||||
}
|
||||
|
||||
|
||||
@ -89,15 +112,16 @@ namespace PettingZoo.UI.Tab.Publisher
|
||||
|
||||
public bool ReplyToSpecified
|
||||
{
|
||||
get => replyToSpecified;
|
||||
set => SetField(ref replyToSpecified, value, otherPropertiesChanged: new[] { nameof(ReplyToNewSubscriber) });
|
||||
get => !ReplyToNewSubscriber;
|
||||
set => ReplyToNewSubscriber = !value;
|
||||
}
|
||||
|
||||
|
||||
public bool ReplyToNewSubscriber
|
||||
{
|
||||
get => !ReplyToSpecified;
|
||||
set => ReplyToSpecified = !value;
|
||||
get => replyToNewSubscriber;
|
||||
set => SetField(ref replyToNewSubscriber, value,
|
||||
otherPropertiesChanged: new[] { nameof(ReplyToSpecified) });
|
||||
}
|
||||
|
||||
|
||||
@ -105,7 +129,7 @@ namespace PettingZoo.UI.Tab.Publisher
|
||||
public virtual Visibility QueueVisibility => SendToQueue ? Visibility.Visible : Visibility.Collapsed;
|
||||
|
||||
|
||||
public MessageType MessageType
|
||||
public PublisherMessageType MessageType
|
||||
{
|
||||
get => messageType;
|
||||
set
|
||||
@ -124,14 +148,20 @@ namespace PettingZoo.UI.Tab.Publisher
|
||||
|
||||
public bool MessageTypeRaw
|
||||
{
|
||||
get => MessageType == MessageType.Raw;
|
||||
set { if (value) MessageType = MessageType.Raw; }
|
||||
get => MessageType == PublisherMessageType.Raw;
|
||||
set
|
||||
{
|
||||
if (value) MessageType = PublisherMessageType.Raw;
|
||||
}
|
||||
}
|
||||
|
||||
public bool MessageTypeTapeti
|
||||
{
|
||||
get => MessageType == MessageType.Tapeti;
|
||||
set { if (value) MessageType = MessageType.Tapeti; }
|
||||
get => MessageType == PublisherMessageType.Tapeti;
|
||||
set
|
||||
{
|
||||
if (value) MessageType = PublisherMessageType.Tapeti;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -142,12 +172,51 @@ namespace PettingZoo.UI.Tab.Publisher
|
||||
}
|
||||
|
||||
|
||||
public ObservableCollectionEx<StoredPublisherMessage> StoredMessages =>
|
||||
storedPublisherMessagesViewModel.StoredMessages;
|
||||
|
||||
public StoredPublisherMessage? SelectedStoredMessage
|
||||
{
|
||||
get => selectedStoredMessage;
|
||||
set => SetField(ref selectedStoredMessage, value, delegateCommandsChanged: new[] { loadStoredMessageCommand, deleteCommand, exportCommand });
|
||||
}
|
||||
|
||||
|
||||
public StoredPublisherMessage? ActiveStoredMessage
|
||||
{
|
||||
get => activeStoredMessage;
|
||||
set => SetField(ref activeStoredMessage, value);
|
||||
}
|
||||
|
||||
|
||||
public ICommand PublishCommand => publishCommand;
|
||||
public ICommand SaveCommand => saveCommand;
|
||||
public ICommand SaveAsCommand => saveAsCommand;
|
||||
public ICommand DeleteCommand => deleteCommand;
|
||||
public ICommand LoadStoredMessageCommand => loadStoredMessageCommand;
|
||||
public ICommand ExportCommand => exportCommand;
|
||||
public ICommand ImportCommand => importCommand;
|
||||
|
||||
|
||||
private readonly DispatcherTimer publishedVisibilityTimer = new()
|
||||
{
|
||||
Interval = TimeSpan.FromSeconds(1)
|
||||
};
|
||||
|
||||
private Visibility publishedVisibility = Visibility.Hidden;
|
||||
public Visibility PublishedVisibility
|
||||
{
|
||||
get => publishedVisibility;
|
||||
set => SetField(ref publishedVisibility, value);
|
||||
}
|
||||
|
||||
|
||||
public string Title => SendToQueue
|
||||
? string.IsNullOrWhiteSpace(Queue) ? PublisherViewStrings.TabTitleEmpty : string.Format(PublisherViewStrings.TabTitle, Queue)
|
||||
: string.IsNullOrWhiteSpace(RoutingKey) ? PublisherViewStrings.TabTitleEmpty : string.Format(PublisherViewStrings.TabTitle, RoutingKey);
|
||||
? string.IsNullOrWhiteSpace(Queue) ? PublisherViewStrings.TabTitleEmpty :
|
||||
string.Format(PublisherViewStrings.TabTitle, Queue)
|
||||
: string.IsNullOrWhiteSpace(RoutingKey)
|
||||
? PublisherViewStrings.TabTitleEmpty
|
||||
: string.Format(PublisherViewStrings.TabTitle, RoutingKey);
|
||||
|
||||
|
||||
public IEnumerable<TabToolbarCommand> ToolbarCommands => toolbarCommands;
|
||||
@ -157,35 +226,83 @@ namespace PettingZoo.UI.Tab.Publisher
|
||||
string IPublishDestination.RoutingKey => SendToExchange ? RoutingKey : Queue;
|
||||
|
||||
|
||||
public PublisherViewModel(ITabFactory tabFactory, IConnection connection, IExampleGenerator exampleGenerator, IPayloadMacroProcessor payloadMacroProcessor, ReceivedMessageInfo? fromReceivedMessage = null)
|
||||
public PublisherViewModel(ITabFactory tabFactory, IConnection connection, IExampleGenerator exampleGenerator,
|
||||
IPayloadMacroProcessor payloadMacroProcessor,
|
||||
StoredPublisherMessagesViewModel storedPublisherMessagesViewModel,
|
||||
ReceivedMessageInfo? fromReceivedMessage = null)
|
||||
{
|
||||
this.connection = connection;
|
||||
this.exampleGenerator = exampleGenerator;
|
||||
this.payloadMacroProcessor = payloadMacroProcessor;
|
||||
this.storedPublisherMessagesViewModel = storedPublisherMessagesViewModel;
|
||||
this.tabFactory = tabFactory;
|
||||
|
||||
publishCommand = new DelegateCommand(PublishExecute, PublishCanExecute);
|
||||
saveCommand = new DelegateCommand(SaveExecute, SaveCanExecute);
|
||||
saveAsCommand = new DelegateCommand(SaveAsExecute);
|
||||
deleteCommand = new DelegateCommand(DeleteExecute, SelectedMessageCanExecute);
|
||||
loadStoredMessageCommand = new DelegateCommand(LoadStoredMessageExecute, SelectedMessageCanExecute);
|
||||
exportCommand = new DelegateCommand(ExportExecute, SelectedMessageCanExecute);
|
||||
importCommand = new DelegateCommand(ImportExecute);
|
||||
|
||||
toolbarCommands = new[]
|
||||
{
|
||||
new TabToolbarCommand(PublishCommand, PublisherViewStrings.CommandPublish, SvgIconHelper.LoadFromResource("/Images/PublishSend.svg"))
|
||||
new TabToolbarCommand(PublishCommand, PublisherViewStrings.CommandPublish,
|
||||
SvgIconHelper.LoadFromResource("/Images/PublishSend.svg"))
|
||||
};
|
||||
|
||||
if (fromReceivedMessage != null)
|
||||
SetMessageTypeControl(fromReceivedMessage);
|
||||
else
|
||||
SetMessageTypeControl(MessageType.Raw);
|
||||
SetMessageTypeControl(PublisherMessageType.Raw);
|
||||
|
||||
|
||||
PropertyChanged += (_, _) => { saveCommand.RaiseCanExecuteChanged(); };
|
||||
|
||||
|
||||
// ReSharper disable once ConditionIsAlwaysTrueOrFalse - null in design time
|
||||
if (connection != null)
|
||||
connection.StatusChanged += ConnectionStatusChanged;
|
||||
|
||||
publishedVisibilityTimer.Tick += (_, _) =>
|
||||
{
|
||||
PublishedVisibility = Visibility.Hidden;
|
||||
publishedVisibilityTimer.Stop();
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
connection.StatusChanged -= ConnectionStatusChanged;
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
|
||||
private void ConnectionStatusChanged(object? sender, StatusChangedEventArgs e)
|
||||
{
|
||||
Application.Current.Dispatcher.BeginInvoke(() =>
|
||||
{
|
||||
publishCommand.RaiseCanExecuteChanged();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private void PublishExecute()
|
||||
{
|
||||
messageTypePublishCommand?.Execute(null);
|
||||
|
||||
PublishedVisibility = Visibility.Visible;
|
||||
publishedVisibilityTimer.Stop();
|
||||
publishedVisibilityTimer.Start();
|
||||
}
|
||||
|
||||
|
||||
private bool PublishCanExecute()
|
||||
{
|
||||
if (connection.Status != ConnectionStatus.Connected)
|
||||
return false;
|
||||
|
||||
if (SendToExchange)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(Exchange) || string.IsNullOrWhiteSpace(RoutingKey))
|
||||
@ -201,13 +318,11 @@ namespace PettingZoo.UI.Tab.Publisher
|
||||
}
|
||||
|
||||
|
||||
private void SetMessageTypeControl(MessageType value)
|
||||
private void SetMessageTypeControl(PublisherMessageType value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case MessageType.Raw:
|
||||
RawPublisherViewModel rawPublisherViewModel;
|
||||
|
||||
case PublisherMessageType.Raw:
|
||||
if (rawPublisherView == null)
|
||||
{
|
||||
rawPublisherViewModel = new RawPublisherViewModel(connection, this, payloadMacroProcessor);
|
||||
@ -216,19 +331,22 @@ namespace PettingZoo.UI.Tab.Publisher
|
||||
publishCommand.RaiseCanExecuteChanged();
|
||||
};
|
||||
|
||||
rawPublisherView ??= new RawPublisherView(rawPublisherViewModel);
|
||||
// This is becoming a bit messy, find a cleaner way...
|
||||
// TODO monitor header changes as well, instead of only the collection
|
||||
rawPublisherViewModel.PropertyChanged += (_, _) => { saveCommand.RaiseCanExecuteChanged(); };
|
||||
rawPublisherViewModel.Headers.CollectionChanged += (_, _) => { saveCommand.RaiseCanExecuteChanged(); };
|
||||
|
||||
rawPublisherView = new RawPublisherView(rawPublisherViewModel);
|
||||
}
|
||||
else
|
||||
rawPublisherViewModel = (RawPublisherViewModel)rawPublisherView.DataContext;
|
||||
Debug.Assert(rawPublisherViewModel != null);
|
||||
|
||||
MessageTypeControl = rawPublisherView;
|
||||
|
||||
messageTypePublishCommand = rawPublisherViewModel.PublishCommand;
|
||||
break;
|
||||
|
||||
case MessageType.Tapeti:
|
||||
TapetiPublisherViewModel tapetiPublisherViewModel;
|
||||
|
||||
case PublisherMessageType.Tapeti:
|
||||
if (tapetiPublisherView == null)
|
||||
{
|
||||
tapetiPublisherViewModel = new TapetiPublisherViewModel(connection, this, exampleGenerator, payloadMacroProcessor);
|
||||
@ -237,13 +355,15 @@ namespace PettingZoo.UI.Tab.Publisher
|
||||
publishCommand.RaiseCanExecuteChanged();
|
||||
};
|
||||
|
||||
tapetiPublisherView ??= new TapetiPublisherView(tapetiPublisherViewModel);
|
||||
tapetiPublisherViewModel.PropertyChanged += (_, _) => { saveCommand.RaiseCanExecuteChanged(); };
|
||||
|
||||
tapetiPublisherView = new TapetiPublisherView(tapetiPublisherViewModel);
|
||||
|
||||
if (tabHostWindow != null)
|
||||
tapetiPublisherViewModel.HostWindowChanged(tabHostWindow);
|
||||
}
|
||||
else
|
||||
tapetiPublisherViewModel = (TapetiPublisherViewModel)tapetiPublisherView.DataContext;
|
||||
Debug.Assert(tapetiPublisherViewModel != null);
|
||||
|
||||
MessageTypeControl = tapetiPublisherView;
|
||||
|
||||
@ -266,17 +386,17 @@ namespace PettingZoo.UI.Tab.Publisher
|
||||
|
||||
if (TapetiPublisherViewModel.IsTapetiMessage(fromReceivedMessage))
|
||||
{
|
||||
var tapetiPublisherViewModel = new TapetiPublisherViewModel(connection, this, exampleGenerator, payloadMacroProcessor, fromReceivedMessage);
|
||||
tapetiPublisherViewModel = new TapetiPublisherViewModel(connection, this, exampleGenerator, payloadMacroProcessor, fromReceivedMessage);
|
||||
tapetiPublisherView = new TapetiPublisherView(tapetiPublisherViewModel);
|
||||
|
||||
MessageType = MessageType.Tapeti;
|
||||
MessageType = PublisherMessageType.Tapeti;
|
||||
}
|
||||
else
|
||||
{
|
||||
var rawPublisherViewModel = new RawPublisherViewModel(connection, this, payloadMacroProcessor, fromReceivedMessage);
|
||||
rawPublisherViewModel = new RawPublisherViewModel(connection, this, payloadMacroProcessor, fromReceivedMessage);
|
||||
rawPublisherView = new RawPublisherView(rawPublisherViewModel);
|
||||
|
||||
MessageType = MessageType.Raw;
|
||||
MessageType = PublisherMessageType.Raw;
|
||||
}
|
||||
}
|
||||
|
||||
@ -304,16 +424,234 @@ namespace PettingZoo.UI.Tab.Publisher
|
||||
|
||||
(tapetiPublisherView?.DataContext as TapetiPublisherViewModel)?.HostWindowChanged(hostWindow);
|
||||
}
|
||||
|
||||
|
||||
private bool SaveCanExecute()
|
||||
{
|
||||
if (disableCheckCanSave)
|
||||
return false;
|
||||
|
||||
return ActiveStoredMessage != null && !GetPublisherMessage().Equals(ActiveStoredMessage.Message);
|
||||
}
|
||||
|
||||
|
||||
private void SaveExecute()
|
||||
{
|
||||
if (ActiveStoredMessage == null)
|
||||
return;
|
||||
|
||||
storedPublisherMessagesViewModel.Save(ActiveStoredMessage, GetPublisherMessage(), message =>
|
||||
{
|
||||
ActiveStoredMessage = message;
|
||||
SelectedStoredMessage = message;
|
||||
|
||||
saveCommand.RaiseCanExecuteChanged();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private void SaveAsExecute()
|
||||
{
|
||||
storedPublisherMessagesViewModel.SaveAs(GetPublisherMessage(), ActiveStoredMessage?.DisplayName, message =>
|
||||
{
|
||||
ActiveStoredMessage = message;
|
||||
SelectedStoredMessage = message;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private void DeleteExecute()
|
||||
{
|
||||
if (SelectedStoredMessage == null)
|
||||
return;
|
||||
|
||||
var message = SelectedStoredMessage;
|
||||
|
||||
storedPublisherMessagesViewModel.Delete(message, () =>
|
||||
{
|
||||
if (SelectedStoredMessage == message)
|
||||
SelectedStoredMessage = null;
|
||||
|
||||
if (ActiveStoredMessage == message)
|
||||
ActiveStoredMessage = null;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private bool SelectedMessageCanExecute()
|
||||
{
|
||||
return SelectedStoredMessage != null;
|
||||
}
|
||||
|
||||
|
||||
private void LoadStoredMessageExecute()
|
||||
{
|
||||
if (SelectedStoredMessage == null)
|
||||
return;
|
||||
|
||||
var message = SelectedStoredMessage.Message;
|
||||
|
||||
disableCheckCanSave = true;
|
||||
try
|
||||
{
|
||||
MessageType = message.MessageType;
|
||||
SendToExchange = message.SendToExchange;
|
||||
Exchange = message.Exchange ?? "";
|
||||
RoutingKey = message.RoutingKey ?? "";
|
||||
Queue = message.Queue ?? "";
|
||||
ReplyToNewSubscriber = message.ReplyToNewSubscriber;
|
||||
ReplyTo = message.ReplyTo ?? "";
|
||||
|
||||
// ReSharper disable once SwitchStatementHandlesSomeKnownEnumValuesWithDefault
|
||||
switch (message.MessageType)
|
||||
{
|
||||
case PublisherMessageType.Raw:
|
||||
if (message.RawPublisherMessage != null)
|
||||
rawPublisherViewModel?.LoadPublisherMessage(message.RawPublisherMessage);
|
||||
|
||||
break;
|
||||
|
||||
case PublisherMessageType.Tapeti:
|
||||
if (message.TapetiPublisherMessage != null)
|
||||
tapetiPublisherViewModel?.LoadPublisherMessage(message.TapetiPublisherMessage);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
ActiveStoredMessage = SelectedStoredMessage;
|
||||
}
|
||||
finally
|
||||
{
|
||||
disableCheckCanSave = false;
|
||||
saveCommand.RaiseCanExecuteChanged();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static readonly JsonSerializerSettings ExportImportSettings = new()
|
||||
{
|
||||
Converters = new List<JsonConverter> { new StringEnumConverter() }
|
||||
};
|
||||
|
||||
|
||||
|
||||
private void ExportExecute()
|
||||
{
|
||||
if (SelectedStoredMessage == null)
|
||||
return;
|
||||
|
||||
var invalidChars = Regex.Escape(new string(Path.GetInvalidFileNameChars()));
|
||||
var invalidRegStr = string.Format(@"([{0}]*\.+$)|([{0}]+)", invalidChars);
|
||||
var suggestedFilename = Regex.Replace(SelectedStoredMessage.DisplayName, invalidRegStr, "_");
|
||||
|
||||
var dialog = new SaveFileDialog
|
||||
{
|
||||
Filter = PublisherViewStrings.StoredMessagesExportImportFilter,
|
||||
FileName = suggestedFilename
|
||||
};
|
||||
|
||||
if (dialog.ShowDialog() != DialogResult.OK)
|
||||
return;
|
||||
|
||||
File.WriteAllText(dialog.FileName, JsonConvert.SerializeObject(SelectedStoredMessage.Message, ExportImportSettings), Encoding.UTF8);
|
||||
}
|
||||
|
||||
|
||||
private void ImportExecute()
|
||||
{
|
||||
var dialog = new OpenFileDialog
|
||||
{
|
||||
Filter = PublisherViewStrings.StoredMessagesExportImportFilter
|
||||
};
|
||||
|
||||
if (dialog.ShowDialog() != DialogResult.OK)
|
||||
return;
|
||||
|
||||
var fileContents = File.ReadAllText(dialog.FileName, Encoding.UTF8);
|
||||
var message = JsonConvert.DeserializeObject<PublisherMessage>(fileContents, ExportImportSettings);
|
||||
if (message == null)
|
||||
return;
|
||||
|
||||
var displayName = dialog.FileName.EndsWith(".pubmsg.json")
|
||||
? Path.GetFileName(dialog.FileName)[..^".pubmsg.json".Length]
|
||||
: Path.GetFileNameWithoutExtension(dialog.FileName);
|
||||
|
||||
storedPublisherMessagesViewModel.SaveAs(message, displayName, storedMessage =>
|
||||
{
|
||||
SelectedStoredMessage = storedMessage;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private PublisherMessage GetPublisherMessage()
|
||||
{
|
||||
return new PublisherMessage
|
||||
{
|
||||
MessageType = MessageType,
|
||||
SendToExchange = SendToExchange,
|
||||
Exchange = Exchange,
|
||||
RoutingKey = RoutingKey,
|
||||
Queue = Queue,
|
||||
ReplyToNewSubscriber = ReplyToNewSubscriber,
|
||||
ReplyTo = ReplyTo,
|
||||
|
||||
RawPublisherMessage = MessageType == PublisherMessageType.Raw
|
||||
? rawPublisherViewModel?.GetPublisherMessage()
|
||||
: null,
|
||||
|
||||
TapetiPublisherMessage = MessageType == PublisherMessageType.Tapeti
|
||||
? tapetiPublisherViewModel?.GetPublisherMessage()
|
||||
: null
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class DesignTimePublisherViewModel : PublisherViewModel
|
||||
{
|
||||
public DesignTimePublisherViewModel() : base(null!, null!, null!, null!)
|
||||
public DesignTimePublisherViewModel() : base(null!, null!, null!, null!, new StoredPublisherMessagesViewModel(new DesignTimePublisherMessagesRepository()))
|
||||
{
|
||||
StoredMessages.CollectionChanged += (_, _) =>
|
||||
{
|
||||
if (StoredMessages.Count < 2)
|
||||
return;
|
||||
|
||||
SelectedStoredMessage = StoredMessages[0];
|
||||
ActiveStoredMessage = StoredMessages[1];
|
||||
};
|
||||
|
||||
PublishedVisibility = Visibility.Visible;
|
||||
}
|
||||
|
||||
public override Visibility ExchangeVisibility => Visibility.Visible;
|
||||
public override Visibility QueueVisibility => Visibility.Visible;
|
||||
|
||||
|
||||
private class DesignTimePublisherMessagesRepository : IPublisherMessagesRepository
|
||||
{
|
||||
public Task<IEnumerable<StoredPublisherMessage>> GetStored()
|
||||
{
|
||||
return Task.FromResult(new StoredPublisherMessage[]
|
||||
{
|
||||
new(new Guid("16fdf930-2e4c-48f4-ae21-68dac9ca62e6"), "Design-time message 1", new PublisherMessage()),
|
||||
new(new Guid("01d2671b-4426-4c1c-bcbc-61689d14796e"), "Design-time message 2", new PublisherMessage())
|
||||
} as IEnumerable<StoredPublisherMessage>);
|
||||
}
|
||||
|
||||
public Task<StoredPublisherMessage> Add(string displayName, PublisherMessage message)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public Task<StoredPublisherMessage> Update(Guid id, string displayName, PublisherMessage message)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public Task Delete(Guid id)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -168,6 +168,24 @@ namespace PettingZoo.UI.Tab.Publisher {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Saved messages.
|
||||
/// </summary>
|
||||
public static string PanelTitleMessages {
|
||||
get {
|
||||
return ResourceManager.GetString("PanelTitleMessages", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Message published.
|
||||
/// </summary>
|
||||
public static string Published {
|
||||
get {
|
||||
return ResourceManager.GetString("Published", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Re: .
|
||||
/// </summary>
|
||||
@ -177,6 +195,15 @@ namespace PettingZoo.UI.Tab.Publisher {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to PettingZoo message (*.pubmsg.json)|*.pubmsg.json.
|
||||
/// </summary>
|
||||
public static string StoredMessagesExportImportFilter {
|
||||
get {
|
||||
return ResourceManager.GetString("StoredMessagesExportImportFilter", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Publish: {0}.
|
||||
/// </summary>
|
||||
@ -194,5 +221,50 @@ namespace PettingZoo.UI.Tab.Publisher {
|
||||
return ResourceManager.GetString("TabTitleEmpty", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Delete.
|
||||
/// </summary>
|
||||
public static string ToolbarDelete {
|
||||
get {
|
||||
return ResourceManager.GetString("ToolbarDelete", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Export....
|
||||
/// </summary>
|
||||
public static string ToolbarExport {
|
||||
get {
|
||||
return ResourceManager.GetString("ToolbarExport", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Import....
|
||||
/// </summary>
|
||||
public static string ToolbarImport {
|
||||
get {
|
||||
return ResourceManager.GetString("ToolbarImport", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Save.
|
||||
/// </summary>
|
||||
public static string ToolbarSave {
|
||||
get {
|
||||
return ResourceManager.GetString("ToolbarSave", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Save as....
|
||||
/// </summary>
|
||||
public static string ToolbarSaveAs {
|
||||
get {
|
||||
return ResourceManager.GetString("ToolbarSaveAs", resourceCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -153,13 +153,37 @@
|
||||
<data name="OptionMessageTypeTapeti" xml:space="preserve">
|
||||
<value>Tapeti message</value>
|
||||
</data>
|
||||
<data name="PanelTitleMessages" xml:space="preserve">
|
||||
<value>Saved messages</value>
|
||||
</data>
|
||||
<data name="Published" xml:space="preserve">
|
||||
<value>Message published</value>
|
||||
</data>
|
||||
<data name="ReplyToCorrelationIdPrefix" xml:space="preserve">
|
||||
<value>Re: </value>
|
||||
</data>
|
||||
<data name="StoredMessagesExportImportFilter" xml:space="preserve">
|
||||
<value>PettingZoo message (*.pubmsg.json)|*.pubmsg.json</value>
|
||||
</data>
|
||||
<data name="TabTitle" xml:space="preserve">
|
||||
<value>Publish: {0}</value>
|
||||
</data>
|
||||
<data name="TabTitleEmpty" xml:space="preserve">
|
||||
<value>Publish</value>
|
||||
</data>
|
||||
<data name="ToolbarDelete" xml:space="preserve">
|
||||
<value>Delete</value>
|
||||
</data>
|
||||
<data name="ToolbarExport" xml:space="preserve">
|
||||
<value>Export...</value>
|
||||
</data>
|
||||
<data name="ToolbarImport" xml:space="preserve">
|
||||
<value>Import...</value>
|
||||
</data>
|
||||
<data name="ToolbarSave" xml:space="preserve">
|
||||
<value>Save</value>
|
||||
</data>
|
||||
<data name="ToolbarSaveAs" xml:space="preserve">
|
||||
<value>Save as...</value>
|
||||
</data>
|
||||
</root>
|
@ -3,7 +3,6 @@ using System.Linq;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Threading;
|
||||
using PettingZoo.Core.Macros;
|
||||
|
||||
namespace PettingZoo.UI.Tab.Publisher
|
||||
{
|
||||
|
@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
@ -7,6 +6,7 @@ using System.Text;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
using PettingZoo.Core.Connection;
|
||||
using PettingZoo.Core.ExportImport.Publisher;
|
||||
using PettingZoo.Core.Macros;
|
||||
using PettingZoo.WPF.ViewModel;
|
||||
|
||||
@ -37,10 +37,17 @@ namespace PettingZoo.UI.Tab.Publisher
|
||||
|
||||
|
||||
|
||||
public MessageDeliveryMode DeliveryMode
|
||||
{
|
||||
get => deliveryMode;
|
||||
set => SetField(ref deliveryMode, value, otherPropertiesChanged: new[] { nameof(DeliveryModeIndex) });
|
||||
}
|
||||
|
||||
|
||||
public int DeliveryModeIndex
|
||||
{
|
||||
get => deliveryMode == MessageDeliveryMode.Persistent ? 1 : 0;
|
||||
set => SetField(ref deliveryMode, value == 1 ? MessageDeliveryMode.Persistent : MessageDeliveryMode.NonPersistent);
|
||||
get => DeliveryMode == MessageDeliveryMode.Persistent ? 1 : 0;
|
||||
set => DeliveryMode = value == 1 ? MessageDeliveryMode.Persistent : MessageDeliveryMode.NonPersistent;
|
||||
}
|
||||
|
||||
|
||||
@ -127,7 +134,7 @@ namespace PettingZoo.UI.Tab.Publisher
|
||||
}
|
||||
|
||||
|
||||
public ObservableCollection<Header> Headers { get; } = new();
|
||||
public ObservableCollectionEx<Header> Headers { get; } = new();
|
||||
|
||||
|
||||
public ICommand PublishCommand => publishCommand;
|
||||
@ -194,6 +201,60 @@ namespace PettingZoo.UI.Tab.Publisher
|
||||
}
|
||||
|
||||
|
||||
public RawPublisherMessage GetPublisherMessage()
|
||||
{
|
||||
return new RawPublisherMessage
|
||||
{
|
||||
DeliveryMode = DeliveryMode,
|
||||
ContentType = ContentType,
|
||||
CorrelationId = CorrelationId,
|
||||
AppId = AppId,
|
||||
ContentEncoding = ContentEncoding,
|
||||
Expiration = Expiration,
|
||||
MessageId = MessageId,
|
||||
Priority = Priority,
|
||||
Timestamp = Timestamp,
|
||||
TypeProperty = TypeProperty,
|
||||
UserId = UserId,
|
||||
Payload = Payload,
|
||||
EnableMacros = EnableMacros,
|
||||
|
||||
Headers = Headers.Where(h => !h.IsEmpty()).ToDictionary(h => h.Key, h => h.Value)
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public void LoadPublisherMessage(RawPublisherMessage message)
|
||||
{
|
||||
DeliveryMode = message.DeliveryMode;
|
||||
ContentType = message.ContentType ?? "";
|
||||
CorrelationId = message.CorrelationId ?? "";
|
||||
AppId = message.AppId ?? "";
|
||||
ContentEncoding = message.ContentEncoding ?? "";
|
||||
Expiration = message.Expiration ?? "";
|
||||
MessageId = message.MessageId ?? "";
|
||||
Priority = message.Priority ?? "";
|
||||
Timestamp = message.Timestamp ?? "";
|
||||
TypeProperty = message.TypeProperty ?? "";
|
||||
UserId = message.UserId ?? "";
|
||||
Payload = message.Payload ?? "";
|
||||
EnableMacros = message.EnableMacros;
|
||||
|
||||
if (message.Headers != null)
|
||||
{
|
||||
Headers.ReplaceAll(message.Headers.Select(p => new Header
|
||||
{
|
||||
Key = p.Key,
|
||||
Value = p.Value
|
||||
}));
|
||||
}
|
||||
else
|
||||
Headers.Clear();
|
||||
|
||||
AddHeader();
|
||||
}
|
||||
|
||||
|
||||
private static bool AnyNotEmpty(params string?[] values)
|
||||
{
|
||||
return values.Any(s => !string.IsNullOrEmpty(s));
|
||||
|
90
PettingZoo/UI/Tab/Publisher/StoredPublisherMessagesStrings.Designer.cs
generated
Normal file
@ -0,0 +1,90 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace PettingZoo.UI.Tab.Publisher {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class StoredPublisherMessagesStrings {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal StoredPublisherMessagesStrings() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the cached ResourceManager instance used by this class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("PettingZoo.UI.Tab.Publisher.StoredPublisherMessagesStrings", typeof(StoredPublisherMessagesStrings).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the current thread's CurrentUICulture property for all
|
||||
/// resource lookups using this strongly typed resource class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Do you want to delete the saved message '{0}'?.
|
||||
/// </summary>
|
||||
internal static string DeleteConfirmation {
|
||||
get {
|
||||
return ResourceManager.GetString("DeleteConfirmation", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Delete message.
|
||||
/// </summary>
|
||||
internal static string DeleteConfirmationTitle {
|
||||
get {
|
||||
return ResourceManager.GetString("DeleteConfirmationTitle", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Save as....
|
||||
/// </summary>
|
||||
internal static string DisplayNameDialogTitle {
|
||||
get {
|
||||
return ResourceManager.GetString("DisplayNameDialogTitle", resourceCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
129
PettingZoo/UI/Tab/Publisher/StoredPublisherMessagesStrings.resx
Normal file
@ -0,0 +1,129 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="DeleteConfirmation" xml:space="preserve">
|
||||
<value>Do you want to delete the saved message '{0}'?</value>
|
||||
</data>
|
||||
<data name="DeleteConfirmationTitle" xml:space="preserve">
|
||||
<value>Delete message</value>
|
||||
</data>
|
||||
<data name="DisplayNameDialogTitle" xml:space="preserve">
|
||||
<value>Save as...</value>
|
||||
</data>
|
||||
</root>
|
@ -0,0 +1,96 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using PettingZoo.Core.ExportImport.Publisher;
|
||||
using PettingZoo.Core.Settings;
|
||||
using PettingZoo.WPF.ViewModel;
|
||||
|
||||
namespace PettingZoo.UI.Tab.Publisher
|
||||
{
|
||||
public class StoredPublisherMessagesViewModel
|
||||
{
|
||||
private readonly IPublisherMessagesRepository publisherMessagesRepository;
|
||||
|
||||
|
||||
public ObservableCollectionEx<StoredPublisherMessage> StoredMessages { get; } = new();
|
||||
|
||||
|
||||
public StoredPublisherMessagesViewModel(IPublisherMessagesRepository publisherMessagesRepository)
|
||||
{
|
||||
this.publisherMessagesRepository = publisherMessagesRepository;
|
||||
|
||||
|
||||
Task.Run(async () =>
|
||||
{
|
||||
var messages = await publisherMessagesRepository.GetStored();
|
||||
|
||||
await Application.Current.Dispatcher.BeginInvoke(() =>
|
||||
{
|
||||
StoredMessages.ReplaceAll(messages);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public void Save(StoredPublisherMessage overwriteMessage, PublisherMessage message, Action<StoredPublisherMessage> onSaved)
|
||||
{
|
||||
Task.Run(async () =>
|
||||
{
|
||||
var updatedMessage = await publisherMessagesRepository.Update(overwriteMessage.Id, overwriteMessage.DisplayName, message);
|
||||
|
||||
await Application.Current.Dispatcher.BeginInvoke(() =>
|
||||
{
|
||||
var index = StoredMessages.IndexOf(overwriteMessage);
|
||||
if (index >= 0)
|
||||
StoredMessages[index] = updatedMessage;
|
||||
else
|
||||
// Should not occur, but might as well handle it gracefully
|
||||
StoredMessages.Add(updatedMessage);
|
||||
|
||||
onSaved(updatedMessage);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public void SaveAs(PublisherMessage message, string? originalDisplayName, Action<StoredPublisherMessage> onSaved)
|
||||
{
|
||||
var displayName = originalDisplayName ?? "";
|
||||
if (!InputDialog.Execute(ref displayName, StoredPublisherMessagesStrings.DisplayNameDialogTitle))
|
||||
return;
|
||||
|
||||
Task.Run(async () =>
|
||||
{
|
||||
var storedMessage = await publisherMessagesRepository.Add(displayName, message);
|
||||
|
||||
await Application.Current.Dispatcher.BeginInvoke(() =>
|
||||
{
|
||||
StoredMessages.Add(storedMessage);
|
||||
onSaved(storedMessage);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public void Delete(StoredPublisherMessage message, Action onDeleted)
|
||||
{
|
||||
if (MessageBox.Show(
|
||||
string.Format(StoredPublisherMessagesStrings.DeleteConfirmation, message.DisplayName),
|
||||
StoredPublisherMessagesStrings.DeleteConfirmationTitle,
|
||||
MessageBoxButton.YesNo,
|
||||
MessageBoxImage.Question) != MessageBoxResult.Yes)
|
||||
return;
|
||||
|
||||
Task.Run(async () =>
|
||||
{
|
||||
await publisherMessagesRepository.Delete(message.Id);
|
||||
|
||||
await Application.Current.Dispatcher.BeginInvoke(() =>
|
||||
{
|
||||
StoredMessages.Remove(message);
|
||||
onDeleted();
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,5 @@
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using PettingZoo.Core.Macros;
|
||||
|
||||
namespace PettingZoo.UI.Tab.Publisher
|
||||
{
|
||||
|
@ -3,6 +3,7 @@ using System.Text;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
using PettingZoo.Core.Connection;
|
||||
using PettingZoo.Core.ExportImport.Publisher;
|
||||
using PettingZoo.Core.Generator;
|
||||
using PettingZoo.Core.Macros;
|
||||
using PettingZoo.Core.Validation;
|
||||
@ -132,6 +133,29 @@ namespace PettingZoo.UI.Tab.Publisher
|
||||
}
|
||||
|
||||
|
||||
public TapetiPublisherMessage GetPublisherMessage()
|
||||
{
|
||||
return new TapetiPublisherMessage
|
||||
{
|
||||
CorrelationId = CorrelationId,
|
||||
Payload = Payload,
|
||||
EnableMacros = EnableMacros,
|
||||
ClassName = ClassName,
|
||||
AssemblyName = AssemblyName
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public void LoadPublisherMessage(TapetiPublisherMessage message)
|
||||
{
|
||||
CorrelationId = message.CorrelationId ?? "";
|
||||
Payload = message.Payload ?? "";
|
||||
EnableMacros = message.EnableMacros;
|
||||
ClassName = message.ClassName ?? "";
|
||||
AssemblyName = message.AssemblyName ?? "";
|
||||
}
|
||||
|
||||
|
||||
private void BrowseClassExecute()
|
||||
{
|
||||
exampleGenerator.Select(tabHostWindow, example =>
|
||||
|
@ -8,6 +8,7 @@
|
||||
xmlns:svgc="http://sharpvectors.codeplex.com/svgc/"
|
||||
xmlns:avalonedit="http://icsharpcode.net/sharpdevelop/avalonedit"
|
||||
xmlns:connection="clr-namespace:PettingZoo.Core.Connection;assembly=PettingZoo.Core"
|
||||
xmlns:controls="clr-namespace:PettingZoo.WPF.Controls;assembly=PettingZoo.WPF"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450"
|
||||
d:DesignWidth="800"
|
||||
@ -36,8 +37,8 @@
|
||||
<ListBox.ItemsSource>
|
||||
<CompositeCollection>
|
||||
<CollectionContainer Collection="{Binding Source={StaticResource Messages}}" />
|
||||
<ListBoxItem HorizontalContentAlignment="Stretch" IsEnabled="False" IsHitTestVisible="False">
|
||||
<Grid Visibility="{Binding UnreadMessagesVisibility}">
|
||||
<ListBoxItem HorizontalContentAlignment="Stretch" IsEnabled="False" IsHitTestVisible="False" Visibility="{Binding UnreadMessagesVisibility}">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition SharedSizeGroup="DateTime" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
@ -50,6 +51,17 @@
|
||||
</Grid>
|
||||
</ListBoxItem>
|
||||
<CollectionContainer Collection="{Binding Source={StaticResource UnreadMessages}}" />
|
||||
<ListBoxItem HorizontalContentAlignment="Stretch" IsEnabled="False" IsHitTestVisible="False" Visibility="{Binding StatusVisibility}">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition SharedSizeGroup="DateTime" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<TextBlock Grid.Column="1" Text="{Binding StatusText}" HorizontalAlignment="Center" Background="{Binding Background, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}}" Foreground="{x:Static SystemColors.GrayTextBrush}" />
|
||||
</Grid>
|
||||
</ListBoxItem>
|
||||
</CompositeCollection>
|
||||
</ListBox.ItemsSource>
|
||||
<ListBox.ItemTemplate>
|
||||
@ -82,14 +94,14 @@
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="200"/>
|
||||
</Grid.RowDefinitions>
|
||||
<ToolBar Grid.Column="0" Grid.Row="0" ToolBarTray.IsLocked="True" Margin="0,0,0,4" Background="Transparent" Loaded="Toolbar_Loaded">
|
||||
<controls:AutoOverflowToolBar Grid.Column="0" Grid.Row="0" ToolBarTray.IsLocked="True" Margin="0,0,0,4" Background="Transparent">
|
||||
<Button Command="{Binding CreatePublisherCommand}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Image Source="{svgc:SvgImage Source=/Images/Publish.svg, AppName=PettingZoo}" Width="16" Height="16" Style="{StaticResource ToolbarIcon}"/>
|
||||
<TextBlock Margin="3,0,0,0" Text="{x:Static res:SubscriberViewStrings.ContextPublish}" />
|
||||
</StackPanel>
|
||||
</Button>
|
||||
</ToolBar>
|
||||
</controls:AutoOverflowToolBar>
|
||||
|
||||
<Border Grid.Column="0" Grid.Row="1" Style="{StaticResource SidePanel}">
|
||||
<DockPanel>
|
||||
|
@ -1,6 +1,4 @@
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media;
|
||||
using ICSharpCode.AvalonEdit.Highlighting;
|
||||
|
||||
namespace PettingZoo.UI.Tab.Subscriber
|
||||
@ -35,17 +33,5 @@ namespace PettingZoo.UI.Tab.Subscriber
|
||||
if (!System.ComponentModel.DesignerProperties.GetIsInDesignMode(this))
|
||||
Background = Brushes.Transparent;
|
||||
}
|
||||
|
||||
private void Toolbar_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
// Hide arrow on the right side of the toolbar
|
||||
var toolBar = sender as ToolBar;
|
||||
|
||||
if (toolBar?.Template.FindName("OverflowGrid", toolBar) is FrameworkElement overflowGrid)
|
||||
overflowGrid.Visibility = Visibility.Collapsed;
|
||||
|
||||
if (toolBar?.Template.FindName("MainPanelBorder", toolBar) is FrameworkElement mainPanelBorder)
|
||||
mainPanelBorder.Margin = new Thickness(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ using System.Windows;
|
||||
using System.Windows.Forms;
|
||||
using System.Windows.Input;
|
||||
using PettingZoo.Core.Connection;
|
||||
using PettingZoo.Core.ExportImport;
|
||||
using PettingZoo.Core.ExportImport.Subscriber;
|
||||
using PettingZoo.Core.Rendering;
|
||||
using PettingZoo.WPF.ProgressWindow;
|
||||
using PettingZoo.WPF.ViewModel;
|
||||
@ -25,7 +25,7 @@ namespace PettingZoo.UI.Tab.Subscriber
|
||||
{
|
||||
private readonly ILogger logger;
|
||||
private readonly ITabFactory tabFactory;
|
||||
private readonly IConnection? connection;
|
||||
private readonly IConnection connection;
|
||||
private readonly ISubscriber subscriber;
|
||||
private readonly IExportImportFormatProvider exportImportFormatProvider;
|
||||
private ReceivedMessageInfo? selectedMessage;
|
||||
@ -106,8 +106,14 @@ namespace PettingZoo.UI.Tab.Subscriber
|
||||
public Visibility ReplyTabVisibility => IsReplyTab ? Visibility.Visible : Visibility.Collapsed;
|
||||
// ReSharper restore UnusedMember.Global
|
||||
|
||||
private readonly Guid subscribeConnectionId;
|
||||
private ConnectionStatus connectionStatus = ConnectionStatus.Connecting;
|
||||
|
||||
public SubscriberViewModel(ILogger logger, ITabFactory tabFactory, IConnection? connection, ISubscriber subscriber, IExportImportFormatProvider exportImportFormatProvider, bool isReplyTab)
|
||||
public Visibility StatusVisibility => connectionStatus is ConnectionStatus.Connecting or ConnectionStatus.Disconnected or ConnectionStatus.Error ? Visibility.Visible : Visibility.Collapsed;
|
||||
public string StatusText => connectionStatus == ConnectionStatus.Connecting ? SubscriberViewStrings.StatusConnecting : SubscriberViewStrings.StatusDisconnected;
|
||||
|
||||
|
||||
public SubscriberViewModel(ILogger logger, ITabFactory tabFactory, IConnection connection, ISubscriber subscriber, IExportImportFormatProvider exportImportFormatProvider, bool isReplyTab)
|
||||
{
|
||||
IsReplyTab = isReplyTab;
|
||||
|
||||
@ -133,6 +139,8 @@ namespace PettingZoo.UI.Tab.Subscriber
|
||||
|
||||
createPublisherCommand = new DelegateCommand(CreatePublisherExecute, CreatePublisherCanExecute);
|
||||
|
||||
subscribeConnectionId = connection.ConnectionId;
|
||||
connection.StatusChanged += ConnectionStatusChanged;
|
||||
subscriber.MessageReceived += SubscriberMessageReceived;
|
||||
subscriber.Start();
|
||||
}
|
||||
@ -141,11 +149,47 @@ namespace PettingZoo.UI.Tab.Subscriber
|
||||
public void Dispose()
|
||||
{
|
||||
GC.SuppressFinalize(this);
|
||||
connection.StatusChanged -= ConnectionStatusChanged;
|
||||
newMessageTimer?.Dispose();
|
||||
subscriber.Dispose();
|
||||
}
|
||||
|
||||
|
||||
private void ConnectionStatusChanged(object? sender, StatusChangedEventArgs e)
|
||||
{
|
||||
// If another connection has been made, this does not concern us
|
||||
if (e.ConnectionId != subscribeConnectionId)
|
||||
return;
|
||||
|
||||
// The subscriber will not reconnect, so after the first disconnect it's over for us
|
||||
if (connectionStatus is ConnectionStatus.Disconnected)
|
||||
return;
|
||||
|
||||
switch (e.Status)
|
||||
{
|
||||
case ConnectionStatus.Connecting:
|
||||
case ConnectionStatus.Error:
|
||||
return;
|
||||
|
||||
case ConnectionStatus.Connected:
|
||||
connectionStatus = ConnectionStatus.Connected;
|
||||
break;
|
||||
|
||||
case ConnectionStatus.Disconnected:
|
||||
default:
|
||||
connectionStatus = ConnectionStatus.Disconnected;
|
||||
break;
|
||||
}
|
||||
|
||||
Application.Current.Dispatcher.BeginInvoke(() =>
|
||||
{
|
||||
|
||||
RaisePropertyChanged(nameof(StatusVisibility));
|
||||
RaisePropertyChanged(nameof(StatusText));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private void ClearExecute()
|
||||
{
|
||||
Messages.Clear();
|
||||
@ -254,7 +298,7 @@ namespace PettingZoo.UI.Tab.Subscriber
|
||||
|
||||
private void CreatePublisherExecute()
|
||||
{
|
||||
if (connection == null)
|
||||
if (connection.Status != ConnectionStatus.Connected)
|
||||
return;
|
||||
|
||||
tabFactory.CreatePublisherTab(connection, SelectedMessage);
|
||||
@ -263,7 +307,7 @@ namespace PettingZoo.UI.Tab.Subscriber
|
||||
|
||||
private bool CreatePublisherCanExecute()
|
||||
{
|
||||
return connection != null && SelectedMessage != null;
|
||||
return SelectedMessage != null;
|
||||
}
|
||||
|
||||
|
||||
|
@ -194,5 +194,23 @@ namespace PettingZoo.UI.Tab.Subscriber {
|
||||
return ResourceManager.GetString("ReplyTabTitle", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Connecting....
|
||||
/// </summary>
|
||||
public static string StatusConnecting {
|
||||
get {
|
||||
return ResourceManager.GetString("StatusConnecting", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Disconnected.
|
||||
/// </summary>
|
||||
public static string StatusDisconnected {
|
||||
get {
|
||||
return ResourceManager.GetString("StatusDisconnected", resourceCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -162,4 +162,10 @@
|
||||
<data name="ReplyTabTitle" xml:space="preserve">
|
||||
<value>Replies</value>
|
||||
</data>
|
||||
<data name="StatusConnecting" xml:space="preserve">
|
||||
<value>Connecting...</value>
|
||||
</data>
|
||||
<data name="StatusDisconnected" xml:space="preserve">
|
||||
<value>Disconnected</value>
|
||||
</data>
|
||||
</root>
|
@ -5,6 +5,7 @@
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:undocked="clr-namespace:PettingZoo.UI.Tab.Undocked"
|
||||
xmlns:svgc="http://sharpvectors.codeplex.com/svgc/"
|
||||
xmlns:controls="clr-namespace:PettingZoo.WPF.Controls;assembly=PettingZoo.WPF"
|
||||
mc:Ignorable="d"
|
||||
d:DataContext="{d:DesignInstance undocked:DesignTimeUndockedTabHostViewModel, IsDesignTimeCreatable=True}"
|
||||
Title="{Binding Title}"
|
||||
@ -12,7 +13,7 @@
|
||||
Width="800"
|
||||
WindowStyle="ThreeDBorderWindow">
|
||||
<DockPanel>
|
||||
<ToolBar DockPanel.Dock="Top" ToolBarTray.IsLocked="True" Loaded="Toolbar_Loaded">
|
||||
<controls:AutoOverflowToolBar DockPanel.Dock="Top" ToolBarTray.IsLocked="True">
|
||||
<Button Command="{Binding DockCommand}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Image Source="{svgc:SvgImage Source=/Images/Dock.svg, AppName=PettingZoo}" Width="16" Height="16" Style="{StaticResource ToolbarIcon}"/>
|
||||
@ -37,7 +38,7 @@
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</ToolBar>
|
||||
</controls:AutoOverflowToolBar>
|
||||
|
||||
<ContentControl Content="{Binding Content}" />
|
||||
</DockPanel>
|
||||
|
@ -1,7 +1,4 @@
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace PettingZoo.UI.Tab.Undocked
|
||||
namespace PettingZoo.UI.Tab.Undocked
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for UndockedTabHostWindow.xaml
|
||||
@ -41,17 +38,5 @@ namespace PettingZoo.UI.Tab.Undocked
|
||||
viewModel.Deactivate();
|
||||
};
|
||||
}
|
||||
|
||||
private void Toolbar_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
// Hide arrow on the right side of the toolbar
|
||||
var toolBar = sender as ToolBar;
|
||||
|
||||
if (toolBar?.Template.FindName("OverflowGrid", toolBar) is FrameworkElement overflowGrid)
|
||||
overflowGrid.Visibility = Visibility.Collapsed;
|
||||
|
||||
if (toolBar?.Template.FindName("MainPanelBorder", toolBar) is FrameworkElement mainPanelBorder)
|
||||
mainPanelBorder.Margin = new Thickness(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using PettingZoo.Core.Connection;
|
||||
using PettingZoo.Core.ExportImport;
|
||||
using PettingZoo.Core.ExportImport.Subscriber;
|
||||
using PettingZoo.Core.Generator;
|
||||
using PettingZoo.Core.Macros;
|
||||
using PettingZoo.UI.Tab.Publisher;
|
||||
@ -17,6 +17,7 @@ namespace PettingZoo.UI.Tab
|
||||
private readonly IExampleGenerator exampleGenerator;
|
||||
private readonly IExportImportFormatProvider exportImportFormatProvider;
|
||||
private readonly IPayloadMacroProcessor payloadMacroProcessor;
|
||||
private readonly StoredPublisherMessagesViewModel storedPublisherMessagesViewModel;
|
||||
|
||||
// Not the cleanest way, but this factory itself can't be singleton without (justifyable) upsetting SimpleInjector
|
||||
private static ISubscriber? replySubscriber;
|
||||
@ -24,17 +25,18 @@ namespace PettingZoo.UI.Tab
|
||||
|
||||
|
||||
public ViewTabFactory(ILogger logger, ITabHostProvider tabHostProvider, IExampleGenerator exampleGenerator, IExportImportFormatProvider exportImportFormatProvider,
|
||||
IPayloadMacroProcessor payloadMacroProcessor)
|
||||
IPayloadMacroProcessor payloadMacroProcessor, StoredPublisherMessagesViewModel storedPublisherMessagesViewModel)
|
||||
{
|
||||
this.logger = logger;
|
||||
this.tabHostProvider = tabHostProvider;
|
||||
this.exampleGenerator = exampleGenerator;
|
||||
this.exportImportFormatProvider = exportImportFormatProvider;
|
||||
this.payloadMacroProcessor = payloadMacroProcessor;
|
||||
this.storedPublisherMessagesViewModel = storedPublisherMessagesViewModel;
|
||||
}
|
||||
|
||||
|
||||
public void CreateSubscriberTab(IConnection? connection, ISubscriber subscriber)
|
||||
public void CreateSubscriberTab(IConnection connection, ISubscriber subscriber)
|
||||
{
|
||||
InternalCreateSubscriberTab(connection, subscriber, false);
|
||||
}
|
||||
@ -63,7 +65,7 @@ namespace PettingZoo.UI.Tab
|
||||
|
||||
public void CreatePublisherTab(IConnection connection, ReceivedMessageInfo? fromReceivedMessage = null)
|
||||
{
|
||||
var viewModel = new PublisherViewModel(this, connection, exampleGenerator, payloadMacroProcessor, fromReceivedMessage);
|
||||
var viewModel = new PublisherViewModel(this, connection, exampleGenerator, payloadMacroProcessor, storedPublisherMessagesViewModel, fromReceivedMessage);
|
||||
var tab = new ViewTab<PublisherView, PublisherViewModel>(
|
||||
new PublisherView(viewModel),
|
||||
viewModel,
|
||||
@ -73,7 +75,7 @@ namespace PettingZoo.UI.Tab
|
||||
}
|
||||
|
||||
|
||||
private ITab InternalCreateSubscriberTab(IConnection? connection, ISubscriber subscriber, bool isReplyTab)
|
||||
private ITab InternalCreateSubscriberTab(IConnection connection, ISubscriber subscriber, bool isReplyTab)
|
||||
{
|
||||
var viewModel = new SubscriberViewModel(logger, this, connection, subscriber, exportImportFormatProvider, isReplyTab);
|
||||
var tab = new ViewTab<SubscriberView, SubscriberViewModel>(
|
||||
|
@ -2,7 +2,7 @@ image: Visual Studio 2022
|
||||
|
||||
|
||||
install:
|
||||
- choco install gitversion.portable -pre -y
|
||||
- choco install gitversion.portable -pre -y --version 5.12.0
|
||||
|
||||
before_build:
|
||||
- nuget restore
|
||||
@ -31,7 +31,7 @@ configuration:
|
||||
deploy:
|
||||
- provider: GitHub
|
||||
auth_token:
|
||||
secure: dWOConKg3VTPvd9DmWOOKiX1SJCalaqKInuk9GlKQOZX2s+Bia49J7q+AHO8wFj7
|
||||
secure: l7meLHe4l/JZh+J0Gfd+Z+fMviSg3FDz4mIjp+S+PGdPgkpcc45t8Ae3EP2+dTGJkTvhSKNZB5Hmc76DOpfNKfrIQdBlQLDrQVS1nZRunjqL0klHVFRKqvwyH0DK5GK3
|
||||
artifact: /PettingZoo-.*\.zip/
|
||||
draft: false
|
||||
prerelease: false
|
||||
|