diff --git a/mROA.Test/UnitTest1.cs b/mROA.Test/UnitTest1.cs index a707535..3d8bac4 100644 --- a/mROA.Test/UnitTest1.cs +++ b/mROA.Test/UnitTest1.cs @@ -29,7 +29,7 @@ public class Tests _contextRepository = repo2; _serialisationModule = new JsonSerialisationModule(_interactionModule, _methodRepository); - _executeModule = new PrepairedExecutionModule(_methodRepository, _serialisationModule, _contextRepository); + _executeModule = new LaunchReadyExecutionModule(_methodRepository, _serialisationModule, _contextRepository); TransmissionConfig.DefaultContextRepository = _contextRepository; } diff --git a/mROA/Abstract/ICommandExecution.cs b/mROA/Abstract/ICommandExecution.cs index 04641f4..23262cc 100644 --- a/mROA/Abstract/ICommandExecution.cs +++ b/mROA/Abstract/ICommandExecution.cs @@ -2,7 +2,7 @@ namespace mROA; public interface ICommandExecution { - Guid ExecutionId { get; init; } + Guid CallRequestId { get; init; } int ClientId { get; set; } int CommandId { get; set; } } \ No newline at end of file diff --git a/mROA/Abstract/ISerialisationModule.cs b/mROA/Abstract/ISerialisationModule.cs index f3e5358..a7d0934 100644 --- a/mROA/Abstract/ISerialisationModule.cs +++ b/mROA/Abstract/ISerialisationModule.cs @@ -7,4 +7,10 @@ public interface ISerialisationModule void HandleIncomingRequest(int clientId, string command); void PostResponse(ICommandExecution call); void SetExecuteModule(IExecuteModule executeModule); + public interface IFrontendSerialisationModule + { + void HandlePostedResponse(string response); + void PostCallRequest(ICallRequest callRequest); + Task GetCommandExecutionResult(Guid callRequestId, CancellationToken cancellationToken); + } } \ No newline at end of file diff --git a/mROA/Implementation/CallRequest.cs b/mROA/Implementation/CallRequest.cs index 27a5bdb..15c3305 100644 --- a/mROA/Implementation/CallRequest.cs +++ b/mROA/Implementation/CallRequest.cs @@ -2,6 +2,7 @@ public interface ICallRequest { + Guid CallRequestId { get; } int CommandId { get; } int ClientId { get; } int ObjectId { get; } @@ -10,23 +11,25 @@ public interface ICallRequest public class JsonCallRequest : ICallRequest { + public Guid CallRequestId { get; } = Guid.NewGuid(); public int CommandId { get; set; } public int ClientId { get; set; } public int ObjectId { get; set; } = -1; - public object Parameter { get; set; } -} -public struct HardCallRequest : ICallRequest -{ - public int CommandId => Command; - public int ClientId => Client; - public int ObjectId => Object; - - public int Command; - public int Client; - public int Object; - public object Parameter { get; set; } - + public object? Parameter { get; set; } } +// public struct HardCallRequest : ICallRequest +// { +// public Guid CallRequestId { get; } = Guid.NewGuid(); +// public int CommandId => Command; +// public int ClientId => Client; +// public int ObjectId => Object; +// +// public int Command; +// public int Client; +// public int Object; +// public object Parameter { get; set; } +// +// } // public class CallRequest : SingletonCallRequest // { // public override int RequestTypeId => (int)RequestType.NonParametrized; diff --git a/mROA/Implementation/ContextRepository.cs b/mROA/Implementation/ContextRepository.cs index 9b51f07..e60d5f3 100644 --- a/mROA/Implementation/ContextRepository.cs +++ b/mROA/Implementation/ContextRepository.cs @@ -8,7 +8,7 @@ public class ContextRepository : IContextRepository private FrozenDictionary _singletons; private object[] _storage; - private Task? _lastIndexFinder = Task.FromResult(0); + private Task _lastIndexFinder = Task.FromResult(0); const int StartupSize = 1024; const int GrowSize = 128; @@ -29,7 +29,7 @@ public class ContextRepository : IContextRepository public int ResisterObject(object o) { - if (_lastIndexFinder is not null) + if (!_lastIndexFinder.IsCompleted) _lastIndexFinder.Wait(); _storage[_lastIndexFinder.Result] = o; @@ -48,12 +48,12 @@ public class ContextRepository : IContextRepository public object GetObject(int id) { - return _storage.Length == -1 || _storage.Length <= id ? null : _storage[id]; + return id == -1 || _storage.Length <= id ? null : _storage[id]; } public object GetSingleObject(Type type) { - return _singletons.TryGetValue(type.GetHashCode(), out var value) ? value : null; + return _singletons.GetValueOrDefault(type.GetHashCode()); } public int GetObjectIndex(object o) diff --git a/mROA/Implementation/FinalCommandExecution.cs b/mROA/Implementation/FinalCommandExecution.cs index d6fd1b7..028e287 100644 --- a/mROA/Implementation/FinalCommandExecution.cs +++ b/mROA/Implementation/FinalCommandExecution.cs @@ -1,16 +1,20 @@ -namespace mROA.Implementation; +using System.Text.Json.Serialization; + +namespace mROA.Implementation; public class FinalCommandExecution : ICommandExecution { - public Guid ExecutionId { get; init; } = Guid.NewGuid(); + public Guid CallRequestId { get; init; } + [JsonIgnore] public int ClientId { get; set; } + [JsonIgnore] public int CommandId { get; set; } public object? Result { get; set; } } public class ExeptionCommandExecution : ICommandExecution { - public Guid ExecutionId { get; init; } = Guid.NewGuid(); + public Guid CallRequestId { get; init; } public int ClientId { get; set; } public int CommandId { get; set; } public string Reason { get; set; } @@ -18,8 +22,10 @@ public class ExeptionCommandExecution : ICommandExecution public class AsyncCommandExecution : ICommandExecution { - public Guid ExecutionId { get; init; } = Guid.NewGuid(); + public Guid CallRequestId { get; init; } + [JsonIgnore] public int ClientId { get; set; } + [JsonIgnore] public int CommandId { get; set; } public void Cancel() diff --git a/mROA/Implementation/JsonFrontendSerialisationModule.cs b/mROA/Implementation/JsonFrontendSerialisationModule.cs new file mode 100644 index 0000000..a8f7a10 --- /dev/null +++ b/mROA/Implementation/JsonFrontendSerialisationModule.cs @@ -0,0 +1,22 @@ +using System.Text.Json; + +namespace mROA.Implementation; + +public class JsonFrontendSerialisationModule : ISerialisationModule.IFrontendSerialisationModule +{ + public void HandlePostedResponse(string response) + { + + } + + + public void PostCallRequest(ICallRequest callRequest) + { + + } + + public async Task GetCommandExecutionResult(Guid callRequestId, CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } +} \ No newline at end of file diff --git a/mROA/Implementation/PrepairedExecutionModule.cs b/mROA/Implementation/LaunchReadyExecutionModule.cs similarity index 61% rename from mROA/Implementation/PrepairedExecutionModule.cs rename to mROA/Implementation/LaunchReadyExecutionModule.cs index bd1f8cb..5ec3b29 100644 --- a/mROA/Implementation/PrepairedExecutionModule.cs +++ b/mROA/Implementation/LaunchReadyExecutionModule.cs @@ -2,14 +2,13 @@ namespace mROA.Implementation; -public class PrepairedExecutionModule : IExecuteModule +public class LaunchReadyExecutionModule : IExecuteModule { private readonly IMethodRepository _methodRepo; private readonly ISerialisationModule _serialisationModule; private readonly IContextRepository _contextRepo; - private readonly MethodInfo _resultExtractionMethod; - public PrepairedExecutionModule(IMethodRepository methodRepo, + public LaunchReadyExecutionModule(IMethodRepository methodRepo, ISerialisationModule serialisationModule, IContextRepository contextRepo) { @@ -27,80 +26,70 @@ public class PrepairedExecutionModule : IExecuteModule var context = command.ObjectId != -1 ? _contextRepo.GetObject(command.ObjectId) - : _contextRepo.GetSingleObject(currentCommand.DeclaringType); + : _contextRepo.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 == typeof(Task)) return ExecuteAsync(currentCommand, context, parameter, command); - + return Execute(currentCommand, context, parameter, command); } - private ICommandExecution Execute(MethodInfo currentCommand, object context, object parameter, ICallRequest request) + private static FinalCommandExecution Execute(MethodInfo currentCommand, object context, object? parameter, + ICallRequest command) { var finalResult = currentCommand.Invoke(context, parameter is null ? [] : [parameter]); return new FinalCommandExecution - { CommandId = request.CommandId, Result = finalResult, ClientId = request.ClientId }; + { + CommandId = command.CommandId, Result = finalResult, ClientId = command.ClientId, + CallRequestId = command.CallRequestId + }; } - private ICommandExecution ExecuteAsync(MethodInfo currentCommand, object context, object parameter, + private AsyncCommandExecution ExecuteAsync(MethodInfo currentCommand, object context, object? parameter, ICallRequest command) { var tokenSource = new CancellationTokenSource(); var token = tokenSource.Token; - var result = currentCommand.Invoke(context, parameter is null ? [token] : [parameter, token]) as Task; + var result = (Task)currentCommand.Invoke(context, parameter is null ? [token] : [parameter, token])!; var exec = new AsyncCommandExecution(tokenSource) - { CommandId = command.CommandId, ClientId = command.ClientId }; + { CommandId = command.CommandId, ClientId = command.ClientId, CallRequestId = command.CallRequestId }; - result.ContinueWith(_ => - { - //_serialisationModule.PostResponse(new FinalCommandExecution - //{ - // ExecutionId = exec.ExecutionId, Result = null, CommandId = command.CommandId, - // ClientId = command.ClientId - //}); - PostFinalizedCallback(exec, null); - - }, token); + result.ContinueWith(_ => { PostFinalizedCallback(exec, null); }, token); return exec; } - private ICommandExecution TypedExecuteAsync(MethodInfo currentCommand, object context, object parameter, + private AsyncCommandExecution TypedExecuteAsync(MethodInfo currentCommand, object context, object? parameter, ICallRequest command) { var tokenSource = new CancellationTokenSource(); var token = tokenSource.Token; var result = - currentCommand.Invoke(context, parameter is null ? [token] : [parameter, token]) as Task; + (Task)currentCommand.Invoke(context, parameter is null ? [token] : [parameter, token])!; var exec = new AsyncCommandExecution(tokenSource) - { CommandId = command.CommandId, ClientId = command.ClientId }; + { CommandId = command.CommandId, ClientId = command.ClientId, CallRequestId = command.CallRequestId }; result.ContinueWith(task => { - var finalResult = task.GetType().GetProperty("Result").GetValue(task); - //_serialisationModule.PostResponse(new FinalCommandExecution - //{ - // ExecutionId = exec.ExecutionId, Result = result, CommandId = command.CommandId, - // ClientId = command.ClientId - //}); + var finalResult = task.GetType().GetProperty("Result")?.GetValue(task); PostFinalizedCallback(exec, finalResult); }, token); return exec; } - private void PostFinalizedCallback(ICommandExecution request, object result) + private void PostFinalizedCallback(AsyncCommandExecution request, object? result) { _serialisationModule.PostResponse(new FinalCommandExecution { - ExecutionId = request.ExecutionId, + CallRequestId = request.CallRequestId, Result = result, CommandId = request.CommandId, ClientId = request.ClientId