билдится на старом дотнете

This commit is contained in:
2025-02-20 16:10:09 +03:00
parent 5af9408a9a
commit 50fd3e7b73
69 changed files with 1990 additions and 1675 deletions
+8 -5
View File
@@ -1,8 +1,11 @@
namespace mROA.Abstract;
using System;
public interface ICommandExecution
namespace mROA.Abstract
{
Guid Id { get; init; }
int ClientId { get; set; }
int CommandId { get; }
public interface ICommandExecution
{
Guid Id { get; set; }
int ClientId { get; set; }
int CommandId { get; }
}
}
+11 -10
View File
@@ -1,12 +1,13 @@
namespace mROA.Abstract;
public delegate void ConnectionHandler(IRepresentationModule representationModule);
public delegate void DisconnectionHandler(IRepresentationModule representationModule);
public interface IConnectionHub : IInjectableModule
namespace mROA.Abstract
{
void RegisterInteraction(INextGenerationInteractionModule interaction);
INextGenerationInteractionModule GetInteracion(int id);
event ConnectionHandler? OnConnected;
event DisconnectionHandler? OnDisconnected;
public delegate void ConnectionHandler(IRepresentationModule representationModule);
public delegate void DisconnectionHandler(IRepresentationModule representationModule);
public interface IConnectionHub : IInjectableModule
{
void RegisterInteraction(INextGenerationInteractionModule interaction);
INextGenerationInteractionModule GetInteracion(int id);
event ConnectionHandler? OnConnected;
event DisconnectionHandler? OnDisconnected;
}
}
+11 -8
View File
@@ -1,11 +1,14 @@
namespace mROA.Abstract;
using System;
public interface IContextRepository : IInjectableModule
namespace mROA.Abstract
{
int ResisterObject(object o);
void ClearObject(int id);
object GetObject(int id);
T? GetObject<T>(int id);
object GetSingleObject(Type type);
int GetObjectIndex(object o);
public interface IContextRepository : IInjectableModule
{
int ResisterObject(object o);
void ClearObject(int id);
object GetObject(int id);
T? GetObject<T>(int id);
object GetSingleObject(Type type);
int GetObjectIndex(object o);
}
}
+5 -4
View File
@@ -1,6 +1,7 @@
namespace mROA.Abstract;
public interface IContextRepositoryHub
namespace mROA.Abstract
{
IContextRepository GetRepository(int clientId);
public interface IContextRepositoryHub
{
IContextRepository GetRepository(int clientId);
}
}
+5 -4
View File
@@ -1,8 +1,9 @@
using mROA.Implementation;
namespace mROA.Abstract;
public interface IExecuteModule : IInjectableModule
namespace mROA.Abstract
{
ICommandExecution Execute(ICallRequest command, IContextRepository contextRepository);
public interface IExecuteModule : IInjectableModule
{
ICommandExecution Execute(ICallRequest command, IContextRepository contextRepository);
}
}
+7 -3
View File
@@ -1,3 +1,7 @@
namespace mROA.Abstract;
public interface IFrontendBridge : IInjectableModule;
namespace mROA.Abstract
{
public interface IFrontendBridge : IInjectableModule
{
}
}
+7 -4
View File
@@ -1,6 +1,9 @@
namespace mROA.Abstract;
using System;
public interface IGatewayModule : IDisposable, IInjectableModule
{
void Run();
namespace mROA.Abstract
{
public interface IGatewayModule : IDisposable, IInjectableModule
{
void Run();
}
}
+5 -4
View File
@@ -1,6 +1,7 @@
namespace mROA.Abstract;
public interface IIdentityGenerator : IInjectableModule
namespace mROA.Abstract
{
int GetNextIdentity();
public interface IIdentityGenerator : IInjectableModule
{
int GetNextIdentity();
}
}
+5 -4
View File
@@ -1,6 +1,7 @@
namespace mROA.Abstract;
public interface IInjectableModule
namespace mROA.Abstract
{
void Inject<T>(T dependency);
public interface IInjectableModule
{
void Inject<T>(T dependency);
}
}
+14 -10
View File
@@ -1,14 +1,18 @@
using System;
using System.IO;
using System.Threading.Tasks;
using mROA.Implementation;
namespace mROA.Abstract;
public interface INextGenerationInteractionModule : IInjectableModule
namespace mROA.Abstract
{
int ConnectionId { get; }
public Stream? BaseStream { get; set; }
Task<NetworkMessage> GetNextMessageReceiving();
Task PostMessage(NetworkMessage message);
void HandleMessage(NetworkMessage message);
NetworkMessage[] UnhandledMessages { get; }
NetworkMessage? FirstByFilter(Predicate<NetworkMessage> predicate);
public interface INextGenerationInteractionModule : IInjectableModule
{
int ConnectionId { get; }
public Stream? BaseStream { get; set; }
Task<NetworkMessage> GetNextMessageReceiving();
Task PostMessage(NetworkMessage message);
void HandleMessage(NetworkMessage message);
NetworkMessage[] UnhandledMessages { get; }
NetworkMessage? FirstByFilter(Predicate<NetworkMessage> predicate);
}
}
+9 -7
View File
@@ -1,11 +1,13 @@
using System.Reflection;
using System.Collections.Generic;
using System.Reflection;
namespace mROA.Abstract;
public interface IMethodRepository : IInjectableModule
namespace mROA.Abstract
{
MethodInfo GetMethod(int id);
int RegisterMethod(MethodInfo method);
public interface IMethodRepository : IInjectableModule
{
MethodInfo GetMethod(int id);
int RegisterMethod(MethodInfo method);
IEnumerable<MethodInfo> GetMethods();
IEnumerable<MethodInfo> GetMethods();
}
}
+6 -5
View File
@@ -1,7 +1,8 @@
namespace mROA.Abstract;
public interface IOwnershipRepository
namespace mROA.Abstract
{
int GetOwnershipId();
int GetHostOwnershipId();
public interface IOwnershipRepository
{
int GetOwnershipId();
int GetHostOwnershipId();
}
}
@@ -1,6 +1,7 @@
namespace mROA.Abstract;
public interface IRepresentationModuleProducer : IInjectableModule
namespace mROA.Abstract
{
IRepresentationModule Produce(int id);
public interface IRepresentationModuleProducer : IInjectableModule
{
IRepresentationModule Produce(int id);
}
}
+6 -3
View File
@@ -1,6 +1,9 @@
namespace mROA.Abstract;
using System.Threading.Tasks;
public interface IRequestExtractor : IInjectableModule
namespace mROA.Abstract
{
Task StartExtraction();
public interface IRequestExtractor : IInjectableModule
{
Task StartExtraction();
}
}
+25 -22
View File
@@ -1,31 +1,34 @@
using System;
using System.Threading.Tasks;
using mROA.Implementation;
using mROA.Implementation.CommandExecution;
namespace mROA.Abstract;
public interface ISerialisationModule : IInjectableModule
namespace mROA.Abstract
{
void HandleIncomingRequest(int clientId, byte[] message);
void PostResponse(NetworkMessage message, int clientId);
void SendWelcomeMessage(int clientId);
public interface IFrontendSerialisationModule : IInjectableModule
public interface ISerialisationModule : IInjectableModule
{
int ClientId { get; }
Task<T> GetNextCommandExecution<T>(Guid requestId) where T : ICommandExecution;
Task<FinalCommandExecution<T>> GetFinalCommandExecution<T>(Guid requestId);
void PostCallRequest(ICallRequest callRequest);
void HandleIncomingRequest(int clientId, byte[] message);
void PostResponse(NetworkMessage message, int clientId);
void SendWelcomeMessage(int clientId);
public interface IFrontendSerialisationModule : IInjectableModule
{
int ClientId { get; }
Task<T> GetNextCommandExecution<T>(Guid requestId) where T : ICommandExecution;
Task<FinalCommandExecution<T>> GetFinalCommandExecution<T>(Guid requestId);
void PostCallRequest(ICallRequest callRequest);
}
}
}
public interface IRepresentationModule : IInjectableModule
{
int Id { get; }
Task<T> GetMessageAsync<T>(Guid? requestId = null, MessageType? messageType = null);
T GetMessage<T>(Guid? requestId = null, MessageType? messageType = null);
Task<byte[]> GetRawMessage(Guid? requestId = null, MessageType? messageType = null);
public interface IRepresentationModule : IInjectableModule
{
int Id { get; }
Task<T> GetMessageAsync<T>(Guid? requestId = null, MessageType? messageType = null);
T GetMessage<T>(Guid? requestId = null, MessageType? messageType = null);
Task<byte[]> GetRawMessage(Guid? requestId = null, MessageType? messageType = null);
Task PostCallMessageAsync<T>(Guid id, MessageType messageType, T payload) where T : notnull;
Task PostCallMessageAsync(Guid id, MessageType messageType, object payload, Type payloadType);
void PostCallMessage<T>(Guid id, MessageType messageType, T payload) where T : notnull;
void PostCallMessage(Guid id, MessageType messageType, object payload, Type payloadType);
Task PostCallMessageAsync<T>(Guid id, MessageType messageType, T payload) where T : notnull;
Task PostCallMessageAsync(Guid id, MessageType messageType, object payload, Type payloadType);
void PostCallMessage<T>(Guid id, MessageType messageType, T payload) where T : notnull;
void PostCallMessage(Guid id, MessageType messageType, object payload, Type payloadType);
}
}
+13 -10
View File
@@ -1,14 +1,17 @@
namespace mROA.Abstract;
using System;
public interface ISerializationToolkit : IInjectableModule
namespace mROA.Abstract
{
byte[] Serialize<T>(T objectToSerialize);
byte[] Serialize(object objectToSerialize, Type type);
T? Deserialize<T>(byte[] rawData);
object? Deserialize(byte[] rawData, Type type);
T? Deserialize<T>(Span<byte> rawData);
object? Deserialize(Span<byte> rawData, Type type);
T Cast<T>(object nonCasted);
object Cast(object nonCasted, Type type);
public interface ISerializationToolkit : IInjectableModule
{
byte[] Serialize<T>(T objectToSerialize);
byte[] Serialize(object objectToSerialize, Type type);
T? Deserialize<T>(byte[] rawData);
object? Deserialize(byte[] rawData, Type type);
T? Deserialize<T>(Span<byte> rawData);
object? Deserialize(Span<byte> rawData, Type type);
T Cast<T>(object nonCasted);
object Cast(object nonCasted, Type type);
}
}
@@ -1,3 +1,6 @@
namespace mROA.Implementation.Attributes;
using System;
public class SharedObjectInterfaceAttribute : Attribute;
namespace mROA.Implementation.Attributes
{
public class SharedObjectInterfaceAttribute : Attribute { }
}
@@ -1,3 +1,6 @@
namespace mROA.Implementation.Attributes;
using System;
public class SharedObjectSingletonAttribute : Attribute;
namespace mROA.Implementation.Attributes
{
public class SharedObjectSingletonAttribute : Attribute { }
}
@@ -1,17 +1,18 @@
using mROA.Abstract;
namespace mROA.Implementation.Backend;
public class BackendIdentityGenerator : IIdentityGenerator
namespace mROA.Implementation.Backend
{
private int _currentId;
public int GetNextIdentity()
{
return ++_currentId;
}
public void Inject<T>(T dependency)
public class BackendIdentityGenerator : IIdentityGenerator
{
private int _currentId;
public int GetNextIdentity()
{
return ++_currentId;
}
public void Inject<T>(T dependency)
{
}
}
}
@@ -1,37 +1,39 @@
using System;
using System.Net;
using System.Reflection;
using mROA.Abstract;
using mROA.Implementation.Bootstrap;
namespace mROA.Implementation.Backend;
public static class BasicConfigurationExtensions
namespace mROA.Implementation.Backend
{
public static void UseJsonSerialisation(this FullMixBuilder builder)
public static class BasicConfigurationExtensions
{
builder.Modules.Add(new JsonSerializationToolkit());
}
public static void UseJsonSerialisation(this FullMixBuilder builder)
{
builder.Modules.Add(new JsonSerializationToolkit());
}
public static void UseNetworkGateway(this FullMixBuilder builder, IPEndPoint endPoint, Type interactionModuleType, params IInjectableModule[] injectableModules)
{
builder.Modules.Add(new NetworkGatewayModule(endPoint, interactionModuleType, injectableModules));
}
public static void UseNetworkGateway(this FullMixBuilder builder, IPEndPoint endPoint, Type interactionModuleType, params IInjectableModule[] injectableModules)
{
builder.Modules.Add(new NetworkGatewayModule(endPoint, interactionModuleType, injectableModules));
}
public static void UseBasicExecution(this FullMixBuilder builder)
{
builder.Modules.Add(new BasicExecutionModule());
}
public static void UseBasicExecution(this FullMixBuilder builder)
{
builder.Modules.Add(new BasicExecutionModule());
}
public static void UseCollectableContextRepository(this FullMixBuilder builder, params Assembly[] assemblies)
{
var repo = new ContextRepository();
repo.FillSingletons(assemblies);
TransmissionConfig.RealContextRepository = repo;
builder.Modules.Add(repo);
}
public static void UseCollectableContextRepository(this FullMixBuilder builder, params Assembly[] assemblies)
{
var repo = new ContextRepository();
repo.FillSingletons(assemblies);
TransmissionConfig.RealContextRepository = repo;
builder.Modules.Add(repo);
}
public static void SetupMethodsRepository(this FullMixBuilder builder, IMethodRepository methodRepository)
{
builder.Modules.Add(methodRepository);
public static void SetupMethodsRepository(this FullMixBuilder builder, IMethodRepository methodRepository)
{
builder.Modules.Add(methodRepository);
}
}
}
@@ -1,121 +1,128 @@
using System.Reflection;
using System;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using mROA.Abstract;
using mROA.Implementation.CommandExecution;
namespace mROA.Implementation.Backend;
public class BasicExecutionModule : IExecuteModule
namespace mROA.Implementation.Backend
{
private IMethodRepository? _methodRepo;
public void Inject<T>(T dependency)
public class BasicExecutionModule : IExecuteModule
{
if (dependency is IMethodRepository methodRepo) _methodRepo = methodRepo;
}
private IMethodRepository? _methodRepo;
public ICommandExecution Execute(ICallRequest command, IContextRepository contextRepository)
{
if (_methodRepo is null)
throw new NullReferenceException("Method repository was not defined");
public void Inject<T>(T dependency)
{
if (dependency is IMethodRepository methodRepo) _methodRepo = methodRepo;
}
public ICommandExecution Execute(ICallRequest command, IContextRepository contextRepository)
{
if (_methodRepo is null)
throw new NullReferenceException("Method repository was not defined");
if (contextRepository is null)
throw new NullReferenceException("Context repository was not defined");
if (contextRepository is null)
throw new NullReferenceException("Context repository was not defined");
var currentCommand = _methodRepo.GetMethod(command.CommandId);
if (currentCommand == null)
throw new Exception($"Command {command.CommandId} not found");
var currentCommand = _methodRepo.GetMethod(command.CommandId);
if (currentCommand == null)
throw new Exception($"Command {command.CommandId} not found");
var context = command.ObjectId != -1
? contextRepository.GetObject(command.ObjectId)
: contextRepository.GetSingleObject(currentCommand.DeclaringType!);
var parameter = command.Parameter;
var context = command.ObjectId != -1
? contextRepository.GetObject(command.ObjectId)
: contextRepository.GetSingleObject(currentCommand.DeclaringType!);
var parameter = command.Parameter;
if (currentCommand.ReturnType.BaseType == typeof(Task) &&
currentCommand.ReturnType.GenericTypeArguments.Length == 1)
return TypedExecuteAsync(currentCommand, context, parameter, command);
if (currentCommand.ReturnType.BaseType == typeof(Task) &&
currentCommand.ReturnType.GenericTypeArguments.Length == 1)
return TypedExecuteAsync(currentCommand, context, parameter, command);
if (currentCommand.ReturnType == typeof(Task))
return ExecuteAsync(currentCommand, context, parameter, command);
if (currentCommand.ReturnType == typeof(Task))
return ExecuteAsync(currentCommand, context, parameter, command);
return Execute(currentCommand, context, parameter, command);
}
private static ICommandExecution Execute(MethodInfo currentCommand, object context, object? parameter,
ICallRequest command)
{
try
{
var finalResult = currentCommand.Invoke(context, parameter is null ? [] : [parameter]);
return new TypedFinalCommandExecution
{
CommandId = command.CommandId, Result = finalResult,
Id = command.Id,
Type = currentCommand.ReturnType
};
return Execute(currentCommand, context, parameter, command);
}
catch (Exception e)
private static ICommandExecution Execute(MethodInfo currentCommand, object context, object? parameter,
ICallRequest command)
{
return new ExceptionCommandExecution
try
{
Id = command.Id, CommandId = command.CommandId,
Exception = e.ToString()
};
}
}
private static ICommandExecution ExecuteAsync(MethodInfo currentCommand, object context, object? parameter,
ICallRequest command)
{
var tokenSource = new CancellationTokenSource();
var token = tokenSource.Token;
try
{
var result = (Task)currentCommand.Invoke(context, parameter is null ? [token] : [parameter, token])!;
result.Wait(token);
return new FinalCommandExecution { CommandId = command.CommandId, Id = command.Id };
}
catch (Exception e)
{
return new ExceptionCommandExecution
var finalResult = currentCommand.Invoke(context, parameter is null ? new object[0] : new[]
{ parameter });
return new TypedFinalCommandExecution
{
CommandId = command.CommandId, Result = finalResult,
Id = command.Id,
Type = currentCommand.ReturnType
};
}
catch (Exception e)
{
Id = command.Id, CommandId = command.CommandId,
Exception = e.ToString()
};
return new ExceptionCommandExecution
{
Id = command.Id, CommandId = command.CommandId,
Exception = e.ToString()
};
}
}
}
private static ICommandExecution TypedExecuteAsync(MethodInfo currentCommand, object context, object? parameter,
ICallRequest command)
{
var tokenSource = new CancellationTokenSource();
var token = tokenSource.Token;
try
private static ICommandExecution ExecuteAsync(MethodInfo currentCommand, object context, object? parameter,
ICallRequest command)
{
var result =
(Task)currentCommand.Invoke(context, parameter is null ? [token] : [parameter, token])!;
result.Wait(token);
var finalResult = result.GetType().GetProperty("Result")?.GetValue(result);
return new TypedFinalCommandExecution
var tokenSource = new CancellationTokenSource();
var token = tokenSource.Token;
try
{
Id = command.Id,
Result = finalResult,
CommandId = command.CommandId,
Type = finalResult?.GetType()
};
var result = (Task)currentCommand.Invoke(context, parameter is null ? new object[] { token } : new[]
{ parameter, token })!;
result.Wait(token);
return new FinalCommandExecution { CommandId = command.CommandId, Id = command.Id };
}
catch (Exception e)
{
return new ExceptionCommandExecution
{
Id = command.Id, CommandId = command.CommandId,
Exception = e.ToString()
};
}
}
catch (Exception e)
private static ICommandExecution TypedExecuteAsync(MethodInfo currentCommand, object context, object? parameter,
ICallRequest command)
{
return new ExceptionCommandExecution
var tokenSource = new CancellationTokenSource();
var token = tokenSource.Token;
try
{
Id = command.Id, CommandId = command.CommandId,
Exception = e.ToString()
};
var result =
(Task)currentCommand.Invoke(context, parameter is null ? new object[] { token } : new[]
{ parameter, token })!;
result.Wait(token);
var finalResult = result.GetType().GetProperty("Result")?.GetValue(result);
return new TypedFinalCommandExecution
{
Id = command.Id,
Result = finalResult,
CommandId = command.CommandId,
Type = finalResult?.GetType()
};
}
catch (Exception e)
{
return new ExceptionCommandExecution
{
Id = command.Id, CommandId = command.CommandId,
Exception = e.ToString()
};
}
}
}
}
+29 -26
View File
@@ -1,35 +1,38 @@
using mROA.Abstract;
using System;
using System.Collections.Generic;
using mROA.Abstract;
namespace mROA.Implementation.Backend;
public class ConnectionHub : IConnectionHub
namespace mROA.Implementation.Backend
{
private readonly Dictionary<int, INextGenerationInteractionModule> _connections = new();
private ISerializationToolkit? _serializationToolkit;
public class ConnectionHub : IConnectionHub
{
private readonly Dictionary<int, INextGenerationInteractionModule> _connections = new();
private ISerializationToolkit? _serializationToolkit;
public void RegisterInteraction(INextGenerationInteractionModule interaction)
{
if (_serializationToolkit is null)
throw new NullReferenceException("Serialization toolkit is null");
public void RegisterInteraction(INextGenerationInteractionModule interaction)
{
if (_serializationToolkit is null)
throw new NullReferenceException("Serialization toolkit is null");
_connections.Add(interaction.ConnectionId, interaction);
var module = new RepresentationModule();
module.Inject(_serializationToolkit);
module.Inject(interaction);
OnConnected?.Invoke(module);
}
_connections.Add(interaction.ConnectionId, interaction);
var module = new RepresentationModule();
module.Inject(_serializationToolkit);
module.Inject(interaction);
OnConnected?.Invoke(module);
}
public INextGenerationInteractionModule GetInteracion(int id)
{
return _connections!.GetValueOrDefault(id, null) ?? throw new Exception("No connection found");
}
public INextGenerationInteractionModule GetInteracion(int id)
{
return _connections!.GetValueOrDefault(id, null) ?? throw new Exception("No connection found");
}
public event ConnectionHandler? OnConnected;
public event DisconnectionHandler? OnDisconnected;
public void Inject<T>(T dependency)
{
if (dependency is ISerializationToolkit serializationToolkit)
_serializationToolkit = serializationToolkit;
public event ConnectionHandler? OnConnected;
public event DisconnectionHandler? OnDisconnected;
public void Inject<T>(T dependency)
{
if (dependency is ISerializationToolkit serializationToolkit)
_serializationToolkit = serializationToolkit;
}
}
}
@@ -1,88 +1,92 @@
using System.Collections.Frozen;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using mROA.Abstract;
using mROA.Implementation.Attributes;
namespace mROA.Implementation.Backend;
public class ContextRepository : IContextRepository
namespace mROA.Implementation.Backend
{
private FrozenDictionary<int, object?>? _singletons;
private object?[] _storage = new object[StartupSize];
private Task<int> _lastIndexFinder = Task.FromResult(0);
private const int StartupSize = 1024;
private const int GrowSize = 128;
public void FillSingletons(params Assembly[] assembly)
public class ContextRepository : IContextRepository
{
var types = assembly.SelectMany(x => x.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(SharedObjectInterfaceAttribute), true).Length > 0)!.GetHashCode(),
Activator.CreateInstance);
}
private Dictionary<int, object?>? _singletons;
private object?[] _storage = new object[StartupSize];
public int ResisterObject(object o)
{
if (!_lastIndexFinder.IsCompleted)
_lastIndexFinder.Wait();
private Task<int> _lastIndexFinder = Task.FromResult(0);
_storage[_lastIndexFinder.Result] = o;
private const int StartupSize = 1024;
private const int GrowSize = 128;
var last = _lastIndexFinder.Result;
_lastIndexFinder = Task.Run(FindLastIndex);
return last;
}
public void ClearObject(int id)
{
_storage[id] = null;
_lastIndexFinder = Task.FromResult(id);
}
public object GetObject(int 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]!;
}
public object GetSingleObject(Type type)
{
return _singletons!.GetValueOrDefault(type.GetHashCode()) ?? throw new ArgumentException("Unregistered singleton type");
}
public int GetObjectIndex(object o)
{
var index = Array.IndexOf(_storage, o);
return index == -1 ? ResisterObject(o) : index;
}
private int FindLastIndex()
{
for (var i = 0; i < _storage.Length; i++)
public void FillSingletons(params Assembly[] assembly)
{
if (_storage[i] is null)
return i;
var types = assembly.SelectMany(x => x.GetTypes()).Where(type =>
type is { IsClass: true, IsAbstract: false, IsGenericType: false } &&
type.GetCustomAttributes(typeof(SharedObjectSingletonAttribute), true).Length > 0);
_singletons =
types.ToDictionary(
t => t.GetInterfaces().FirstOrDefault(i =>
i.GetCustomAttributes(typeof(SharedObjectInterfaceAttribute), true).Length > 0)!.GetHashCode(),
Activator.CreateInstance);
}
var nextStorage = new object[_storage.Length + GrowSize];
Array.Copy(_storage, nextStorage, _storage.Length);
_storage = nextStorage;
return _storage.Length;
}
public void Inject<T>(T dependency)
{
}
public int ResisterObject(object o)
{
if (!_lastIndexFinder.IsCompleted)
_lastIndexFinder.Wait();
_storage[_lastIndexFinder.Result] = o;
var last = _lastIndexFinder.Result;
_lastIndexFinder = Task.Run(FindLastIndex);
return last;
}
public void ClearObject(int id)
{
_storage[id] = null;
_lastIndexFinder = Task.FromResult(id);
}
public object GetObject(int 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]!;
}
public object GetSingleObject(Type type)
{
return _singletons!.GetValueOrDefault(type.GetHashCode()) ?? throw new ArgumentException("Unregistered singleton type");
}
public int GetObjectIndex(object o)
{
var index = Array.IndexOf(_storage, o);
return index == -1 ? ResisterObject(o) : index;
}
private int FindLastIndex()
{
for (var i = 0; i < _storage.Length; i++)
{
if (_storage[i] is null)
return i;
}
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,50 +1,58 @@
using System;
using mROA.Abstract;
namespace mROA.Implementation.Backend;
public class HubRequestExtractor(Type extractoType) : IInjectableModule
namespace mROA.Implementation.Backend
{
private IConnectionHub? _hub;
private IContextRepository? _contextRepository;
private IMethodRepository? _methodRepository;
private ISerializationToolkit? _serializationToolkit;
private IExecuteModule? _executeModule;
public void Inject<T>(T dependency)
public class HubRequestExtractor : IInjectableModule
{
switch (dependency)
private IConnectionHub? _hub;
private IContextRepository? _contextRepository;
private IMethodRepository? _methodRepository;
private ISerializationToolkit? _serializationToolkit;
private IExecuteModule? _executeModule;
private readonly Type _extractorType;
public HubRequestExtractor(Type extractorType)
{
case IConnectionHub connectionHub:
_hub = connectionHub;
_hub.OnConnected += HubOnOnConnected;
break;
case IContextRepository contextRepository:
_contextRepository = contextRepository;
break;
case IMethodRepository methodRepository:
_methodRepository = methodRepository;
break;
case ISerializationToolkit serializationToolkit:
_serializationToolkit = serializationToolkit;
break;
case IExecuteModule executeModule:
_executeModule = executeModule;
break;
_extractorType = extractorType;
}
public void Inject<T>(T dependency)
{
switch (dependency)
{
case IConnectionHub connectionHub:
_hub = connectionHub;
_hub.OnConnected += HubOnOnConnected;
break;
case IContextRepository contextRepository:
_contextRepository = contextRepository;
break;
case IMethodRepository methodRepository:
_methodRepository = methodRepository;
break;
case ISerializationToolkit serializationToolkit:
_serializationToolkit = serializationToolkit;
break;
case IExecuteModule executeModule:
_executeModule = executeModule;
break;
}
}
private void HubOnOnConnected(IRepresentationModule interaction)
{
var extractor = (IRequestExtractor)Activator.CreateInstance(_extractorType)!;
extractor.Inject(interaction);
if (_contextRepository is IContextRepositoryHub contextHub)
extractor.Inject(contextHub.GetRepository(interaction.Id));
else
extractor.Inject(interaction);
extractor.Inject(_methodRepository);
extractor.Inject(_serializationToolkit);
extractor.Inject(_executeModule);
_ = extractor.StartExtraction();
}
}
private void HubOnOnConnected(IRepresentationModule interaction)
{
var extractor = (IRequestExtractor)Activator.CreateInstance(extractoType)!;
extractor.Inject(interaction);
if (_contextRepository is IContextRepositoryHub contextHub)
extractor.Inject(contextHub.GetRepository(interaction.Id));
else
extractor.Inject(interaction);
extractor.Inject(_methodRepository);
extractor.Inject(_serializationToolkit);
extractor.Inject(_executeModule);
_ = extractor.StartExtraction();
}
}
@@ -1,56 +1,65 @@
using System;
using System.Collections.Generic;
using mROA.Abstract;
namespace mROA.Implementation.Backend;
public class MultiClientContextRepository(Func<int, IContextRepository> produceRepository) : IContextRepository, IContextRepositoryHub
namespace mROA.Implementation.Backend
{
private Dictionary<int, IContextRepository> _repositories = new();
private IContextRepository GetRepositoryByClientId(int clientId)
public class MultiClientContextRepository : IContextRepository, IContextRepositoryHub
{
if (_repositories.TryGetValue(clientId, out var repository))
return repository;
private Dictionary<int, IContextRepository> _repositories = new();
private readonly Func<int, IContextRepository> _produceRepository;
public MultiClientContextRepository(Func<int, IContextRepository> produceRepository)
{
_produceRepository = produceRepository;
}
private IContextRepository GetRepositoryByClientId(int clientId)
{
if (_repositories.TryGetValue(clientId, out var repository))
return repository;
var created = produceRepository(clientId);
_repositories.Add(clientId, created);
return created;
}
public void Inject<T>(T dependency)
{
}
var created = _produceRepository(clientId);
_repositories.Add(clientId, created);
return created;
}
public void Inject<T>(T dependency)
{
}
public int ResisterObject(object o)
{
return GetRepositoryByClientId(TransmissionConfig.OwnershipRepository.GetOwnershipId()).ResisterObject(o);
}
public int ResisterObject(object o)
{
return GetRepositoryByClientId(TransmissionConfig.OwnershipRepository.GetOwnershipId()).ResisterObject(o);
}
public void ClearObject(int id)
{
GetRepositoryByClientId(TransmissionConfig.OwnershipRepository.GetOwnershipId()).ClearObject(id);
}
public void ClearObject(int id)
{
GetRepositoryByClientId(TransmissionConfig.OwnershipRepository.GetOwnershipId()).ClearObject(id);
}
public object GetObject(int id)
{
return GetRepositoryByClientId(TransmissionConfig.OwnershipRepository.GetOwnershipId()).GetObject(id);
}
public object GetObject(int id)
{
return GetRepositoryByClientId(TransmissionConfig.OwnershipRepository.GetOwnershipId()).GetObject(id);
}
public T? GetObject<T>(int id)
{
return GetRepositoryByClientId(TransmissionConfig.OwnershipRepository.GetOwnershipId()).GetObject<T>(id);
}
public T? GetObject<T>(int id)
{
return GetRepositoryByClientId(TransmissionConfig.OwnershipRepository.GetOwnershipId()).GetObject<T>(id);
}
public object GetSingleObject(Type type)
{
return GetRepositoryByClientId(TransmissionConfig.OwnershipRepository.GetOwnershipId()).GetSingleObject(type);
}
public object GetSingleObject(Type type)
{
return GetRepositoryByClientId(TransmissionConfig.OwnershipRepository.GetOwnershipId()).GetSingleObject(type);
}
public int GetObjectIndex(object o)
{
return GetRepositoryByClientId(TransmissionConfig.OwnershipRepository.GetOwnershipId()).GetObjectIndex(o);
}
public int GetObjectIndex(object o)
{
return GetRepositoryByClientId(TransmissionConfig.OwnershipRepository.GetOwnershipId()).GetObjectIndex(o);
}
public IContextRepository GetRepository(int clientId)
{
return GetRepositoryByClientId(clientId);
public IContextRepository GetRepository(int clientId)
{
return GetRepositoryByClientId(clientId);
}
}
}
@@ -1,28 +1,31 @@
using mROA.Abstract;
using System;
using System.Collections.Generic;
using mROA.Abstract;
namespace mROA.Implementation.Backend;
public class MultiClientOwnershipRepository : IOwnershipRepository
namespace mROA.Implementation.Backend
{
private Dictionary<int, int> _ownerships = new();
public int GetOwnershipId()
public class MultiClientOwnershipRepository : IOwnershipRepository
{
return _ownerships.GetValueOrDefault(Environment.CurrentManagedThreadId, 0);
}
private Dictionary<int, int> _ownerships = new();
public int GetHostOwnershipId()
{
return 0;
}
public int GetOwnershipId()
{
return _ownerships.GetValueOrDefault(Environment.CurrentManagedThreadId, 0);
}
public void RegisterOwnership(int ownershipId)
{
_ownerships.TryAdd(Environment.CurrentManagedThreadId, ownershipId);
}
public int GetHostOwnershipId()
{
return 0;
}
public void FreeOwnership()
{
_ownerships.Remove(Environment.CurrentManagedThreadId);
public void RegisterOwnership(int ownershipId)
{
_ownerships.TryAdd(Environment.CurrentManagedThreadId, ownershipId);
}
public void FreeOwnership()
{
_ownerships.Remove(Environment.CurrentManagedThreadId);
}
}
}
@@ -1,89 +1,91 @@
using System.Net;
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading.Tasks;
using mROA.Abstract;
namespace mROA.Implementation.Backend;
public class NetworkGatewayModule : IGatewayModule
namespace mROA.Implementation.Backend
{
private readonly Type? _interactionModuleType;
private readonly IInjectableModule[]? _injectableModules;
private readonly TcpListener _tcpListener;
private IConnectionHub? _hub;
private ISerializationToolkit? _serialization;
public NetworkGatewayModule(IPEndPoint endpoint, Type interactionModuleType, IInjectableModule[] injectableModules)
public class NetworkGatewayModule : IGatewayModule
{
_tcpListener = new(endpoint);
_interactionModuleType = interactionModuleType;
_injectableModules = injectableModules;
}
private readonly Type? _interactionModuleType;
private readonly IInjectableModule[]? _injectableModules;
private readonly TcpListener _tcpListener;
private IConnectionHub? _hub;
private ISerializationToolkit? _serialization;
public void Run()
{
_tcpListener.Start();
Console.WriteLine($"Listening on {_tcpListener.LocalEndpoint}");
Console.WriteLine("Enter Backspace to stop");
Task.Run(HandleIncomingConnections);
while (true)
public NetworkGatewayModule(IPEndPoint endpoint, Type interactionModuleType, IInjectableModule[] injectableModules)
{
var key = Console.ReadKey();
if (key.Key == ConsoleKey.Backspace)
break;
_tcpListener = new(endpoint);
_interactionModuleType = interactionModuleType;
_injectableModules = injectableModules;
}
Console.WriteLine("Stopping");
}
public void Dispose()
{
_tcpListener.Stop();
_tcpListener.Dispose();
}
private void HandleIncomingConnections()
{
if (_hub is null)
throw new NullReferenceException("Hub module is null");
if (_tcpListener == null)
throw new NullReferenceException("TcpListener is null");
if (_injectableModules is null)
throw new NullReferenceException("InjectableModules is null");
if (_interactionModuleType is null)
throw new NullReferenceException("InteractionModuleType is null");
if (_serialization is null)
throw new NullReferenceException("Serialization is null");
while (true)
public void Run()
{
var client = _tcpListener.AcceptTcpClient();
Console.WriteLine($"Client connected from {client.Client.RemoteEndPoint}");
var interaction = Activator.CreateInstance(_interactionModuleType) as INextGenerationInteractionModule;
_tcpListener.Start();
Console.WriteLine($"Listening on {_tcpListener.LocalEndpoint}");
Console.WriteLine("Enter Backspace to stop");
foreach (var injectableModule in _injectableModules)
interaction!.Inject(injectableModule);
Task.Run(HandleIncomingConnections);
interaction!.Inject(_serialization);
interaction.BaseStream = client.GetStream();
interaction.PostMessage(new NetworkMessage
while (true)
{
Id = Guid.NewGuid(), SchemaId = MessageType.IdAssigning,
Data = _serialization.Serialize(new IdAssingnment { Id = interaction.ConnectionId })
});
_hub.RegisterInteraction(interaction);
Console.WriteLine("Client registered");
}
}
var key = Console.ReadKey();
if (key.Key == ConsoleKey.Backspace)
break;
}
public void Inject<T>(T dependency)
{
if (dependency is IConnectionHub interactionModule)
_hub = interactionModule;
if (dependency is ISerializationToolkit serializationToolkit)
_serialization = serializationToolkit;
Console.WriteLine("Stopping");
}
public void Dispose()
{
_tcpListener.Stop();
}
private void HandleIncomingConnections()
{
if (_hub is null)
throw new NullReferenceException("Hub module is null");
if (_tcpListener == null)
throw new NullReferenceException("TcpListener is null");
if (_injectableModules is null)
throw new NullReferenceException("InjectableModules is null");
if (_interactionModuleType is null)
throw new NullReferenceException("InteractionModuleType is null");
if (_serialization is null)
throw new NullReferenceException("Serialization is null");
while (true)
{
var client = _tcpListener.AcceptTcpClient();
Console.WriteLine($"Client connected from {client.Client.RemoteEndPoint}");
var interaction = Activator.CreateInstance(_interactionModuleType) as INextGenerationInteractionModule;
foreach (var injectableModule in _injectableModules)
interaction!.Inject(injectableModule);
interaction!.Inject(_serialization);
interaction.BaseStream = client.GetStream();
interaction.PostMessage(new NetworkMessage
{
Id = Guid.NewGuid(), SchemaId = MessageType.IdAssigning,
Data = _serialization.Serialize(new IdAssingnment { Id = interaction.ConnectionId })
});
_hub.RegisterInteraction(interaction);
Console.WriteLine("Client registered");
}
}
public void Inject<T>(T dependency)
{
if (dependency is IConnectionHub interactionModule)
_hub = interactionModule;
if (dependency is ISerializationToolkit serializationToolkit)
_serialization = serializationToolkit;
}
}
}
+16 -13
View File
@@ -1,20 +1,23 @@
using System.Collections.Generic;
using System.Linq;
using mROA.Abstract;
namespace mROA.Implementation.Bootstrap;
public class FullMixBuilder
namespace mROA.Implementation.Bootstrap
{
public List<IInjectableModule> Modules { get; } = [];
public void Build()
public class FullMixBuilder
{
foreach (var module in Modules)
foreach (var injection in Modules)
module.Inject(injection);
}
public List<IInjectableModule> Modules { get; } = new() { };
public T? GetModule<T>()
{
return Modules.OfType<T>().FirstOrDefault();
public void Build()
{
foreach (var module in Modules)
foreach (var injection in Modules)
module.Inject(injection);
}
public T? GetModule<T>()
{
return Modules.OfType<T>().FirstOrDefault();
}
}
}
+19 -17
View File
@@ -1,24 +1,26 @@
using System.Text.Json.Serialization;
using System;
using System.Text.Json.Serialization;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace mROA.Implementation;
public interface ICallRequest
namespace mROA.Implementation
{
Guid Id { get; }
int CommandId { get; }
int ObjectId { get; }
object? Parameter { get; }
}
public interface ICallRequest
{
Guid Id { get; }
int CommandId { get; }
int ObjectId { get; }
object? Parameter { get; }
}
public class DefaultCallRequest : ICallRequest
{
public Guid Id { get; set; } = Guid.NewGuid();
public int CommandId { get; init; }
public int ObjectId { get; init; } = -1;
public class DefaultCallRequest : ICallRequest
{
public Guid Id { get; set; } = Guid.NewGuid();
public int CommandId { get; set; }
public int ObjectId { get; set; } = -1;
[JsonIgnore]
public Type? ParameterType { get; init; }
public object? Parameter { get; set; }
[JsonIgnore]
public Type? ParameterType { get; set; }
public object? Parameter { get; set; }
}
}
@@ -1,17 +1,19 @@
using mROA.Abstract;
using System;
using mROA.Abstract;
using mROA.Implementation.Frontend;
namespace mROA.Implementation.CommandExecution;
public class ExceptionCommandExecution : ICommandExecution
namespace mROA.Implementation.CommandExecution
{
public Guid Id { get; init; }
public int ClientId { get; set; }
public int CommandId { get; init; }
public required string Exception { get; set; }
public RemoteException GetException()
public class ExceptionCommandExecution : ICommandExecution
{
return new RemoteException(Exception) { CallRequestId = Id };
public Guid Id { get; set; }
public int ClientId { get; set; }
public int CommandId { get; set; }
public string Exception { get; set; }
public RemoteException GetException()
{
return new RemoteException(Exception) { CallRequestId = Id };
}
}
}
@@ -1,20 +1,22 @@
using System.Text.Json.Serialization;
using System;
using System.Text.Json.Serialization;
using mROA.Abstract;
// ReSharper disable UnusedAutoPropertyAccessor.Global
namespace mROA.Implementation.CommandExecution;
public class FinalCommandExecution : ICommandExecution
namespace mROA.Implementation.CommandExecution
{
public Guid Id { get; init; }
[JsonIgnore]
public int ClientId { get; set; }
[JsonIgnore]
public int CommandId { get; init; }
}
public class FinalCommandExecution : ICommandExecution
{
public Guid Id { get; set; }
[JsonIgnore]
public int ClientId { get; set; }
[JsonIgnore]
public int CommandId { get; set; }
}
public class FinalCommandExecution<T> : FinalCommandExecution
{
public T? Result { get; init; }
public class FinalCommandExecution<T> : FinalCommandExecution
{
public T? Result { get; set; }
}
}
@@ -1,10 +1,12 @@
using System.Text.Json.Serialization;
using System;
using System.Text.Json.Serialization;
namespace mROA.Implementation.CommandExecution;
public class TypedFinalCommandExecution : FinalCommandExecution<object>
namespace mROA.Implementation.CommandExecution
{
[JsonIgnore]
// ReSharper disable once UnusedAutoPropertyAccessor.Global
public Type? Type { get; set; }
public class TypedFinalCommandExecution : FinalCommandExecution<object>
{
[JsonIgnore]
// ReSharper disable once UnusedAutoPropertyAccessor.Global
public Type? Type { get; set; }
}
}
@@ -1,40 +1,42 @@
using mROA.Abstract;
using System;
using mROA.Abstract;
namespace mROA.Implementation;
public class CreativeRepresentationModuleProducer : IRepresentationModuleProducer
namespace mROA.Implementation
{
private Type _reprModuleType;
private IInjectableModule[] _creationModules;
private IConnectionHub? _hub;
public CreativeRepresentationModuleProducer(IInjectableModule[] creationModules, Type reprModuleType)
public class CreativeRepresentationModuleProducer : IRepresentationModuleProducer
{
_creationModules = creationModules;
_reprModuleType = reprModuleType;
}
private Type _reprModuleType;
private IInjectableModule[] _creationModules;
private IConnectionHub? _hub;
public CreativeRepresentationModuleProducer(IInjectableModule[] creationModules, Type reprModuleType)
{
_creationModules = creationModules;
_reprModuleType = reprModuleType;
}
public void Inject<T>(T dependency)
{
if (dependency is IConnectionHub interactionModule)
_hub = interactionModule;
}
public void Inject<T>(T dependency)
{
if (dependency is IConnectionHub interactionModule)
_hub = interactionModule;
}
public IRepresentationModule Produce(int id)
{
if (_hub == null)
throw new NullReferenceException("Interaction module is null");
public IRepresentationModule Produce(int id)
{
if (_hub == null)
throw new NullReferenceException("Interaction module is null");
var produced =
Activator.CreateInstance(_reprModuleType) as IRepresentationModule ??
throw new Exception("Bad serialization module type");
var produced =
Activator.CreateInstance(_reprModuleType) as IRepresentationModule ??
throw new Exception("Bad serialization module type");
foreach (var creationModule in _creationModules)
produced.Inject(creationModule);
foreach (var creationModule in _creationModules)
produced.Inject(creationModule);
produced.Inject(_hub.GetInteracion(id));
produced.Inject(_hub.GetInteracion(id));
return produced;
return produced;
}
}
}
@@ -1,6 +1,8 @@
namespace mROA.Implementation.Frontend;
using System;
// public class JsonFrontendSerialisationModule
namespace mROA.Implementation.Frontend
{
// public class JsonFrontendSerialisationModule
// : ISerialisationModule.IFrontendSerialisationModule
// {
// private IInteractionModule.IFrontendInteractionModule? _interactionModule;
@@ -77,8 +79,16 @@ namespace mROA.Implementation.Frontend;
// }
// }
public class RemoteException(string error) : Exception
{
public Guid CallRequestId;
public override string Message => $"Error in request {CallRequestId} : {error}";
public class RemoteException : Exception
{
public Guid CallRequestId;
private readonly string _error;
public RemoteException(string error)
{
_error = error;
}
public override string Message => $"Error in request {CallRequestId} : {_error}";
}
}
@@ -1,43 +1,51 @@
using System;
using System.Net;
using System.Net.Sockets;
using mROA.Abstract;
namespace mROA.Implementation.Frontend;
public class NetworkFrontendBridge(IPEndPoint ipEndPoint) : IFrontendBridge
namespace mROA.Implementation.Frontend
{
private readonly TcpClient _tcpClient = new();
private NextGenerationInteractionModule? _interactionModule;
private ISerializationToolkit? _serialization;
public void Inject<T>(T dependency)
public class NetworkFrontendBridge : IFrontendBridge
{
switch (dependency)
private readonly TcpClient _tcpClient = new();
private NextGenerationInteractionModule? _interactionModule;
private ISerializationToolkit? _serialization;
private readonly IPEndPoint _ipEndPoint;
public NetworkFrontendBridge(IPEndPoint ipEndPoint)
{
case NextGenerationInteractionModule interactionModule:
_interactionModule = interactionModule;
break;
case ISerializationToolkit toolkit:
_serialization = toolkit;
break;
_ipEndPoint = ipEndPoint;
}
}
public void Connect()
{
if (_interactionModule is null)
throw new Exception("Interaction module was not injected");
if (_serialization == null)
throw new NullReferenceException("Serialization toolkit is not initialized");
public void Inject<T>(T dependency)
{
switch (dependency)
{
case NextGenerationInteractionModule interactionModule:
_interactionModule = interactionModule;
break;
case ISerializationToolkit toolkit:
_serialization = toolkit;
break;
}
}
public void Connect()
{
if (_interactionModule is null)
throw new Exception("Interaction module was not injected");
if (_serialization == null)
throw new NullReferenceException("Serialization toolkit is not initialized");
_tcpClient.Connect(ipEndPoint);
_interactionModule.BaseStream = _tcpClient.GetStream();
var welcomeMessage = _interactionModule.GetNextMessageReceiving().GetAwaiter().GetResult();
if (welcomeMessage.SchemaId != MessageType.IdAssigning)
{
throw new Exception($"Incorrect message type. Must be IdAssigning, current : {welcomeMessage.SchemaId.ToString()}");
}
_tcpClient.Connect(_ipEndPoint);
_interactionModule.BaseStream = _tcpClient.GetStream();
var welcomeMessage = _interactionModule.GetNextMessageReceiving().GetAwaiter().GetResult();
if (welcomeMessage.SchemaId != MessageType.IdAssigning)
{
throw new Exception($"Incorrect message type. Must be IdAssigning, current : {welcomeMessage.SchemaId.ToString()}");
}
TransmissionConfig.OwnershipRepository = new StaticOwnershipRepository(_serialization.Deserialize<IdAssingnment>(welcomeMessage.Data)!.Id);
TransmissionConfig.OwnershipRepository = new StaticOwnershipRepository(_serialization.Deserialize<IdAssingnment>(welcomeMessage.Data)!.Id);
}
}
}
@@ -1,88 +1,92 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using mROA.Abstract;
using mROA.Implementation.Backend;
using mROA.Implementation.CommandExecution;
// ReSharper disable MethodHasAsyncOverload
namespace mROA.Implementation.Frontend;
public class RequestExtractor : IRequestExtractor
namespace mROA.Implementation.Frontend
{
private IRepresentationModule? _representationModule;
private IContextRepository? _contextRepository;
private IMethodRepository? _methodRepository;
private IExecuteModule? _executeModule;
private ISerializationToolkit? _serializationToolkit;
public void Inject<T>(T dependency)
public class RequestExtractor : IRequestExtractor
{
switch (dependency)
private IRepresentationModule? _representationModule;
private IContextRepository? _contextRepository;
private IMethodRepository? _methodRepository;
private IExecuteModule? _executeModule;
private ISerializationToolkit? _serializationToolkit;
public void Inject<T>(T dependency)
{
case IExecuteModule executeModule:
_executeModule = executeModule;
break;
case IContextRepository contextRepository:
_contextRepository = contextRepository;
break;
case IMethodRepository methodRepository:
_methodRepository = methodRepository;
break;
case IRepresentationModule representationModule:
_representationModule = representationModule;
break;
case ISerializationToolkit serializationToolkit:
_serializationToolkit = serializationToolkit;
break;
}
}
public async Task StartExtraction()
{
if (_serializationToolkit == null)
throw new NullReferenceException("Serializing toolkit is null.");
if (_executeModule == null)
throw new NullReferenceException("Execute module is null.");
if (_contextRepository == null)
throw new NullReferenceException("Context repository is null.");
if (_representationModule == null)
throw new NullReferenceException("Representation module is null.");
if (_methodRepository == null)
throw new NullReferenceException("Method repository is null.");
await Task.Yield();
var multiClientOwnershipRepository = TransmissionConfig.OwnershipRepository as MultiClientOwnershipRepository;
multiClientOwnershipRepository?.RegisterOwnership(_representationModule.Id);
try
{
while (true)
switch (dependency)
{
var request =
_representationModule!.GetMessage<DefaultCallRequest>(messageType: MessageType.CallRequest);
// Console.WriteLine("Executing {0}", request.Id);
if (request.Parameter is not null)
{
var parameterType = _methodRepository!.GetMethod(request.CommandId).GetParameters().First()
.ParameterType;
request.Parameter = _serializationToolkit.Cast(request.Parameter, parameterType);
}
var result = _executeModule.Execute(request, _contextRepository);
var resultType = result is FinalCommandExecution
? MessageType.FinishedCommandExecution
: MessageType.ExceptionCommandExecution;
_representationModule.PostCallMessage(request.Id, resultType, result, result.GetType());
case IExecuteModule executeModule:
_executeModule = executeModule;
break;
case IContextRepository contextRepository:
_contextRepository = contextRepository;
break;
case IMethodRepository methodRepository:
_methodRepository = methodRepository;
break;
case IRepresentationModule representationModule:
_representationModule = representationModule;
break;
case ISerializationToolkit serializationToolkit:
_serializationToolkit = serializationToolkit;
break;
}
}
catch
public async Task StartExtraction()
{
if (_serializationToolkit == null)
throw new NullReferenceException("Serializing toolkit is null.");
if (_executeModule == null)
throw new NullReferenceException("Execute module is null.");
if (_contextRepository == null)
throw new NullReferenceException("Context repository is null.");
if (_representationModule == null)
throw new NullReferenceException("Representation module is null.");
if (_methodRepository == null)
throw new NullReferenceException("Method repository is null.");
await Task.Yield();
var multiClientOwnershipRepository = TransmissionConfig.OwnershipRepository as MultiClientOwnershipRepository;
multiClientOwnershipRepository?.RegisterOwnership(_representationModule.Id);
try
{
while (true)
{
var request =
_representationModule!.GetMessage<DefaultCallRequest>(messageType: MessageType.CallRequest);
// Console.WriteLine("Executing {0}", request.Id);
if (request.Parameter is not null)
{
var parameterType = _methodRepository!.GetMethod(request.CommandId).GetParameters().First()
.ParameterType;
request.Parameter = _serializationToolkit.Cast(request.Parameter, parameterType);
}
var result = _executeModule.Execute(request, _contextRepository);
var resultType = result is FinalCommandExecution
? MessageType.FinishedCommandExecution
: MessageType.ExceptionCommandExecution;
_representationModule.PostCallMessage(request.Id, resultType, result, result.GetType());
}
}
catch
{
multiClientOwnershipRepository?.RegisterOwnership(_representationModule.Id);
}
}
}
}
@@ -1,16 +1,24 @@
using mROA.Abstract;
namespace mROA.Implementation.Frontend;
public class StaticOwnershipRepository(int id) : IOwnershipRepository
namespace mROA.Implementation.Frontend
{
public int GetOwnershipId()
public class StaticOwnershipRepository : IOwnershipRepository
{
return id;
}
private readonly int _id;
public int GetHostOwnershipId()
{
return id;
public StaticOwnershipRepository(int id)
{
_id = id;
}
public int GetOwnershipId()
{
return _id;
}
public int GetHostOwnershipId()
{
return _id;
}
}
}
+5 -4
View File
@@ -1,6 +1,7 @@
namespace mROA.Implementation;
public class IdAssingnment
namespace mROA.Implementation
{
public int Id { get; set; }
public class IdAssingnment
{
public int Id { get; set; }
}
}
+51 -49
View File
@@ -1,59 +1,61 @@
using System.Text.Json;
using System;
using System.Text.Json;
using mROA.Abstract;
namespace mROA.Implementation;
public class JsonSerializationToolkit : ISerializationToolkit
namespace mROA.Implementation
{
public byte[] Serialize<T>(T objectToSerialize)
public class JsonSerializationToolkit : ISerializationToolkit
{
return JsonSerializer.SerializeToUtf8Bytes(objectToSerialize);
}
public byte[] Serialize(object objectToSerialize, Type type)
{
return JsonSerializer.SerializeToUtf8Bytes(objectToSerialize, type);
}
public T? Deserialize<T>(byte[] rawData)
{
return JsonSerializer.Deserialize<T>(rawData);
}
public object? Deserialize(byte[] rawData, Type type)
{
return JsonSerializer.Deserialize(rawData, type);
}
public T? Deserialize<T>(Span<byte> rawData)
{
return JsonSerializer.Deserialize<T>(rawData);
}
public object? Deserialize(Span<byte> rawData, Type type)
{
return JsonSerializer.Deserialize(rawData, type);
}
public T Cast<T>(object nonCasted)
{
return nonCasted switch
public byte[] Serialize<T>(T objectToSerialize)
{
JsonElement jsonElement => jsonElement.Deserialize<T>()!,
T casted => casted,
_ => throw new JsonException("Cannot cast object to type " + typeof(T).FullName)
};
}
return JsonSerializer.SerializeToUtf8Bytes(objectToSerialize);
}
public object Cast(object nonCasted, Type type)
{
if (nonCasted is JsonElement jsonElement)
return jsonElement.Deserialize(type)!;
public byte[] Serialize(object objectToSerialize, Type type)
{
return JsonSerializer.SerializeToUtf8Bytes(objectToSerialize, type);
}
throw new JsonException("Cannot cast object to type " + type.FullName);
}
public T? Deserialize<T>(byte[] rawData)
{
return JsonSerializer.Deserialize<T>(rawData);
}
public void Inject<T>(T dependency)
{
public object? Deserialize(byte[] rawData, Type type)
{
return JsonSerializer.Deserialize(rawData, type);
}
public T? Deserialize<T>(Span<byte> rawData)
{
return JsonSerializer.Deserialize<T>(rawData);
}
public object? Deserialize(Span<byte> rawData, Type type)
{
return JsonSerializer.Deserialize(rawData, type);
}
public T Cast<T>(object nonCasted)
{
return nonCasted switch
{
JsonElement jsonElement => jsonElement.Deserialize<T>()!,
T casted => casted,
_ => throw new JsonException("Cannot cast object to type " + typeof(T).FullName)
};
}
public object Cast(object nonCasted, Type type)
{
if (nonCasted is JsonElement jsonElement)
return jsonElement.Deserialize(type)!;
throw new JsonException("Cannot cast object to type " + type.FullName);
}
public void Inject<T>(T dependency)
{
}
}
}
+37 -33
View File
@@ -1,43 +1,47 @@
using System.Reflection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using mROA.Abstract;
using mROA.Implementation.Attributes;
namespace mROA.Implementation;
public class MethodRepository : IMethodRepository
namespace mROA.Implementation
{
private readonly List<MethodInfo> _methods = [];
public MethodInfo GetMethod(int id)
public class MethodRepository : IMethodRepository
{
if (_methods.Count <= id)
throw new Exception("Method such registered method");
private readonly List<MethodInfo> _methods = new() { };
return _methods[id];
}
public int RegisterMethod(MethodInfo method)
{
_methods.Add(method);
return _methods.Count - 1;
}
public IEnumerable<MethodInfo> GetMethods()
{
return _methods;
}
public void CollectForAssembly(Assembly assembly)
{
var types = assembly.GetTypes().Where(i => i.IsInterface && i.GetCustomAttributes(typeof(SharedObjectInterfaceAttribute), true).Length > 0);
foreach (var type in types)
public MethodInfo GetMethod(int id)
{
foreach (var method in type.GetMethods())
RegisterMethod(method);
if (_methods.Count <= id)
throw new Exception("Method such registered method");
return _methods[id];
}
public int RegisterMethod(MethodInfo method)
{
_methods.Add(method);
return _methods.Count - 1;
}
public IEnumerable<MethodInfo> GetMethods()
{
return _methods;
}
public void CollectForAssembly(Assembly assembly)
{
var types = assembly.GetTypes().Where(i => i.IsInterface && i.GetCustomAttributes(typeof(SharedObjectInterfaceAttribute), true).Length > 0);
foreach (var type in types)
{
foreach (var method in type.GetMethods())
RegisterMethod(method);
}
}
public void Inject<T>(T dependency)
{
}
}
public void Inject<T>(T dependency)
{
}
}
+14 -12
View File
@@ -1,18 +1,20 @@
using System.Text.Json.Serialization;
using System;
using System.Text.Json.Serialization;
// ReSharper disable UnusedMember.Global
namespace mROA.Implementation;
public class NetworkMessage
namespace mROA.Implementation
{
public Guid Id { get; init; }
[JsonConverter(typeof(JsonStringEnumConverter))]
public MessageType SchemaId { get; init; }
public class NetworkMessage
{
public Guid Id { get; set; }
[JsonConverter(typeof(JsonStringEnumConverter))]
public MessageType SchemaId { get; set; }
public required byte[] Data { get; init; }
}
public byte[] Data { get; set; }
}
public enum MessageType
{
Unknown, FinishedCommandExecution, ExceptionCommandExecution, AsyncCancelCommandExecution, CallRequest, IdAssigning
public enum MessageType
{
Unknown, FinishedCommandExecution, ExceptionCommandExecution, AsyncCancelCommandExecution, CallRequest, IdAssigning
}
}
@@ -1,87 +1,95 @@
using mROA.Abstract;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using mROA.Abstract;
namespace mROA.Implementation;
public class NextGenerationInteractionModule : INextGenerationInteractionModule
namespace mROA.Implementation
{
private ISerializationToolkit? _serialization;
public int ConnectionId { get; private set; }
public Stream? BaseStream { get; set; }
private Task<NetworkMessage>? _currentReceiving;
private const int BufferSize = ushort.MaxValue;
private readonly Memory<byte> _buffer = new byte[BufferSize];
private readonly List<NetworkMessage> _messageBuffer = new (128);
public void Inject<T>(T dependency)
public class NextGenerationInteractionModule : INextGenerationInteractionModule
{
switch (dependency)
private ISerializationToolkit? _serialization;
public int ConnectionId { get; private set; }
public Stream? BaseStream { get; set; }
private Task<NetworkMessage>? _currentReceiving;
private const int BufferSize = ushort.MaxValue;
private readonly Memory<byte> _buffer = new byte[BufferSize];
private readonly List<NetworkMessage> _messageBuffer = new (128);
public void Inject<T>(T dependency)
{
case ISerializationToolkit toolkit:
_serialization = toolkit;
break;
case IIdentityGenerator identityGenerator:
ConnectionId = identityGenerator.GetNextIdentity();
break;
switch (dependency)
{
case ISerializationToolkit toolkit:
_serialization = toolkit;
break;
case IIdentityGenerator identityGenerator:
ConnectionId = identityGenerator.GetNextIdentity();
break;
}
}
public Task<NetworkMessage> GetNextMessageReceiving()
{
if (_currentReceiving != null) return _currentReceiving;
_currentReceiving = Task.Run(GetNextMessage);
return _currentReceiving;
}
public async Task PostMessage(NetworkMessage message)
{
if (BaseStream == null)
throw new NullReferenceException("BaseStream is null");
if (_serialization == null)
throw new NullReferenceException("Serialization toolkit is not initialized");
// Console.WriteLine("Sending {0}", JsonSerializer.Serialize(message));
var rawMessage = _serialization.Serialize(message);
await BaseStream.WriteAsync(BitConverter.GetBytes((ushort)rawMessage.Length).AsMemory(0, sizeof(ushort)));
await BaseStream.WriteAsync(rawMessage);
}
public void HandleMessage(NetworkMessage message)
{
_messageBuffer.Remove(message);
}
public NetworkMessage[] UnhandledMessages => _messageBuffer.ToArray();
public NetworkMessage? FirstByFilter(Predicate<NetworkMessage> predicate)
{
return _messageBuffer.FirstOrDefault(m => predicate(m));
}
private async Task<NetworkMessage> GetNextMessage()
{
if (BaseStream == null)
throw new NullReferenceException("BaseStream is null");
if (_serialization == null)
throw new NullReferenceException("Serialization toolkit is null");
// Console.WriteLine("Receiving message");
var firstBit = (byte)BaseStream.ReadByte();
var secondBit = (byte)BaseStream.ReadByte();
var len = BitConverter.ToUInt16(new[] { firstBit, secondBit});
var localSpan = _buffer.Slice(0, len);
await BaseStream.ReadExactlyAsync(localSpan);
// Console.WriteLine("Receiving {0}", Encoding.Default.GetString(_buffer[..len]));
var message = _serialization.Deserialize<NetworkMessage>(localSpan.Span);
_messageBuffer.Add(message!);
_currentReceiving = GetNextMessage();
return message!;
}
}
public Task<NetworkMessage> GetNextMessageReceiving()
{
if (_currentReceiving != null) return _currentReceiving;
_currentReceiving = Task.Run(GetNextMessage);
return _currentReceiving;
}
public async Task PostMessage(NetworkMessage message)
{
if (BaseStream == null)
throw new NullReferenceException("BaseStream is null");
if (_serialization == null)
throw new NullReferenceException("Serialization toolkit is not initialized");
// Console.WriteLine("Sending {0}", JsonSerializer.Serialize(message));
var rawMessage = _serialization.Serialize(message);
await BaseStream.WriteAsync(BitConverter.GetBytes((ushort)rawMessage.Length).AsMemory(0, sizeof(ushort)));
await BaseStream.WriteAsync(rawMessage);
}
public void HandleMessage(NetworkMessage message)
{
_messageBuffer.Remove(message);
}
public NetworkMessage[] UnhandledMessages => _messageBuffer.ToArray();
public NetworkMessage? FirstByFilter(Predicate<NetworkMessage> predicate)
{
return _messageBuffer.FirstOrDefault(m => predicate(m));
}
private NetworkMessage GetNextMessage()
{
if (BaseStream == null)
throw new NullReferenceException("BaseStream is null");
if (_serialization == null)
throw new NullReferenceException("Serialization toolkit is null");
// Console.WriteLine("Receiving message");
var len = BitConverter.ToUInt16([(byte)BaseStream.ReadByte(), (byte)BaseStream.ReadByte()]);
var localSpan = _buffer.Span.Slice(0, len);
BaseStream.ReadExactly(localSpan);
// Console.WriteLine("Receiving {0}", Encoding.Default.GetString(_buffer[..len]));
var message = _serialization.Deserialize<NetworkMessage>(localSpan);
_messageBuffer.Add(message!);
_currentReceiving = Task.Run(GetNextMessage);
return message!;
}
}
+50 -48
View File
@@ -1,57 +1,59 @@
using System.Collections.Frozen;
using System;
using System.Collections.Generic;
using mROA.Abstract;
namespace mROA.Implementation;
public class RemoteContextRepository : IContextRepository
namespace mROA.Implementation
{
private IRepresentationModuleProducer? _representationProducer;
public static FrozenDictionary<Type, Type> RemoteTypes = FrozenDictionary<Type, Type>.Empty;
public int ResisterObject(object o)
public class RemoteContextRepository : IContextRepository
{
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 (_representationProducer == null)
throw new NullReferenceException("representation producer is not initialized");
if (!RemoteTypes.TryGetValue(typeof(T), out var remoteType)) throw new NotSupportedException();
var remote = (T)Activator.CreateInstance(remoteType, id, _representationProducer.Produce(TransmissionConfig.OwnershipRepository.GetOwnershipId()))!;
return remote;
}
public object GetSingleObject(Type type)
{
if (_representationProducer == null)
throw new NullReferenceException("representation producer is not initialized");
return Activator.CreateInstance(RemoteTypes[type], -1, _representationProducer.Produce(TransmissionConfig.OwnershipRepository.GetOwnershipId()))!;
}
public int GetObjectIndex(object o)
{
if (o is RemoteObjectBase remote)
private IRepresentationModuleProducer? _representationProducer;
public static Dictionary<Type, Type> RemoteTypes = new();
public int ResisterObject(object o)
{
return remote.Id;
throw new NotSupportedException();
}
throw new NotSupportedException();
}
public void Inject<T>(T dependency)
{
if (dependency is IRepresentationModuleProducer serialisationModule)
_representationProducer = serialisationModule;
public void ClearObject(int id)
{
throw new NotSupportedException();
}
public object GetObject(int id)
{
throw new NotSupportedException();
}
public T GetObject<T>(int id)
{
if (_representationProducer == null)
throw new NullReferenceException("representation producer is not initialized");
if (!RemoteTypes.TryGetValue(typeof(T), out var remoteType)) throw new NotSupportedException();
var remote = (T)Activator.CreateInstance(remoteType, id, _representationProducer.Produce(TransmissionConfig.OwnershipRepository.GetOwnershipId()))!;
return remote;
}
public object GetSingleObject(Type type)
{
if (_representationProducer == null)
throw new NullReferenceException("representation producer is not initialized");
return Activator.CreateInstance(RemoteTypes[type], -1, _representationProducer.Produce(TransmissionConfig.OwnershipRepository.GetOwnershipId()))!;
}
public int GetObjectIndex(object o)
{
if (o is RemoteObjectBase remote)
{
return remote.Id;
}
throw new NotSupportedException();
}
public void Inject<T>(T dependency)
{
if (dependency is IRepresentationModuleProducer serialisationModule)
_representationProducer = serialisationModule;
}
}
}
+48 -37
View File
@@ -1,53 +1,64 @@
using mROA.Abstract;
using System.Threading.Tasks;
using mROA.Abstract;
using mROA.Implementation.CommandExecution;
// ReSharper disable UnusedMember.Global
namespace mROA.Implementation;
public abstract class RemoteObjectBase(int id, IRepresentationModule representationModule)
namespace mROA.Implementation
{
public int Id => id;
public int OwnerId => representationModule.Id;
protected async Task<T> GetResultAsync<T>(int methodId, object? parameter = default)
public abstract class RemoteObjectBase
{
var request = new DefaultCallRequest
{ CommandId = methodId, ObjectId = id, Parameter = parameter, ParameterType = parameter?.GetType() };
await representationModule.PostCallMessageAsync(request.Id, MessageType.CallRequest, request);
private readonly int _id;
private readonly IRepresentationModule _representationModule;
var successResponse =
representationModule.GetMessageAsync<FinalCommandExecution<T>>(
messageType: MessageType.FinishedCommandExecution, requestId: request.Id);
var errorResponse =
representationModule.GetMessageAsync<ExceptionCommandExecution>(
messageType: MessageType.ExceptionCommandExecution, requestId: request.Id);
Task.WaitAny(successResponse, errorResponse);
protected RemoteObjectBase(int id, IRepresentationModule representationModule)
{
_id = id;
_representationModule = representationModule;
}
if (successResponse.IsCompletedSuccessfully)
return successResponse.Result.Result!;
public int Id => _id;
public int OwnerId => _representationModule.Id;
throw errorResponse.Result.GetException();
}
protected async Task<T> GetResultAsync<T>(int methodId, object? parameter = default)
{
var request = new DefaultCallRequest
{ CommandId = methodId, ObjectId = _id, Parameter = parameter, ParameterType = parameter?.GetType() };
await _representationModule.PostCallMessageAsync(request.Id, MessageType.CallRequest, request);
protected async Task CallAsync(int methodId, object? parameter = default)
{
var request = new DefaultCallRequest
{ CommandId = methodId, ObjectId = id, Parameter = parameter, ParameterType = parameter?.GetType() };
await representationModule.PostCallMessageAsync(request.Id, MessageType.CallRequest, request);
var successResponse =
_representationModule.GetMessageAsync<FinalCommandExecution<T>>(
messageType: MessageType.FinishedCommandExecution, requestId: request.Id);
var errorResponse =
_representationModule.GetMessageAsync<ExceptionCommandExecution>(
messageType: MessageType.ExceptionCommandExecution, requestId: request.Id);
Task.WaitAny(successResponse, errorResponse);
var successResponse =
representationModule.GetMessageAsync<FinalCommandExecution>(
messageType: MessageType.FinishedCommandExecution, requestId: request.Id);
var errorResponse =
representationModule.GetMessageAsync<ExceptionCommandExecution>(
messageType: MessageType.ExceptionCommandExecution, requestId: request.Id);
if (successResponse.IsCompletedSuccessfully)
return successResponse.Result.Result!;
Task.WaitAny(successResponse, errorResponse);
throw errorResponse.Result.GetException();
}
if (successResponse.IsCompletedSuccessfully)
return;
protected async Task CallAsync(int methodId, object? parameter = default)
{
var request = new DefaultCallRequest
{ CommandId = methodId, ObjectId = _id, Parameter = parameter, ParameterType = parameter?.GetType() };
await _representationModule.PostCallMessageAsync(request.Id, MessageType.CallRequest, request);
throw errorResponse.Result.GetException();
var successResponse =
_representationModule.GetMessageAsync<FinalCommandExecution>(
messageType: MessageType.FinishedCommandExecution, requestId: request.Id);
var errorResponse =
_representationModule.GetMessageAsync<ExceptionCommandExecution>(
messageType: MessageType.ExceptionCommandExecution, requestId: request.Id);
Task.WaitAny(successResponse, errorResponse);
if (successResponse.IsCompletedSuccessfully)
return;
throw errorResponse.Result.GetException();
}
}
}
+82 -79
View File
@@ -1,93 +1,96 @@
using mROA.Abstract;
using System;
using System.Threading.Tasks;
using mROA.Abstract;
namespace mROA.Implementation;
public class RepresentationModule : IRepresentationModule
namespace mROA.Implementation
{
private ISerializationToolkit? _serialization;
private INextGenerationInteractionModule? _interaction;
public void Inject<T>(T dependency)
public class RepresentationModule : IRepresentationModule
{
switch (dependency)
private ISerializationToolkit? _serialization;
private INextGenerationInteractionModule? _interaction;
public void Inject<T>(T dependency)
{
case ISerializationToolkit toolkit:
_serialization = toolkit;
break;
case INextGenerationInteractionModule interactionModule:
_interaction = interactionModule;
break;
}
}
public int Id => (_interaction ?? throw new NullReferenceException("Interaction is not initialized")).ConnectionId;
public async Task<T> GetMessageAsync<T>(Guid? requestId, MessageType? messageType)
{
if (_serialization == null)
throw new NullReferenceException("Serialization toolkit is not initialized");
return _serialization.Deserialize<T>(await GetRawMessage(requestId, messageType))!;
}
public T GetMessage<T>(Guid? requestId = null, MessageType? messageType = null)
{
if (_serialization == null)
throw new NullReferenceException("Serialization toolkit is not initialized");
return _serialization.Deserialize<T>(GetRawMessage(requestId, messageType).GetAwaiter().GetResult())!;
}
public async Task<byte[]> GetRawMessage(Guid? requestId = null, MessageType? messageType = null)
{
if (_interaction == null)
throw new NullReferenceException("Interaction toolkit is not initialized");
var fromBuffer =
_interaction.FirstByFilter(message =>
(requestId is null || message.Id == requestId) &&
(messageType is null || message.SchemaId == messageType));
if (fromBuffer == null)
{
while (true)
switch (dependency)
{
var message = await _interaction.GetNextMessageReceiving();
if ((requestId is not null && message.Id != requestId) ||
(messageType is not null && message.SchemaId != messageType)) continue;
_interaction.HandleMessage(message);
return message.Data;
case ISerializationToolkit toolkit:
_serialization = toolkit;
break;
case INextGenerationInteractionModule interactionModule:
_interaction = interactionModule;
break;
}
}
_interaction.HandleMessage(fromBuffer);
return fromBuffer.Data;
}
public int Id => (_interaction ?? throw new NullReferenceException("Interaction is not initialized")).ConnectionId;
public async Task PostCallMessageAsync<T>(Guid id, MessageType messageType, T payload) where T : notnull
{
await PostCallMessageAsync(id, messageType, payload, typeof(T));
}
public async Task PostCallMessageAsync(Guid id, MessageType messageType, object payload, Type payloadType)
{
if (_interaction == null)
throw new NullReferenceException("Interaction toolkit is not initialized");
if (_serialization == null)
throw new NullReferenceException("Serialization toolkit is not initialized");
public async Task<T> GetMessageAsync<T>(Guid? requestId, MessageType? messageType)
{
if (_serialization == null)
throw new NullReferenceException("Serialization toolkit is not initialized");
await _interaction.PostMessage(new NetworkMessage
{ Id = id, SchemaId = messageType, Data = _serialization.Serialize(payload, payloadType) });
}
return _serialization.Deserialize<T>(await GetRawMessage(requestId, messageType))!;
}
public void PostCallMessage<T>(Guid id, MessageType messageType, T payload) where T : notnull
{
PostCallMessageAsync(id, messageType, payload).GetAwaiter().GetResult();
}
public T GetMessage<T>(Guid? requestId = null, MessageType? messageType = null)
{
if (_serialization == null)
throw new NullReferenceException("Serialization toolkit is not initialized");
return _serialization.Deserialize<T>(GetRawMessage(requestId, messageType).GetAwaiter().GetResult())!;
}
public void PostCallMessage(Guid id, MessageType messageType, object payload, Type payloadType)
{
PostCallMessageAsync(id, messageType, payload, payloadType).GetAwaiter().GetResult();
public async Task<byte[]> GetRawMessage(Guid? requestId = null, MessageType? messageType = null)
{
if (_interaction == null)
throw new NullReferenceException("Interaction toolkit is not initialized");
var fromBuffer =
_interaction.FirstByFilter(message =>
(requestId is null || message.Id == requestId) &&
(messageType is null || message.SchemaId == messageType));
if (fromBuffer == null)
{
while (true)
{
var message = await _interaction.GetNextMessageReceiving();
if ((requestId is not null && message.Id != requestId) ||
(messageType is not null && message.SchemaId != messageType)) continue;
_interaction.HandleMessage(message);
return message.Data;
}
}
_interaction.HandleMessage(fromBuffer);
return fromBuffer.Data;
}
public async Task PostCallMessageAsync<T>(Guid id, MessageType messageType, T payload) where T : notnull
{
await PostCallMessageAsync(id, messageType, payload, typeof(T));
}
public async Task PostCallMessageAsync(Guid id, MessageType messageType, object payload, Type payloadType)
{
if (_interaction == null)
throw new NullReferenceException("Interaction toolkit is not initialized");
if (_serialization == null)
throw new NullReferenceException("Serialization toolkit is not initialized");
await _interaction.PostMessage(new NetworkMessage
{ Id = id, SchemaId = messageType, Data = _serialization.Serialize(payload, payloadType) });
}
public void PostCallMessage<T>(Guid id, MessageType messageType, T payload) where T : notnull
{
PostCallMessageAsync(id, messageType, payload).GetAwaiter().GetResult();
}
public void PostCallMessage(Guid id, MessageType messageType, object payload, Type payloadType)
{
PostCallMessageAsync(id, messageType, payload, payloadType).GetAwaiter().GetResult();
}
}
}
+81 -79
View File
@@ -1,101 +1,103 @@
using System.Text.Json.Serialization;
using System;
using System.Text.Json.Serialization;
using mROA.Abstract;
// ReSharper disable UnusedMember.Global
#pragma warning disable CS8618, CS9264
namespace mROA.Implementation;
public static class TransmissionConfig
namespace mROA.Implementation
{
private static IContextRepository? _realContextRepository;
private static IContextRepository? _remoteEndpointContextRepository;
private static IOwnershipRepository? _ownershipRepository;
public static IContextRepository RealContextRepository
public static class TransmissionConfig
{
get => _realContextRepository ?? throw new NullReferenceException("RealContextRepository is null");
set => _realContextRepository = value;
}
private static IContextRepository? _realContextRepository;
private static IContextRepository? _remoteEndpointContextRepository;
private static IOwnershipRepository? _ownershipRepository;
public static IContextRepository RemoteEndpointContextRepository
{
get => _remoteEndpointContextRepository ?? throw new NullReferenceException("RemoteEndpointContextRepository is null");
set => _remoteEndpointContextRepository = value;
}
public static IOwnershipRepository OwnershipRepository
{
get => _ownershipRepository ?? throw new NullReferenceException("OwnershipRepository is null");
set => _ownershipRepository = value;
}
}
public class SharedObject<T> where T : notnull
{
private IContextRepository GetDefaultContextRepository() =>
(OwnerId == TransmissionConfig.OwnershipRepository.GetHostOwnershipId()
? TransmissionConfig.RealContextRepository
: TransmissionConfig.RemoteEndpointContextRepository) ??
throw new NullReferenceException(
"DefaultContextRepository was not defined");
private int _contextId = -2;
private int _ownerId = -1;
public int OwnerId
{
get
public static IContextRepository RealContextRepository
{
_ownerId = _ownerId == -1 ? TransmissionConfig.OwnershipRepository.GetOwnershipId() : _ownerId;
return _ownerId;
get => _realContextRepository ?? throw new NullReferenceException("RealContextRepository is null");
set => _realContextRepository = value;
}
init => _ownerId = value;
public static IContextRepository RemoteEndpointContextRepository
{
get => _remoteEndpointContextRepository ?? throw new NullReferenceException("RemoteEndpointContextRepository is null");
set => _remoteEndpointContextRepository = value;
}
public static IOwnershipRepository OwnershipRepository
{
get => _ownershipRepository ?? throw new NullReferenceException("OwnershipRepository is null");
set => _ownershipRepository = value;
}
}
// ReSharper disable once MemberCanBePrivate.Global
public int ContextId
public class SharedObject<T> where T : notnull
{
// ReSharper disable once UnusedMember.Global
get
private IContextRepository GetDefaultContextRepository() =>
(OwnerId == TransmissionConfig.OwnershipRepository.GetHostOwnershipId()
? TransmissionConfig.RealContextRepository
: TransmissionConfig.RemoteEndpointContextRepository) ??
throw new NullReferenceException(
"DefaultContextRepository was not defined");
private int _contextId = -2;
private int _ownerId = -1;
public int OwnerId
{
if (_contextId != -2)
get
{
_ownerId = _ownerId == -1 ? TransmissionConfig.OwnershipRepository.GetOwnershipId() : _ownerId;
return _ownerId;
}
set => _ownerId = value;
}
// ReSharper disable once MemberCanBePrivate.Global
public int ContextId
{
// ReSharper disable once UnusedMember.Global
get
{
if (_contextId != -2)
return _contextId;
_contextId = TransmissionConfig.RealContextRepository.GetObjectIndex(Value);
return _contextId;
_contextId = TransmissionConfig.RealContextRepository.GetObjectIndex(Value);
return _contextId;
}
set
{
_contextId = value;
Value = GetDefaultContextRepository().GetObject<T>(_contextId)!;
}
}
init
[JsonIgnore] public T Value { get; private set; }
// ReSharper disable once MemberCanBePrivate.Global
// ReSharper disable once UnusedMember.Global
public SharedObject()
{
_contextId = value;
Value = GetDefaultContextRepository().GetObject<T>(_contextId)!;
}
}
[JsonIgnore] public T Value { get; private init; }
// ReSharper disable once MemberCanBePrivate.Global
// ReSharper disable once UnusedMember.Global
public SharedObject()
{
}
// ReSharper disable once UnusedMember.Global
public SharedObject(T value)
{
Value = value;
if (value is RemoteObjectBase ro)
// ReSharper disable once UnusedMember.Global
public SharedObject(T value)
{
_ownerId = ro.OwnerId;
_contextId = ro.Id;
Value = value;
if (value is RemoteObjectBase ro)
{
_ownerId = ro.OwnerId;
_contextId = ro.Id;
}
else
_ownerId = TransmissionConfig.OwnershipRepository.GetHostOwnershipId();
}
else
_ownerId = TransmissionConfig.OwnershipRepository.GetHostOwnershipId();
public static implicit operator T(SharedObject<T> value) => value.Value;
public static implicit operator SharedObject<T>(T value) =>
new(value);
}
public static implicit operator T(SharedObject<T> value) => value.Value;
public static implicit operator SharedObject<T>(T value) =>
new(value);
}
@@ -1,21 +1,23 @@
using mROA.Abstract;
using System;
using mROA.Abstract;
namespace mROA.Implementation;
public class StaticRepresentationModuleProducer : IRepresentationModuleProducer
namespace mROA.Implementation
{
private IRepresentationModule? _representationModule;
public class StaticRepresentationModuleProducer : IRepresentationModuleProducer
{
private IRepresentationModule? _representationModule;
public IRepresentationModule Produce(int ownership)
{
if (_representationModule == null)
throw new NullReferenceException("The representation module is not initialized.");
return _representationModule;
}
public IRepresentationModule Produce(int ownership)
{
if (_representationModule == null)
throw new NullReferenceException("The representation module is not initialized.");
return _representationModule;
}
public void Inject<T>(T dependency)
{
if (dependency is IRepresentationModule serialisationModule)
_representationModule = serialisationModule;
public void Inject<T>(T dependency)
{
if (dependency is IRepresentationModule serialisationModule)
_representationModule = serialisationModule;
}
}
}
+43
View File
@@ -0,0 +1,43 @@
using System.Collections.Generic;
using global::System;
using global::System.IO;
using global::System.Threading;
using global::System.Threading.Tasks;
namespace mROA
{
public static class LegacyExtentions
{
public static async ValueTask<int> ReadExactlyAsync(this Stream stream, byte[] buffer, int offset, int count)
{
return await stream.ReadAtLeastAsyncCore(buffer.AsMemory(offset, count), count, true, default);
}
public static ValueTask<int> ReadExactlyAsync(this Stream stream, Memory<byte> buffer,
CancellationToken cancellationToken = default(CancellationToken))
{
return stream.ReadAtLeastAsyncCore(buffer, buffer.Length, true, cancellationToken);
}
private static async ValueTask<int> ReadAtLeastAsyncCore(this Stream stream,
Memory<byte> buffer,
int minimumBytes,
bool throwOnEndOfStream,
CancellationToken cancellationToken)
{
int totalRead;
int num;
for (totalRead = 0; totalRead < minimumBytes; totalRead += num)
{
num = await stream.ReadAsync(buffer.Slice(totalRead), cancellationToken).ConfigureAwait(false);
if (num == 0)
{
if (throwOnEndOfStream)
throw new EndOfStreamException();
return totalRead;
}
}
return totalRead;
}
}
}
+6 -2
View File
@@ -1,8 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<TargetFramework>netstandard2.1</TargetFramework>
<Nullable>enable</Nullable>
<Title>mROA</Title>
<Version>2.0.0</Version>
@@ -12,6 +11,11 @@
<PackageProjectUrl>https://github.com/YaslePoy/mROA</PackageProjectUrl>
<RepositoryType>git</RepositoryType>
<PackageTags>RPC</PackageTags>
<LangVersion>9</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Text.Json" Version="9.0.2" />
</ItemGroup>
</Project>