добавлены реализации
This commit is contained in:
@@ -2,10 +2,7 @@ namespace mROA;
|
||||
|
||||
public interface ICommandExecution
|
||||
{
|
||||
int ExecutionId { get; set; }
|
||||
|
||||
Guid ExecutionId { get; init; }
|
||||
int ClientId { 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
|
||||
{
|
||||
void SetInteractionHandler(Action<(int clientId, byte[] message)> handler);
|
||||
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