добавлены реализации

This commit is contained in:
2025-01-11 22:44:29 +03:00
parent 7b60a07039
commit a4372ceb9e
14 changed files with 248 additions and 17 deletions
@@ -2,10 +2,7 @@ namespace mROA;
public interface ICommandExecution public interface ICommandExecution
{ {
int ExecutionId { get; set; } Guid ExecutionId { get; init; }
int ClientId { get; set; } int ClientId { get; set; }
int CommandId { get; set; } int CommandId { get; set; }
void Cancel();
} }
+8
View File
@@ -0,0 +1,8 @@
namespace mROA;
public interface IContextRepository
{
int ResisterObject(object o);
void ClearObject(int id);
object GetObject(int id);
}
+6
View File
@@ -0,0 +1,6 @@
namespace mROA;
public interface IExecuteModule
{
ICommandExecution Execute(int objectId, int commandId, object parameter);
}
+7
View File
@@ -0,0 +1,7 @@
namespace mROA;
public interface IInputModule
{
void HandleIncomingRequest(object command);
void PostResponse(ICommandExecution call);
}
@@ -2,5 +2,6 @@ namespace mROA;
public interface IInteractionModule public interface IInteractionModule
{ {
void SetInteractionHandler(Action<(int clientId, byte[] message)> handler);
void SendTo(int clientId, byte[] message); void SendTo(int clientId, byte[] message);
} }
+11
View File
@@ -0,0 +1,11 @@
using System.Reflection;
namespace mROA;
public interface IMethodRepository
{
MethodInfo GetMethod(int id);
int RegisterMethod(MethodInfo method);
IEnumerable<MethodInfo> GetMethods();
}
-6
View File
@@ -1,6 +0,0 @@
namespace mROA;
public interface IExecuteModule
{
void Execute(int objectId, int commandId, object parameter);
}
-7
View File
@@ -1,7 +0,0 @@
namespace mROA;
public interface IInputModule
{
void AddIncomingRequestHandler(Action<object> handler);
void SendResponse(ICommandExecution call, object response);
}
+34
View File
@@ -0,0 +1,34 @@
namespace mROA.Implementation;
public interface ICallRequest
{
int RequestTypeId { get; }
int CommandId { get; set; }
int ClientId { get; set; }
}
public class StaticCallRequest : ICallRequest
{
public virtual int RequestTypeId => (int)RequestType.Static;
public int CommandId { get; set; }
public int ClientId { get; set; }
}
public class CallRequest : StaticCallRequest
{
public override int RequestTypeId => (int)RequestType.NonParametrized;
public int ObjectId { get; set; }
}
public class ParametrizedCallRequest : CallRequest
{
public override int RequestTypeId => (int)RequestType.Parametrized;
public object Parameter { get; set; }
}
enum RequestType
{
Static,
NonParametrized,
Parametrized
}
+58
View File
@@ -0,0 +1,58 @@
namespace mROA.Implementation;
public class ContextRepository : IContextRepository
{
private object[] _storage;
private int _lastIndex;
private Task<int>? _lastIndexFinder;
const int StartupSize = 1024;
const int GrowSize = 128;
public ContextRepository()
{
_storage = new object[StartupSize];
}
public int ResisterObject(object o)
{
if (_lastIndexFinder is not null)
_lastIndexFinder.Wait();
var oldIndex = _lastIndex;
_lastIndex = _lastIndexFinder.Result;
_storage[oldIndex] = o;
_lastIndexFinder = FindLastIndex();
return _lastIndex;
}
public void ClearObject(int id)
{
_storage[id] = null;
_lastIndexFinder = Task.FromResult(id);
}
public object GetObject(int id)
{
return _storage.Length == -1 || _storage.Length <= id ? null : _storage[id];
}
private async Task<int> FindLastIndex()
{
for (int 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);
return _storage.Length;
}
}
@@ -0,0 +1,36 @@
namespace mROA.Implementation;
public class FinalCommandExecution : ICommandExecution
{
public Guid ExecutionId { get; init; } = new Guid();
public int ClientId { get; set; }
public int CommandId { get; set; }
public object? Result { get; set; }
}
public class ExeptionCommandExecution : ICommandExecution
{
public Guid ExecutionId { get; init; } = new Guid();
public int ClientId { get; set; }
public int CommandId { get; set; }
public string Reason { get; set; }
}
public class AsyncCommandExecution : ICommandExecution
{
public Guid ExecutionId { get; init; } = new Guid();
public int ClientId { get; set; }
public int CommandId { get; set; }
public void Cancel()
{
LocalToken.Cancel();
}
private CancellationTokenSource LocalToken;
public AsyncCommandExecution(CancellationTokenSource localToken)
{
LocalToken = localToken;
}
}
+21
View File
@@ -0,0 +1,21 @@
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace mROA.Implementation;
public class InputModule(IInteractionModule dataSource, IExecuteModule executeModule)
: IInputModule
{
public void HandleIncomingRequest(object command)
{
}
public void PostResponse(ICommandExecution call)
{
var texted = JsonSerializer.Serialize(call);
var binary = Encoding.UTF8.GetBytes(texted);
dataSource.SendTo(call.ClientId, binary);
}
}
+27
View File
@@ -0,0 +1,27 @@
using System.Reflection;
namespace mROA.Implementation;
public class MethodRepository : IMethodRepository
{
private List<MethodInfo> _methods;
public MethodInfo GetMethod(int id)
{
if (_methods.Count >= id)
return null;
return _methods[id];
}
public int RegisterMethod(MethodInfo method)
{
_methods.Add(method);
return _methods.Count - 1;
}
public IEnumerable<MethodInfo> GetMethods()
{
return _methods;
}
}
@@ -0,0 +1,38 @@
using System.Reflection;
namespace mROA.Implementation;
public class PrepairedExecutionModule(
IMethodRepository methodRepo,
IInputModule inputModule,
IContextRepository contextRepo)
: IExecuteModule
{
public ICommandExecution Execute(int objectId, int commandId, object parameter)
{
var command = methodRepo.GetMethod(commandId);
if (command == null)
throw new Exception($"Command {commandId} not found");
if (command.ReturnType != typeof(Task))
{
var tokenSource = new CancellationTokenSource();
var token = tokenSource.Token;
var result = command.Invoke(contextRepo.GetObject(objectId), [parameter, token]) as Task<object>;
var exec = new AsyncCommandExecution(tokenSource) { CommandId = commandId };
result.ContinueWith(task =>
{
var result = task.Result;
inputModule.PostResponse(new FinalCommandExecution
{ ExecutionId = exec.ExecutionId, Result = result, CommandId = commandId });
}, token);
return exec;
}
var finalResult = command.Invoke(contextRepo.GetObject(objectId), [parameter]);
return new FinalCommandExecution { CommandId = commandId, Result = finalResult };
}
}