добавлены реализации
This commit is contained in:
@@ -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();
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
namespace mROA;
|
||||||
|
|
||||||
|
public interface IContextRepository
|
||||||
|
{
|
||||||
|
int ResisterObject(object o);
|
||||||
|
void ClearObject(int id);
|
||||||
|
object GetObject(int id);
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
namespace mROA;
|
||||||
|
|
||||||
|
public interface IExecuteModule
|
||||||
|
{
|
||||||
|
ICommandExecution Execute(int objectId, int commandId, object parameter);
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
namespace mROA;
|
||||||
|
|
||||||
|
public interface IMethodRepository
|
||||||
|
{
|
||||||
|
MethodInfo GetMethod(int id);
|
||||||
|
int RegisterMethod(MethodInfo method);
|
||||||
|
|
||||||
|
IEnumerable<MethodInfo> GetMethods();
|
||||||
|
}
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
namespace mROA;
|
|
||||||
|
|
||||||
public interface IExecuteModule
|
|
||||||
{
|
|
||||||
void Execute(int objectId, int commandId, object parameter);
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
namespace mROA;
|
|
||||||
|
|
||||||
public interface IInputModule
|
|
||||||
{
|
|
||||||
void AddIncomingRequestHandler(Action<object> handler);
|
|
||||||
void SendResponse(ICommandExecution call, object response);
|
|
||||||
}
|
|
||||||
@@ -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
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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 };
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user