From 1f2df53c1259e7d33016bd98400d83a62d0a363a Mon Sep 17 00:00:00 2001 From: Mikhail Mitrofanov Date: Mon, 3 Feb 2025 10:06:05 +0300 Subject: [PATCH] =?UTF-8?q?=D0=BD=D0=B0=D1=87=D0=B0=D0=BB=D0=BE=20=D0=BA?= =?UTF-8?q?=D0=BE=D0=B4=D0=B3=D0=B5=D0=BD=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mROA.Test/ITestController.cs | 45 ++++++++++++++++++ mROA.Test/StreamTest.cs | 24 +++++++--- mROA.Test/obj/mROA.Test.csproj.nuget.g.props | 6 +-- mROA/Abstract/IContextRepository.cs | 7 ++- mROA/Implementation/ContextRepository.cs | 17 +++++-- .../FrontendContextRepository.cs | 47 +++++++++++++++++++ mROA/Implementation/IRemoteObject.cs | 6 +++ .../StreamBasedInteractionModule.cs | 11 ++--- mROA/Implementation/Test/MockExecModule.cs | 10 +++- .../Implementation/TransmittedSharedObject.cs | 7 +-- mROA/obj/mROA.csproj.nuget.g.props | 4 +- 11 files changed, 152 insertions(+), 32 deletions(-) create mode 100644 mROA/Implementation/FrontendContextRepository.cs create mode 100644 mROA/Implementation/IRemoteObject.cs diff --git a/mROA.Test/ITestController.cs b/mROA.Test/ITestController.cs index 5f02545..c4f1f47 100644 --- a/mROA.Test/ITestController.cs +++ b/mROA.Test/ITestController.cs @@ -116,4 +116,49 @@ public class TestParameter { public int A { get; set; } public TransmittedSharedObject LinkedObject { get; set; } +} + +public class TestControllerRemoteEndoint : ITestController, IRemoteObject +{ + public TestControllerRemoteEndoint(int id) + { + _id = id; + } + public void A() + { + + } + + public Task AAsync(CancellationToken cancellationToken) + { + + } + + public int B() + { + + } + + public Task BAsync(CancellationToken cancellationToken) + { + + } + + public TransmittedSharedObject SharedObjectTransmitionTest() + { + + } + + public int Parametrized(TestParameter parameter) + { + + } + + public TransmittedSharedObject GetTestParameter() + { + + } + + private int _id; + public int Id => _id; } \ No newline at end of file diff --git a/mROA.Test/StreamTest.cs b/mROA.Test/StreamTest.cs index 54dc398..d723677 100644 --- a/mROA.Test/StreamTest.cs +++ b/mROA.Test/StreamTest.cs @@ -1,5 +1,6 @@ using System.Net; using System.Net.Sockets; +using System.Text.Json; using mROA.Implementation; using mROA.Implementation.Test; @@ -12,6 +13,7 @@ public class StreamTest private JsonFrontendSerialisationModule _frontendSerialisationModule; private ISerialisationModule _serialisationModule; private IExecuteModule _executeModule; + bool isTestNotFinished = true; [SetUp] public void Setup() @@ -25,12 +27,7 @@ public class StreamTest _frontendInteractionModule = new StreamBasedFrontendInteractionModule(); _frontendSerialisationModule = new JsonFrontendSerialisationModule(_frontendInteractionModule); - } - - [Test] - public void StreamingTest() - { - bool isTestNotFinished = true; + Task.Run(() => { TcpListener listener = new TcpListener(IPAddress.Loopback, 4567); @@ -44,13 +41,26 @@ public class StreamTest while (isTestNotFinished) ; }); + } + + [Test] + public void StreamingTest() + { var tcpClient = new TcpClient(); tcpClient.Connect(IPAddress.Loopback, 4567); _frontendInteractionModule.ServerStream = tcpClient.GetStream(); var req = new JsonCallRequest { CommandId = 1, ObjectId = -1 }; _frontendSerialisationModule.PostCallRequest(req); - var res =_frontendSerialisationModule.GetNextCommandExecution(req.CallRequestId).Result; + var res = ((JsonElement)_frontendSerialisationModule.GetNextCommandExecution(req.CallRequestId).Result).Deserialize(); isTestNotFinished = false; + Assert.That(res.A == "wqer" && res.B == 5); } + + [Test] + public void RemoteObjectTest() + { + + } + } \ No newline at end of file diff --git a/mROA.Test/obj/mROA.Test.csproj.nuget.g.props b/mROA.Test/obj/mROA.Test.csproj.nuget.g.props index 92a05d6..f0b8464 100644 --- a/mROA.Test/obj/mROA.Test.csproj.nuget.g.props +++ b/mROA.Test/obj/mROA.Test.csproj.nuget.g.props @@ -5,12 +5,12 @@ NuGet $(MSBuildThisFileDirectory)project.assets.json $(UserProfile)\.nuget\packages\ - C:\Users\Mikhail\.nuget\packages\;C:\Program Files (x86)\Microsoft Visual Studio\Shared\NuGetPackages + C:\Users\Mimm\.nuget\packages\;C:\Program Files (x86)\Microsoft Visual Studio\Shared\NuGetPackages PackageReference 6.12.0 - + @@ -21,6 +21,6 @@ - C:\Users\Mikhail\.nuget\packages\nunit.analyzers\4.6.0 + C:\Users\Mimm\.nuget\packages\nunit.analyzers\4.6.0 \ No newline at end of file diff --git a/mROA/Abstract/IContextRepository.cs b/mROA/Abstract/IContextRepository.cs index e11c95c..a06b3e3 100644 --- a/mROA/Abstract/IContextRepository.cs +++ b/mROA/Abstract/IContextRepository.cs @@ -1,10 +1,13 @@ -namespace mROA; +using mROA.Implementation; + +namespace mROA; public interface IContextRepository { int ResisterObject(object o); void ClearObject(int id); - object GetObject(int id); + object? GetObject(int id); + T? GetObject(int id); object GetSingleObject(Type type); int GetObjectIndex(object o); } \ No newline at end of file diff --git a/mROA/Implementation/ContextRepository.cs b/mROA/Implementation/ContextRepository.cs index e60d5f3..62d129d 100644 --- a/mROA/Implementation/ContextRepository.cs +++ b/mROA/Implementation/ContextRepository.cs @@ -24,14 +24,18 @@ public class ContextRepository : IContextRepository var types = assembly.GetTypes().Where(type => type is { IsClass: true, IsAbstract: false, IsGenericType: false } && type.GetCustomAttributes(typeof(SharedObjectSingletonAttribute), true).Length > 0); - _singletons = types.ToFrozenDictionary(t => t.GetInterfaces().FirstOrDefault(i => i.GetCustomAttributes(typeof(SharedObjectInterafceAttribute), true).Length > 0)!.GetHashCode(), Activator.CreateInstance); + _singletons = + types.ToFrozenDictionary( + t => t.GetInterfaces().FirstOrDefault(i => + i.GetCustomAttributes(typeof(SharedObjectInterafceAttribute), true).Length > 0)!.GetHashCode(), + Activator.CreateInstance); } public int ResisterObject(object o) { if (!_lastIndexFinder.IsCompleted) _lastIndexFinder.Wait(); - + _storage[_lastIndexFinder.Result] = o; var last = _lastIndexFinder.Result; @@ -46,14 +50,19 @@ public class ContextRepository : IContextRepository _lastIndexFinder = Task.FromResult(id); } - public object GetObject(int id) + public object? GetObject(int id) { return id == -1 || _storage.Length <= id ? null : _storage[id]; } + public T GetObject(int id) + { + return id == -1 || _storage.Length <= id ? throw new NullReferenceException("Cannot find that object. It is null"): (T)_storage[id]; + } + public object GetSingleObject(Type type) { - return _singletons.GetValueOrDefault(type.GetHashCode()); + return _singletons.GetValueOrDefault(type.GetHashCode()) ?? throw new ArgumentException("Unregistered singleton type"); } public int GetObjectIndex(object o) diff --git a/mROA/Implementation/FrontendContextRepository.cs b/mROA/Implementation/FrontendContextRepository.cs new file mode 100644 index 0000000..4a90c58 --- /dev/null +++ b/mROA/Implementation/FrontendContextRepository.cs @@ -0,0 +1,47 @@ +using System.Collections.Frozen; + +namespace mROA.Implementation; + +public class FrontendContextRepository(Dictionary remoteTypes) : IContextRepository +{ + private FrozenDictionary _remoteTypes = remoteTypes.ToFrozenDictionary(); + + public int ResisterObject(object o) + { + throw new NotSupportedException(); + } + + public void ClearObject(int id) + { + throw new NotSupportedException(); + } + + public object GetObject(int id) + { + throw new NotSupportedException(); + } + + public T GetObject(int id) + { + if (_remoteTypes.TryGetValue(typeof(T), out var remoteType)) + { + var remote = (T)Activator.CreateInstance(remoteType, id)!; + return remote; + } + throw new NotSupportedException(); + } + + public object GetSingleObject(Type type) + { + throw new NotSupportedException(); + } + + public int GetObjectIndex(object o) + { + if (o is IRemoteObject remote) + { + return remote.Id; + } + throw new NotSupportedException(); + } +} \ No newline at end of file diff --git a/mROA/Implementation/IRemoteObject.cs b/mROA/Implementation/IRemoteObject.cs new file mode 100644 index 0000000..435c23a --- /dev/null +++ b/mROA/Implementation/IRemoteObject.cs @@ -0,0 +1,6 @@ +namespace mROA.Implementation; + +public interface IRemoteObject +{ + internal int Id { get; } +} \ No newline at end of file diff --git a/mROA/Implementation/StreamBasedInteractionModule.cs b/mROA/Implementation/StreamBasedInteractionModule.cs index 792aafb..4b7c2eb 100644 --- a/mROA/Implementation/StreamBasedInteractionModule.cs +++ b/mROA/Implementation/StreamBasedInteractionModule.cs @@ -4,14 +4,14 @@ public class StreamBasedInteractionModule : IInteractionModule { private Dictionary _streams = new(); private Action _handler; - + public void RegisterClient(Stream stream) { var id = Random.Shared.Next(); _streams.Add(id, stream); ListenTo((id, stream), _handler); } - + public void SetMessageHandler(Action handler) { _handler = handler; @@ -26,7 +26,6 @@ public class StreamBasedInteractionModule : IInteractionModule stream.Write(BitConverter.GetBytes((ushort)message.Length), 0, sizeof(ushort)); stream.Write(message, 0, message.Length); - } private async Task ListenTo((int id, Stream stream) client, Action action) @@ -40,15 +39,13 @@ public class StreamBasedInteractionModule : IInteractionModule await client.stream.ReadExactlyAsync(buffer, 0, 2); var len = BitConverter.ToUInt16(buffer, 0); await client.stream.ReadExactlyAsync(buffer, 0, len); - - action(client.id, buffer[..len]); + Task.Run(() => action(client.id, buffer[..len])); } } - catch (Exception e) + catch (Exception) { Console.WriteLine($"Client handling finished:{client.id}"); _streams.Remove(client.id); } - } } \ No newline at end of file diff --git a/mROA/Implementation/Test/MockExecModule.cs b/mROA/Implementation/Test/MockExecModule.cs index 36e9f02..5f79c30 100644 --- a/mROA/Implementation/Test/MockExecModule.cs +++ b/mROA/Implementation/Test/MockExecModule.cs @@ -1,10 +1,16 @@ -namespace mROA.Implementation; +namespace mROA.Implementation.Test; public class MockExecModule : IExecuteModule { public ICommandExecution Execute(ICallRequest command) { return new FinalCommandExecution - { CommandId = command.CommandId, Result = new { A = "wqer", B = 5 }, CallRequestId = command.CallRequestId }; + { CommandId = command.CommandId, Result = new MockResult { A = "wqer", B = 5 }, CallRequestId = command.CallRequestId }; } +} + +public class MockResult +{ + public string A { get; set; } + public int B { get; set; } } \ No newline at end of file diff --git a/mROA/Implementation/TransmittedSharedObject.cs b/mROA/Implementation/TransmittedSharedObject.cs index 35a8c10..ceac482 100644 --- a/mROA/Implementation/TransmittedSharedObject.cs +++ b/mROA/Implementation/TransmittedSharedObject.cs @@ -12,16 +12,13 @@ public class TransmittedSharedObject public int ContextId { get; set; } = -1; [JsonIgnore] - public T Value => (T)TransmissionConfig.DefaultContextRepository.GetObject(ContextId); + public T? Value => TransmissionConfig.DefaultContextRepository.GetObject(ContextId); [JsonIgnore] public IContextRepository Context { get; set; } - public static implicit operator T(TransmittedSharedObject value) => value.Value; + public static implicit operator T(TransmittedSharedObject value) => value.Value!; public static implicit operator TransmittedSharedObject(T value) => new() { ContextId = TransmissionConfig.DefaultContextRepository.GetObjectIndex(value) }; - - // public void Fill() => Value = (T)TransmissionConfig.DefaultContextRepository.GetObject(ContextId); - // public void Collect() => ContextId = TransmissionConfig.DefaultContextRepository.GetObjectIndex(ContextId); } \ No newline at end of file diff --git a/mROA/obj/mROA.csproj.nuget.g.props b/mROA/obj/mROA.csproj.nuget.g.props index 721d876..7f9c9db 100644 --- a/mROA/obj/mROA.csproj.nuget.g.props +++ b/mROA/obj/mROA.csproj.nuget.g.props @@ -5,12 +5,12 @@ NuGet $(MSBuildThisFileDirectory)project.assets.json $(UserProfile)\.nuget\packages\ - C:\Users\Mikhail\.nuget\packages\;C:\Program Files (x86)\Microsoft Visual Studio\Shared\NuGetPackages + C:\Users\Mimm\.nuget\packages\;C:\Program Files (x86)\Microsoft Visual Studio\Shared\NuGetPackages PackageReference 6.12.0 - + \ No newline at end of file