что то неожиданно сломалось после рефакторинга
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
using Example.Backend;
|
||||
using Example.Shared;
|
||||
using mROA.Implementation;
|
||||
using mROA.Implementation.Attributes;
|
||||
|
||||
namespace Example.Backend;
|
||||
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
using System.Net;
|
||||
using Example.Backend;
|
||||
using mROA.Abstract;
|
||||
using mROA.Codegen;
|
||||
using mROA.Implementation;
|
||||
using mROA.Implementation.Backend;
|
||||
using mROA.Implementation.Bootstrap;
|
||||
|
||||
|
||||
@@ -14,6 +16,7 @@ bootstrap.UseCollectableContextRepository(typeof(PrinterFactory).Assembly);
|
||||
bootstrap.SetupMethodsRepository(new CoCodegenMethodRepository());
|
||||
bootstrap.Build();
|
||||
|
||||
var gateway = bootstrap.GetModule<IGatewayModule>();
|
||||
|
||||
var gateway = bootstrap.GetModule<IGatewayModule>() ;
|
||||
|
||||
gateway.Run();
|
||||
@@ -4,8 +4,9 @@
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using mROA.Codegen;
|
||||
using mROA.Implementation;
|
||||
using mROA.Implementation.Bootstrap;
|
||||
using mROA.Implementation.Frontend;
|
||||
|
||||
|
||||
var mixer = new FullMixBuilder();
|
||||
|
||||
@@ -15,6 +16,8 @@ mixer.Modules.Add(new StreamBasedFrontendInteractionModule());
|
||||
mixer.Modules.Add(new NetworkFrontendBridge(new IPEndPoint(IPAddress.Loopback, 4567)));
|
||||
|
||||
mixer.Build();
|
||||
|
||||
mixer.GetModule<NetworkFrontendBridge>().Connect();
|
||||
var context = mixer.GetModule<FrontendContextRepository>();
|
||||
|
||||
var factory = context.GetSingleObject(typeof(Example.Shared.IPrinterFactory)) as Example.Shared.IPrinterFactory;
|
||||
|
||||
@@ -7,10 +7,8 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\mROA.Codegen\mROA.Codegen.csproj"
|
||||
OutputItemType="Analyzer"
|
||||
ReferenceOutputAssembly="false"/>
|
||||
<ProjectReference Include="..\mROA\mROA.csproj" />
|
||||
<ProjectReference Include="..\mROA.Codegen\mROA.Codegen.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false"/>
|
||||
<ProjectReference Include="..\mROA\mROA.csproj"/>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using mROA.Implementation;
|
||||
using mROA.Implementation.Attributes;
|
||||
|
||||
namespace Example.Shared;
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using mROA.Implementation;
|
||||
using mROA.Implementation.Attributes;
|
||||
|
||||
namespace Example.Shared;
|
||||
|
||||
@@ -7,4 +8,5 @@ public interface IPrinter
|
||||
{
|
||||
string GetName();
|
||||
Task<TransmittedSharedObject<IPage>> Print(string text, CancellationToken cancellationToken);
|
||||
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using mROA.Implementation;
|
||||
using mROA.Implementation.Attributes;
|
||||
|
||||
namespace Example.Shared;
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ namespace {Namespace}
|
||||
string attributeName = attributeSymbol.ContainingType.ToDisplayString();
|
||||
|
||||
// Check the full name of the [Report] attribute.
|
||||
if (attributeName == "mROA.Implementation.SharedObjectInterfaceAttribute")
|
||||
if (attributeName == "mROA.Implementation.Attributes.SharedObjectInterfaceAttribute")
|
||||
return (classDeclarationSyntax, true);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace mROA;
|
||||
namespace mROA.Abstract;
|
||||
|
||||
public interface ICommandExecution
|
||||
{
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
using mROA.Abstract;
|
||||
using mROA.Implementation;
|
||||
|
||||
namespace mROA;
|
||||
namespace mROA.Abstract;
|
||||
|
||||
public interface IContextRepository : IInjectableModule
|
||||
{
|
||||
int ResisterObject(object o);
|
||||
void ClearObject(int id);
|
||||
object? GetObject(int id);
|
||||
object GetObject(int id);
|
||||
T? GetObject<T>(int id);
|
||||
object GetSingleObject(Type type);
|
||||
int GetObjectIndex(object o);
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using mROA.Abstract;
|
||||
using mROA.Implementation;
|
||||
|
||||
namespace mROA;
|
||||
namespace mROA.Abstract;
|
||||
|
||||
public interface IExecuteModule : IInjectableModule
|
||||
{
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
using mROA.Abstract;
|
||||
|
||||
namespace mROA.Implementation;
|
||||
namespace mROA.Abstract;
|
||||
|
||||
public interface IGatewayModule : IDisposable, IInjectableModule
|
||||
{
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
using mROA.Abstract;
|
||||
|
||||
namespace mROA;
|
||||
namespace mROA.Abstract;
|
||||
|
||||
public interface IInteractionModule : IInjectableModule
|
||||
{
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System.Reflection;
|
||||
using mROA.Abstract;
|
||||
|
||||
namespace mROA;
|
||||
namespace mROA.Abstract;
|
||||
|
||||
public interface IMethodRepository : IInjectableModule
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace mROA.Implementation;
|
||||
namespace mROA.Abstract;
|
||||
|
||||
public interface IRemoteObject
|
||||
{
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using mROA.Abstract;
|
||||
using mROA.Implementation;
|
||||
|
||||
namespace mROA;
|
||||
namespace mROA.Abstract;
|
||||
|
||||
public interface ISerialisationModule : IInjectableModule
|
||||
{
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
namespace mROA.Implementation;
|
||||
namespace mROA.Implementation.Attributes;
|
||||
|
||||
public class SharedObjectInterfaceAttribute : Attribute;
|
||||
@@ -1,3 +1,3 @@
|
||||
namespace mROA.Implementation;
|
||||
namespace mROA.Implementation.Attributes;
|
||||
|
||||
public class SharedObjectSingletonAttribute : Attribute;
|
||||
@@ -1,8 +1,9 @@
|
||||
using System.Net;
|
||||
using System.Reflection;
|
||||
using mROA.Abstract;
|
||||
using mROA.Implementation.Bootstrap;
|
||||
|
||||
namespace mROA.Implementation;
|
||||
namespace mROA.Implementation.Backend;
|
||||
|
||||
public static class BasicConfigurationExtensions
|
||||
{
|
||||
|
||||
@@ -1,32 +1,31 @@
|
||||
using System.Reflection;
|
||||
using mROA.Abstract;
|
||||
|
||||
namespace mROA.Implementation;
|
||||
namespace mROA.Implementation.Backend;
|
||||
|
||||
public class BasicExecutionModule : IExecuteModule
|
||||
{
|
||||
private IMethodRepository _methodRepo;
|
||||
private ISerialisationModule _serialisationModule;
|
||||
private IContextRepository _contextRepo;
|
||||
private IMethodRepository? _methodRepo;
|
||||
private IContextRepository? _contextRepo;
|
||||
|
||||
public void Inject<T>(T dependency)
|
||||
{
|
||||
if (dependency is IMethodRepository methodRepo)
|
||||
_methodRepo = methodRepo;
|
||||
if (dependency is ISerialisationModule serialisationModule)
|
||||
_serialisationModule = serialisationModule;
|
||||
|
||||
if (dependency is IContextRepository contextRepo)
|
||||
_contextRepo = contextRepo;
|
||||
}
|
||||
|
||||
public ICommandExecution Execute(ICallRequest command)
|
||||
{
|
||||
var currentCommand = _methodRepo.GetMethod(command.CommandId);
|
||||
var currentCommand = _methodRepo!.GetMethod(command.CommandId);
|
||||
if (currentCommand == null)
|
||||
throw new Exception($"Command {command.CommandId} not found");
|
||||
|
||||
var context = command.ObjectId != -1
|
||||
? _contextRepo.GetObject(command.ObjectId)
|
||||
: _contextRepo.GetSingleObject(currentCommand.DeclaringType!);
|
||||
? _contextRepo!.GetObject(command.ObjectId)
|
||||
: _contextRepo!.GetSingleObject(currentCommand.DeclaringType!);
|
||||
var parameter = command.Parameter;
|
||||
|
||||
if (currentCommand.ReturnType.BaseType == typeof(Task) &&
|
||||
@@ -57,7 +56,7 @@ public class BasicExecutionModule : IExecuteModule
|
||||
return new ExceptionCommandExecution
|
||||
{
|
||||
CallRequestId = command.CallRequestId, CommandId = command.CommandId,
|
||||
Exeption = e.ToString()
|
||||
Exception = e.ToString()
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -82,7 +81,7 @@ public class BasicExecutionModule : IExecuteModule
|
||||
return new ExceptionCommandExecution
|
||||
{
|
||||
CallRequestId = command.CallRequestId, CommandId = command.CommandId,
|
||||
Exeption = e.ToString()
|
||||
Exception = e.ToString()
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -105,7 +104,7 @@ public class BasicExecutionModule : IExecuteModule
|
||||
CallRequestId = command.CallRequestId,
|
||||
Result = finalResult,
|
||||
CommandId = command.CommandId,
|
||||
Type = finalResult.GetType()
|
||||
Type = finalResult?.GetType()
|
||||
};
|
||||
}
|
||||
catch (Exception e)
|
||||
@@ -113,7 +112,7 @@ public class BasicExecutionModule : IExecuteModule
|
||||
return new ExceptionCommandExecution
|
||||
{
|
||||
CallRequestId = command.CallRequestId, CommandId = command.CommandId,
|
||||
Exeption = e.ToString()
|
||||
Exception = e.ToString()
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
using System.Collections.Frozen;
|
||||
using System.Reflection;
|
||||
using mROA.Abstract;
|
||||
using mROA.Implementation.Attributes;
|
||||
|
||||
namespace mROA.Implementation;
|
||||
namespace mROA.Implementation.Backend;
|
||||
|
||||
public class ContextRepository : IContextRepository
|
||||
{
|
||||
private FrozenDictionary<int, object?> _singletons;
|
||||
private object[] _storage;
|
||||
private FrozenDictionary<int, object?>? _singletons;
|
||||
private object?[] _storage = new object[StartupSize];
|
||||
|
||||
private Task<int> _lastIndexFinder = Task.FromResult(0);
|
||||
|
||||
@@ -14,11 +16,6 @@ public class ContextRepository : IContextRepository
|
||||
const int GrowSize = 128;
|
||||
|
||||
|
||||
public ContextRepository()
|
||||
{
|
||||
_storage = new object[StartupSize];
|
||||
}
|
||||
|
||||
public void FillSingletons(params Assembly[] assembly)
|
||||
{
|
||||
var types = assembly.SelectMany(x => x.GetTypes()).Where(type =>
|
||||
@@ -39,7 +36,7 @@ public class ContextRepository : IContextRepository
|
||||
_storage[_lastIndexFinder.Result] = o;
|
||||
|
||||
var last = _lastIndexFinder.Result;
|
||||
_lastIndexFinder = FindLastIndex();
|
||||
_lastIndexFinder = Task.Run(FindLastIndex);
|
||||
|
||||
return last;
|
||||
}
|
||||
@@ -50,30 +47,28 @@ 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];
|
||||
return (id == -1 || _storage.Length <= id ? null : _storage[id]) ?? throw new NullReferenceException();
|
||||
}
|
||||
|
||||
public T GetObject<T>(int id)
|
||||
{
|
||||
return id == -1 || _storage.Length <= id ? throw new NullReferenceException("Cannot find that object. It is null"): (T)_storage[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()) ?? throw new ArgumentException("Unregistered singleton type");
|
||||
return _singletons!.GetValueOrDefault(type.GetHashCode()) ?? throw new ArgumentException("Unregistered singleton type");
|
||||
}
|
||||
|
||||
public int GetObjectIndex(object o)
|
||||
{
|
||||
var index = Array.IndexOf(_storage, o);
|
||||
if (index == -1)
|
||||
return ResisterObject(o);
|
||||
return index;
|
||||
return index == -1 ? ResisterObject(o) : index;
|
||||
}
|
||||
|
||||
private async Task<int> FindLastIndex()
|
||||
private int FindLastIndex()
|
||||
{
|
||||
for (int i = 0; i < _storage.Length; i++)
|
||||
{
|
||||
@@ -83,6 +78,7 @@ public class ContextRepository : IContextRepository
|
||||
|
||||
var nextStorage = new object[_storage.Length + GrowSize];
|
||||
Array.Copy(_storage, nextStorage, _storage.Length);
|
||||
_storage = nextStorage;
|
||||
return _storage.Length;
|
||||
}
|
||||
public void Inject<T>(T dependency)
|
||||
|
||||
@@ -1,27 +1,26 @@
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using mROA.Implementation.Bootstrap;
|
||||
using mROA.Abstract;
|
||||
|
||||
namespace mROA.Implementation;
|
||||
namespace mROA.Implementation.Backend;
|
||||
|
||||
public class JsonSerialisationModule : ISerialisationModule
|
||||
{
|
||||
private IInteractionModule _dataSource;
|
||||
private IExecuteModule _executeModule;
|
||||
private IMethodRepository _methodRepository;
|
||||
private IInteractionModule? _dataSource;
|
||||
private IExecuteModule? _executeModule;
|
||||
private IMethodRepository? _methodRepository;
|
||||
|
||||
public void HandleIncomingRequest(int clientId, byte[] command)
|
||||
{
|
||||
DefaultCallRequest request = JsonSerializer.Deserialize<DefaultCallRequest>(command);
|
||||
DefaultCallRequest request = JsonSerializer.Deserialize<DefaultCallRequest>(command)!;
|
||||
|
||||
if (request.Parameter is not null)
|
||||
{
|
||||
var parameter = _methodRepository.GetMethod(request.CommandId).GetParameters().First().ParameterType;
|
||||
var parameter = _methodRepository!.GetMethod(request.CommandId).GetParameters().First().ParameterType;
|
||||
request.Parameter = ((JsonElement)request.Parameter).Deserialize(parameter);
|
||||
}
|
||||
|
||||
var response = _executeModule.Execute(request);
|
||||
var response = _executeModule!.Execute(request);
|
||||
response.ClientId = clientId;
|
||||
PostResponse(response);
|
||||
}
|
||||
@@ -47,7 +46,7 @@ public class JsonSerialisationModule : ISerialisationModule
|
||||
// }
|
||||
|
||||
var binary = Encoding.UTF8.GetBytes(texted);
|
||||
_dataSource.SendTo(call.ClientId, binary);
|
||||
_dataSource!.SendTo(call.ClientId, binary);
|
||||
}
|
||||
|
||||
public void Inject<T>(T dependency)
|
||||
|
||||
@@ -1,17 +1,14 @@
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using mROA.Abstract;
|
||||
|
||||
namespace mROA.Implementation;
|
||||
namespace mROA.Implementation.Backend;
|
||||
|
||||
public class NetworkGatewayModule : IGatewayModule
|
||||
public class NetworkGatewayModule(IPEndPoint endpoint) : IGatewayModule
|
||||
{
|
||||
private TcpListener _tcpListener;
|
||||
private IInteractionModule _interactionModule;
|
||||
private readonly TcpListener _tcpListener = new(endpoint);
|
||||
private IInteractionModule? _interactionModule;
|
||||
|
||||
public NetworkGatewayModule(IPEndPoint endpoint)
|
||||
{
|
||||
_tcpListener = new TcpListener(endpoint);
|
||||
}
|
||||
|
||||
public void Run()
|
||||
{
|
||||
@@ -41,6 +38,8 @@ public class NetworkGatewayModule : IGatewayModule
|
||||
|
||||
private void HandleIncomingConnections()
|
||||
{
|
||||
if (_interactionModule is null)
|
||||
throw new NullReferenceException("Interaction module is null");
|
||||
while (true)
|
||||
{
|
||||
var client = _tcpListener.AcceptTcpClient();
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
namespace mROA.Implementation;
|
||||
using mROA.Abstract;
|
||||
|
||||
namespace mROA.Implementation.Backend;
|
||||
|
||||
public class StreamBasedInteractionModule : IInteractionModule
|
||||
{
|
||||
private Dictionary<int, Stream> _streams = new();
|
||||
private Action<int, byte[]> _handler;
|
||||
private readonly Dictionary<int, Stream> _streams = new();
|
||||
private Action<int, byte[]>? _handler;
|
||||
|
||||
public void RegisterSourse(Stream stream)
|
||||
{
|
||||
var id = Random.Shared.Next();
|
||||
_streams.Add(id, stream);
|
||||
ListenTo((id, stream), _handler);
|
||||
_ = ListenTo((id, stream), _handler!);
|
||||
}
|
||||
|
||||
public void SendTo(int clientId, byte[] message)
|
||||
@@ -34,7 +36,7 @@ public class StreamBasedInteractionModule : IInteractionModule
|
||||
await client.stream.ReadExactlyAsync(buffer, 0, 2);
|
||||
var len = BitConverter.ToUInt16(buffer, 0);
|
||||
await client.stream.ReadExactlyAsync(buffer, 0, len);
|
||||
Task.Run(() => action(client.id, buffer[..len]));
|
||||
_ = Task.Run(() => action(client.id, buffer[..len]));
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
|
||||
@@ -2,14 +2,14 @@ using mROA.Abstract;
|
||||
|
||||
namespace mROA.Implementation.Bootstrap;
|
||||
|
||||
public interface ImRoaBuilder
|
||||
public interface IRoaBuilder
|
||||
{
|
||||
void Build();
|
||||
}
|
||||
|
||||
public class FullMixBuilder : ImRoaBuilder
|
||||
public class FullMixBuilder : IRoaBuilder
|
||||
{
|
||||
public List<IInjectableModule> Modules { get; private set; } = new();
|
||||
public List<IInjectableModule> Modules { get; } = new();
|
||||
public void Build()
|
||||
{
|
||||
foreach (var module in Modules)
|
||||
@@ -17,7 +17,7 @@ public class FullMixBuilder : ImRoaBuilder
|
||||
module.Inject(injection);
|
||||
}
|
||||
|
||||
public T GetModule<T>()
|
||||
public T? GetModule<T>()
|
||||
{
|
||||
return Modules.OfType<T>().FirstOrDefault();
|
||||
}
|
||||
|
||||
@@ -5,13 +5,13 @@ public interface ICallRequest
|
||||
Guid CallRequestId { get; internal set; }
|
||||
int CommandId { get; }
|
||||
int ObjectId { get; }
|
||||
object Parameter { get; }
|
||||
object? Parameter { get; }
|
||||
}
|
||||
|
||||
public class DefaultCallRequest : ICallRequest
|
||||
{
|
||||
public Guid CallRequestId { get; set; } = Guid.NewGuid();
|
||||
public int CommandId { get; set; }
|
||||
public int ObjectId { get; set; } = -1;
|
||||
public int CommandId { get; init; }
|
||||
public int ObjectId { get; init; } = -1;
|
||||
public object? Parameter { get; set; }
|
||||
}
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
using System.Text.Json.Serialization;
|
||||
using mROA.Abstract;
|
||||
|
||||
// ReSharper disable UnusedAutoPropertyAccessor.Global
|
||||
|
||||
namespace mROA.Implementation;
|
||||
|
||||
@@ -19,7 +22,7 @@ public class FinalCommandExecution<T> : FinalCommandExecution
|
||||
public class TypedFinalCommandExecution : FinalCommandExecution<object>
|
||||
{
|
||||
[JsonIgnore]
|
||||
public Type Type { get; set; }
|
||||
public Type? Type { get; set; }
|
||||
}
|
||||
|
||||
public class ExceptionCommandExecution : ICommandExecution
|
||||
@@ -27,5 +30,5 @@ public class ExceptionCommandExecution : ICommandExecution
|
||||
public Guid CallRequestId { get; init; }
|
||||
public int ClientId { get; set; }
|
||||
public int CommandId { get; set; }
|
||||
public string Exeption { get; set; }
|
||||
public required string Exception { get; set; }
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
// using System.Collections.Frozen;
|
||||
//
|
||||
// namespace mROA.Implementation;
|
||||
//
|
||||
// public class FrontendContextRepository(
|
||||
// Dictionary<Type, Type> remoteTypes,
|
||||
// ISerialisationModule.IFrontendSerialisationModule serialisationModule) : IContextRepository
|
||||
// {
|
||||
// private FrozenDictionary<Type, Type> _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<T>(int id)
|
||||
// {
|
||||
// if (_remoteTypes.TryGetValue(typeof(T), out var remoteType))
|
||||
// {
|
||||
// var remote = (T)Activator.CreateInstance(remoteType, id, serialisationModule)!;
|
||||
// return remote;
|
||||
// }
|
||||
//
|
||||
// throw new NotSupportedException();
|
||||
// }
|
||||
//
|
||||
// public object GetSingleObject(Type type)
|
||||
// {
|
||||
// return Activator.CreateInstance(remoteTypes[type], -1, serialisationModule)!;
|
||||
// }
|
||||
//
|
||||
// public int GetObjectIndex(object o)
|
||||
// {
|
||||
// if (o is IRemoteObject remote)
|
||||
// {
|
||||
// return remote.Id;
|
||||
// }
|
||||
//
|
||||
// throw new NotSupportedException();
|
||||
// }
|
||||
//
|
||||
// public void Inject<T>(T dependency)
|
||||
// {
|
||||
// }
|
||||
//
|
||||
// public void Bake()
|
||||
// {
|
||||
// }
|
||||
// }
|
||||
@@ -1,12 +1,14 @@
|
||||
namespace mROA.Implementation;
|
||||
using mROA.Abstract;
|
||||
|
||||
namespace mROA.Implementation.Frontend;
|
||||
|
||||
public class FrontendServiceBuilder
|
||||
{
|
||||
protected IInteractionModule.IFrontendInteractionModule _interactionModule;
|
||||
protected ISerialisationModule.IFrontendSerialisationModule _serialisationModule;
|
||||
protected IInteractionModule.IFrontendInteractionModule? InteractionModule;
|
||||
protected ISerialisationModule.IFrontendSerialisationModule? SerialisationModule;
|
||||
|
||||
public ISerialisationModule.IFrontendSerialisationModule Build()
|
||||
{
|
||||
return _serialisationModule;
|
||||
return SerialisationModule!;
|
||||
}
|
||||
}
|
||||
@@ -1,21 +1,25 @@
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using mROA.Abstract;
|
||||
|
||||
namespace mROA.Implementation;
|
||||
namespace mROA.Implementation.Frontend;
|
||||
|
||||
public class JsonFrontendSerialisationModule
|
||||
: ISerialisationModule.IFrontendSerialisationModule
|
||||
{
|
||||
private IInteractionModule.IFrontendInteractionModule _interactionModule;
|
||||
private IInteractionModule.IFrontendInteractionModule? _interactionModule;
|
||||
|
||||
public async Task<T> GetNextCommandExecution<T>(Guid requestId) where T : ICommandExecution
|
||||
{
|
||||
if (_interactionModule is null)
|
||||
throw new Exception("Interaction module not initialized");
|
||||
|
||||
var receiveMessage = await _interactionModule.ReceiveMessage();
|
||||
var parsed = JsonSerializer.Deserialize<T>(receiveMessage);
|
||||
var parsed = JsonSerializer.Deserialize<T>(receiveMessage)!;
|
||||
while (parsed.CallRequestId != requestId)
|
||||
{
|
||||
receiveMessage = await _interactionModule.ReceiveMessage();
|
||||
parsed = JsonSerializer.Deserialize<T>(receiveMessage);
|
||||
parsed = JsonSerializer.Deserialize<T>(receiveMessage)!;
|
||||
}
|
||||
|
||||
return parsed;
|
||||
@@ -23,19 +27,22 @@ public class JsonFrontendSerialisationModule
|
||||
|
||||
public async Task<FinalCommandExecution<T>> GetFinalCommandExecution<T>(Guid requestId)
|
||||
{
|
||||
if (_interactionModule is null)
|
||||
throw new Exception("Interaction module not initialized");
|
||||
|
||||
var receiveMessage = await _interactionModule.ReceiveMessage();
|
||||
// var str = Encoding.UTF8.GetString(receiveMessage);
|
||||
var document = JsonDocument.Parse(receiveMessage);
|
||||
if (document.RootElement.TryGetProperty("Exeption", out var exeptionElement))
|
||||
if (document.RootElement.TryGetProperty("Exception", out var exceptionElement))
|
||||
{
|
||||
throw new RemoteException(exeptionElement.GetString()) { CallRequestId = requestId };
|
||||
throw new RemoteException(exceptionElement.GetString()!) { CallRequestId = requestId };
|
||||
}
|
||||
|
||||
var parsed = document.Deserialize<FinalCommandExecution<T>>();
|
||||
var parsed = document.Deserialize<FinalCommandExecution<T>>()!;
|
||||
while (parsed.CallRequestId != requestId)
|
||||
{
|
||||
receiveMessage = await _interactionModule.ReceiveMessage();
|
||||
parsed = JsonSerializer.Deserialize<FinalCommandExecution<T>>(receiveMessage);
|
||||
parsed = JsonSerializer.Deserialize<FinalCommandExecution<T>>(receiveMessage)!;
|
||||
}
|
||||
|
||||
parsed.Result = parsed.Result! is JsonElement e ? e.Deserialize<T>() : (T)parsed.Result!;
|
||||
@@ -44,6 +51,9 @@ public class JsonFrontendSerialisationModule
|
||||
|
||||
public void PostCallRequest(ICallRequest callRequest)
|
||||
{
|
||||
if (_interactionModule is null)
|
||||
throw new Exception("Interaction module not initialized");
|
||||
|
||||
var post = JsonSerializer.Serialize(callRequest, callRequest.GetType());
|
||||
_interactionModule.PostMessage(Encoding.UTF8.GetBytes(post));
|
||||
}
|
||||
|
||||
@@ -2,21 +2,28 @@ using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using mROA.Abstract;
|
||||
|
||||
namespace mROA.Implementation;
|
||||
namespace mROA.Implementation.Frontend;
|
||||
|
||||
public class NetworkFrontendBridge : IFrontendBridge
|
||||
public class NetworkFrontendBridge(IPEndPoint ipEndPoint) : IFrontendBridge
|
||||
{
|
||||
private TcpClient _tcpClient;
|
||||
public NetworkFrontendBridge(IPEndPoint serverEndPoint)
|
||||
{
|
||||
_tcpClient = new TcpClient();
|
||||
_tcpClient.Connect(serverEndPoint);
|
||||
}
|
||||
private readonly TcpClient _tcpClient = new();
|
||||
private StreamBasedFrontendInteractionModule? _interactionModule;
|
||||
|
||||
public void Inject<T>(T dependency)
|
||||
{
|
||||
if (dependency is StreamBasedFrontendInteractionModule interactionModule)
|
||||
{
|
||||
interactionModule.ServerStream = _tcpClient.GetStream();
|
||||
_interactionModule = interactionModule;
|
||||
}
|
||||
}
|
||||
|
||||
public void Connect()
|
||||
{
|
||||
_tcpClient.Connect(ipEndPoint);
|
||||
if (_interactionModule is null)
|
||||
{
|
||||
throw new Exception("Interaction module was not injected");
|
||||
}
|
||||
_interactionModule.ServerStream = _tcpClient.GetStream();
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,15 @@
|
||||
namespace mROA.Implementation;
|
||||
using mROA.Abstract;
|
||||
|
||||
namespace mROA.Implementation.Frontend;
|
||||
|
||||
public class StreamBasedFrontendInteractionModule : IInteractionModule.IFrontendInteractionModule
|
||||
{
|
||||
public Stream ServerStream { get; set; }
|
||||
public Stream? ServerStream { get; set; }
|
||||
|
||||
public async Task<byte[]> ReceiveMessage()
|
||||
{
|
||||
if (ServerStream is null)
|
||||
throw new IOException("Server is not connected.");
|
||||
const int bufferSize = ushort.MaxValue;
|
||||
|
||||
byte[] buffer = new byte[bufferSize];
|
||||
@@ -20,6 +24,9 @@ public class StreamBasedFrontendInteractionModule : IInteractionModule.IFrontend
|
||||
|
||||
public void PostMessage(byte[] message)
|
||||
{
|
||||
if (ServerStream is null)
|
||||
throw new IOException("Server is not connected.");
|
||||
|
||||
ServerStream.Write(BitConverter.GetBytes((ushort)message.Length), 0, sizeof(ushort));
|
||||
ServerStream.Write(message, 0, message.Length);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using System.Reflection;
|
||||
using mROA.Abstract;
|
||||
using mROA.Implementation.Attributes;
|
||||
|
||||
namespace mROA.Implementation;
|
||||
|
||||
@@ -9,7 +11,7 @@ public class MethodRepository : IMethodRepository
|
||||
public MethodInfo GetMethod(int id)
|
||||
{
|
||||
if (_methods.Count <= id)
|
||||
return null;
|
||||
throw new Exception("Method such registered method");
|
||||
|
||||
return _methods[id];
|
||||
}
|
||||
|
||||
@@ -1,32 +1,34 @@
|
||||
using System.Text.Json.Serialization;
|
||||
using mROA.Abstract;
|
||||
|
||||
namespace mROA.Implementation;
|
||||
|
||||
public static class TransmissionConfig
|
||||
{
|
||||
public static IContextRepository DefaultContextRepository { get; set; }
|
||||
public static IContextRepository? DefaultContextRepository { get; set; }
|
||||
}
|
||||
|
||||
public class TransmittedSharedObject<T>
|
||||
public class TransmittedSharedObject<T> where T : notnull
|
||||
{
|
||||
public int ContextId { get; set; } = -1;
|
||||
private static IContextRepository GetDefaultContextRepository() => TransmissionConfig.DefaultContextRepository ??
|
||||
throw new NullReferenceException(
|
||||
"DefaultContextRepository was not defined");
|
||||
|
||||
private int ContextId { get; init; } = -1;
|
||||
|
||||
[JsonIgnore]
|
||||
public T? Value => TransmissionConfig.DefaultContextRepository.GetObject<T>(ContextId);
|
||||
public T? Value => GetDefaultContextRepository().GetObject<T>(ContextId);
|
||||
|
||||
[JsonIgnore]
|
||||
public IContextRepository Context { get; set; }
|
||||
|
||||
public TransmittedSharedObject()
|
||||
private TransmittedSharedObject()
|
||||
{
|
||||
}
|
||||
public TransmittedSharedObject(T value)
|
||||
public TransmittedSharedObject(T value)
|
||||
{
|
||||
ContextId = TransmissionConfig.DefaultContextRepository.GetObjectIndex(value);
|
||||
ContextId = GetDefaultContextRepository().GetObjectIndex(value);
|
||||
}
|
||||
|
||||
public static implicit operator T(TransmittedSharedObject<T> value) => value.Value!;
|
||||
|
||||
public static implicit operator TransmittedSharedObject<T>(T value) =>
|
||||
new() { ContextId = TransmissionConfig.DefaultContextRepository.GetObjectIndex(value) };
|
||||
new() { ContextId = GetDefaultContextRepository().GetObjectIndex(value) };
|
||||
}
|
||||
Reference in New Issue
Block a user