diff --git a/Example.Backend/Program.cs b/Example.Backend/Program.cs index 668505e..52016a0 100644 --- a/Example.Backend/Program.cs +++ b/Example.Backend/Program.cs @@ -2,6 +2,7 @@ using System.Linq; using System.Net; using Example.Backend; +using Example.Shared; using mROA.Abstract; using mROA.Cbor; using mROA.Codegen; @@ -13,7 +14,6 @@ class Program { public static void Main(string[] args) { - new CoCodegenMethodRepository(); var builder = new FullMixBuilder(); // builder.UseJsonSerialisation(); builder.Modules.Add(new CborSerializationToolkit()); @@ -40,8 +40,11 @@ class Program repo.Inject(builder.Modules.OfType().First()); return repo; })); - builder.SetupMethodsRepository(new CoCodegenMethodRepository()); - + var methodRepo = new CollectableMethodRepository(); + methodRepo.AppendInvokers(new GeneratedInvokersCollection()); + builder.Modules.Add(methodRepo); + builder.Modules.Add(new GeneratedCallIndexProvider()); + builder.Modules.Add(new GeneratedCallIndexProvider()); builder.Modules.Add(new CancellationRepository()); builder.Build(); diff --git a/Example.Frontend/Example.Frontend.csproj b/Example.Frontend/Example.Frontend.csproj index 42db3a4..fdac1b1 100644 --- a/Example.Frontend/Example.Frontend.csproj +++ b/Example.Frontend/Example.Frontend.csproj @@ -10,11 +10,11 @@ - TRACE;JUST_LOAD + TRACE; - JUST_LOAD + diff --git a/Example.Frontend/Program.cs b/Example.Frontend/Program.cs index 8cab54c..3856ac5 100644 --- a/Example.Frontend/Program.cs +++ b/Example.Frontend/Program.cs @@ -14,6 +14,7 @@ using mROA.Implementation.Backend; using mROA.Implementation.Bootstrap; using mROA.Implementation.Frontend; + class Program { public static async Task Main(string[] args) @@ -32,7 +33,10 @@ class Program builder.Modules.Add(new StaticRepresentationModuleProducer()); builder.Modules.Add(new RequestExtractor()); builder.Modules.Add(new BasicExecutionModule()); - builder.Modules.Add(new CoCodegenMethodRepository()); + var methodRepo = new CollectableMethodRepository(); + methodRepo.AppendInvokers(new GeneratedInvokersCollection()); + builder.Modules.Add(methodRepo); + builder.Modules.Add(new GeneratedCallIndexProvider()); builder.UseCollectableContextRepository(); builder.Modules.Add(new CancellationRepository()); diff --git a/mROA.Codegen/IndexProvider.cstmpl b/mROA.Codegen/IndexProvider.cstmpl new file mode 100644 index 0000000..3c8d7d7 --- /dev/null +++ b/mROA.Codegen/IndexProvider.cstmpl @@ -0,0 +1,47 @@ +using System; +using System.Linq; +using mROA.Abstract; +using mROA.Implementation; +using System.Collections.Generic; + + +namespace +{ + public class GeneratedCallIndexProvider : ICallIndexProvider + { + public Dictionary> _activators = new () { + , + + }; + public Dictionary> Activators => _activators; + private IndexSpan _span = new () + { + ApiLevel = , + Identifier = "", + Length = , + Offset = 0, + }; + + public IndexSpan Span => _span; + + private Dictionary Indexes = new() + { + + + }; + + public void Inject(T dependency) + { + } + + public void SetupOffset(int offset) + { + _span.Offset = offset; + } + + public int[] GetIndices(Type type) + { + return Indexes[type].Select(i => i + _span.Offset).ToArray(); + } + } +} \ No newline at end of file diff --git a/mROA.Codegen/MethodRepo.cstmpl b/mROA.Codegen/MethodRepo.cstmpl index 3860e42..e231aef 100644 --- a/mROA.Codegen/MethodRepo.cstmpl +++ b/mROA.Codegen/MethodRepo.cstmpl @@ -4,13 +4,15 @@ using System.Reflection; using mROA.Abstract; using mROA.Implementation; using System; +using System.Collections; using System.Threading; namespace mROA.Codegen { - public class CoCodegenMethodRepository : IMethodRepository + public class GeneratedInvokersCollection : IReadOnlyList { - private readonly List _methods = new () { + private readonly List _invokers = new() + { , @@ -32,22 +34,21 @@ namespace mROA.Codegen ParameterTypes = new Type[] { }, SuitableType = typeof(), Invoking = (i, parameters, special) => , - } + } }; - public IMethodInvoker GetMethod(int id) + public IEnumerator GetEnumerator() { - if (id == -1) - return mROA.Implementation.MethodInvoker.Dispose; - - if (_methods.Count <= id) - return null; - - return _methods[id]; + return _invokers.GetEnumerator(); } - public void Inject(T dependency) + IEnumerator IEnumerable.GetEnumerator() { + return GetEnumerator(); } + + public int Count => _invokers.Count; + + public IMethodInvoker this[int index] => _invokers[index]; } } \ No newline at end of file diff --git a/mROA.Codegen/Proxy.cstmpl b/mROA.Codegen/Proxy.cstmpl index 6fb0d5c..b8371fa 100644 --- a/mROA.Codegen/Proxy.cstmpl +++ b/mROA.Codegen/Proxy.cstmpl @@ -10,8 +10,8 @@ namespace partial class : RemoteObjectBase, { - public (int id, IRepresentationModule representationModule, IEndPointContext context) - : base(id, representationModule, context) + public (int id, IRepresentationModule representationModule, IEndPointContext context, int[] callIndices) + : base(id, representationModule, context, callIndices) { } diff --git a/mROA.Codegen/RemoteTypeBinder.cstmpl b/mROA.Codegen/RemoteTypeBinder.cstmpl index f343fc2..56e6965 100644 --- a/mROA.Codegen/RemoteTypeBinder.cstmpl +++ b/mROA.Codegen/RemoteTypeBinder.cstmpl @@ -11,12 +11,9 @@ namespace mROA.Codegen public sealed class RemoteTypeBinder { static RemoteTypeBinder(){ - RemoteInstanceRepository.RemoteTypeFactories = new Dictionary> { - , - - }; InstanceRepository.EventBinders = new object[] { - + , + new EventBinder<> { diff --git a/mROA.Codegen/mROA.Codegen.csproj b/mROA.Codegen/mROA.Codegen.csproj index 2f199bd..3eb3357 100644 --- a/mROA.Codegen/mROA.Codegen.csproj +++ b/mROA.Codegen/mROA.Codegen.csproj @@ -43,4 +43,10 @@ + + + + + + diff --git a/mROA.Codegen/mROASourceGenerator.cs b/mROA.Codegen/mROASourceGenerator.cs index b644989..afb485e 100644 --- a/mROA.Codegen/mROASourceGenerator.cs +++ b/mROA.Codegen/mROASourceGenerator.cs @@ -30,6 +30,7 @@ namespace mROA.Codegen private static readonly Predicate ParameterFilterForType = i => i.Name is "CancellationToken" or "RequestContext"; + private TemplateDocument _indexerTemplate; private TemplateDocument _binderTemplate; private TemplateDocument _classTemplate; private TemplateDocument _classTemplateOriginal; @@ -37,66 +38,21 @@ namespace mROA.Codegen private TemplateDocument _interfaceTemplateOriginal; private TemplateDocument _methodInvokerOriginal; private TemplateDocument _methodRepoTemplate; + private int _currentInternalCallIndex = 0; - public void Initialize(GeneratorInitializationContext context) - { - try - { - - _methodRepoTemplate = TemplateReader.FromEmbeddedResource("MethodRepo.cstmpl"); - _methodInvokerOriginal = - ((InnerTemplateSection)_methodRepoTemplate["syncInvoker"]!).InnerTemplate; - _classTemplateOriginal = TemplateReader.FromEmbeddedResource("Proxy.cstmpl"); - _binderTemplate = TemplateReader.FromEmbeddedResource("RemoteTypeBinder.cstmpl"); - _interfaceTemplateOriginal = TemplateReader.FromEmbeddedResource("PartialInterface.cstmpl"); - } - catch (Exception e) - { - Console.WriteLine(e); - } - } - - // public void Execute(GeneratorExecutionContext context) - // { - // // return; - // try - // { - // var trees = context.Compilation.SyntaxTrees; - // - // var interfaces = new List(); - // foreach (var tree in trees) - // { - // var node = (CompilationUnitSyntax)tree.GetRoot(); - // - // foreach (var member in node.Members) - // if (member is InterfaceDeclarationSyntax ids) - // interfaces.Add(ids); - // else if (member is NamespaceDeclarationSyntax nds) - // foreach (var inside in nds.Members) - // - // if (inside is InterfaceDeclarationSyntax ids2) - // if (ContainsSoiAttribute(ids2.AttributeLists, context, ids2)) - // interfaces.Add(ids2); - // } - // - // GenerateCode(context, context.Compilation, interfaces.ToImmutableArray()); - // } - // catch (Exception) - // { - // Console.WriteLine("ERROR: Unable to load method repository"); - // } - // } private void GenerateCode(SourceProductionContext context, Compilation compilation, ImmutableArray classes) { var totalMethods = new List(); - - + + _indexerTemplate.AddDefine("namespace", compilation.AssemblyName!); var invokers = new List(); var declarations = classes.ToList(); + var apiLevel = 0; foreach (var classDeclarationSyntax in declarations) { + _currentInternalCallIndex = 0; var semanticModel = compilation.GetSemanticModel(classDeclarationSyntax.SyntaxTree); if (semanticModel.GetDeclaredSymbol(classDeclarationSyntax) is not INamedTypeSymbol classSymbol) @@ -121,6 +77,7 @@ namespace mROA.Codegen _classTemplate = (TemplateDocument)_classTemplateOriginal.Clone(); var propertiesAccessMethods = new List<(string, IMethodSymbol)>(); + int startInvokers = invokers.Count; foreach (var method in innerMethods) switch (method.MethodKind) { @@ -162,7 +119,8 @@ namespace mROA.Codegen } GenerateEventImplementation(classSymbol, invokers, context); - + var endInvokers = invokers.Count; + _indexerTemplate.Insert("indexSpan", $"{{ typeof({originalName}), new[] {{ {JoinWithComa(Enumerable.Range(startInvokers, endInvokers - startInvokers).Select(i => i.ToString()))} }} }},"); _classTemplate.AddDefine("className", className); _classTemplate.AddDefine("originalName", originalName); _classTemplate.AddDefine("namespaceName", namespaceName); @@ -174,23 +132,29 @@ namespace mROA.Codegen #if !DONT_ADD context.AddSource($"{className}.g.cs", SourceText.From(code, Encoding.UTF8)); #endif - _binderTemplate.Insert("remoteTypePair", - $"{{ typeof({classSymbol.ToUnityString()}), (i, r, c) => new {namespaceName}.{className}(i, r, c) }}"); + _indexerTemplate.Insert("remoteTypePair", + $"{{ typeof({classSymbol.ToUnityString()}), (id, r, c, indices) => new {namespaceName}.{className}(id, r, c, indices) }}"); } if (totalMethods.Count != 0) { var coCodegenRepoCode = _methodRepoTemplate.Compile(); + _indexerTemplate.AddDefine("level", apiLevel.ToString()); + _indexerTemplate.AddDefine("len", invokers.Count.ToString()); + + var providerCode = _indexerTemplate.Compile(); #if !DONT_ADD - context.AddSource("CoCodegenMethodRepository.g.cs", SourceText.From(coCodegenRepoCode, Encoding.UTF8)); + context.AddSource("GeneratedInvokersCollection.g.cs", SourceText.From(coCodegenRepoCode, Encoding.UTF8)); + context.AddSource("GeneratedIndexProvider.g.cs", SourceText.From(providerCode, Encoding.UTF8)); + #endif } - if (_binderTemplate["remoteTypePair+"] != null) + if (_indexerTemplate["remoteTypePair+"] != null) { - var fronendRepoCode = _binderTemplate.Compile(); + var frontendRepoCode = _binderTemplate.Compile(); #if !DONT_ADD - context.AddSource("RemoteTypeBinder.g.cs", SourceText.From(fronendRepoCode, Encoding.UTF8)); + context.AddSource("RemoteTypeBinder.g.cs", SourceText.From(frontendRepoCode, Encoding.UTF8)); #endif } } @@ -264,7 +228,6 @@ namespace mROA.Codegen private void GenerateDeclaredMethod(IMethodSymbol method, List invokers, INamedTypeSymbol baseInterace) { - var index = invokers.Count; var sb = new StringBuilder(); bool isParametrized; @@ -299,7 +262,6 @@ namespace mROA.Codegen : " ") + $"{method.ReturnType.ToUnityString()} {method.Name}({string.Join(", ", method.Parameters.Select(ToFullString))}){{"); - var isUntrusted = method.GetAttributes().Any(i => i.AttributeClass.Name == "UntrustedAttribute"); var prefix = isAsync ? "await " : ""; @@ -312,7 +274,7 @@ namespace mROA.Codegen if (isUntrusted) { - caller = $"CallUntrustedAsync({index}{parameterLink})"; + caller = $"CallUntrustedAsync(_callIndices[{_currentInternalCallIndex++}]{parameterLink})"; } else { @@ -323,10 +285,10 @@ namespace mROA.Codegen : string.Empty; caller = isVoid - ? $"CallAsync({index}{parameterLink}{tokenInsert})" + ? $"CallAsync(_callIndices[{_currentInternalCallIndex++}]{parameterLink}{tokenInsert})" : isAsync - ? $"GetResultAsync<{ExtractTaskType(method.ReturnType)}>({index}{parameterLink}{tokenInsert})" - : $"GetResultAsync<{ToFullString(method.ReturnType)}>({index}{parameterLink}{tokenInsert})"; + ? $"GetResultAsync<{ExtractTaskType(method.ReturnType)}>(_callIndices[{_currentInternalCallIndex++}]{parameterLink}{tokenInsert})" + : $"GetResultAsync<{ToFullString(method.ReturnType)}>(_callIndices[{_currentInternalCallIndex++}]{parameterLink}{tokenInsert})"; if (!isVoid) prefix = "return " + prefix; @@ -415,7 +377,7 @@ namespace mROA.Codegen var eventBinderTemplate = (TemplateDocument)((InnerTemplateSection)document["eventBinderTemplate"]!).InnerTemplate.Clone(); - var index = invokers.Count - 1; + var index = _currentInternalCallIndex - 1; var parameters = (eventSymbol.Type as INamedTypeSymbol)!.TypeArguments.ToList(); var parametersDeclaration = string.Join(", ", JoinWithComa(Enumerable.Range(0, parameters.Count).Select(i => "p" + i))); @@ -436,7 +398,7 @@ namespace mROA.Codegen eventBinderTemplate.AddDefine("type", baseType.ToUnityString()); eventBinderTemplate.AddDefine("eventName", eventSymbol.Name); eventBinderTemplate.AddDefine("parametersDeclaration", parametersDeclaration); - eventBinderTemplate.AddDefine("commandId", index.ToString()); + eventBinderTemplate.AddDefine("commandId", $"context.CallIndexProvider.GetIndices(typeof({baseType.ToUnityString()}))[{index}]"); eventBinderTemplate.AddDefine("transferParameters", transferParameters); var eventBinderCode = eventBinderTemplate.Compile(); document.Insert("eventBinder", eventBinderCode); @@ -498,7 +460,6 @@ namespace mROA.Codegen private void GeneratePropertyMethod(IMethodSymbol method, List<(string, IMethodSymbol)> propsCollection, List invokers, INamedTypeSymbol baseInterace) { - var index = invokers.Count; string frontend; string backend; if (method.MethodKind == MethodKind.PropertyGet) @@ -540,7 +501,7 @@ namespace mROA.Codegen } frontend = - $"get => GetResultAsync<{method.ReturnType.ToUnityString()}>({index}{parametersArray}).GetAwaiter().GetResult();"; + $"get => GetResultAsync<{method.ReturnType.ToUnityString()}>(_callIndices[{_currentInternalCallIndex++}]{parametersArray}).GetAwaiter().GetResult();"; } else { @@ -586,7 +547,7 @@ namespace mROA.Codegen backend = invokerTemplate.Compile(); } - frontend = $"set => CallAsync({index}, new System.Object[] {{ {parametersArray} }}).Wait();"; + frontend = $"set => CallAsync(_callIndices[{_currentInternalCallIndex++}], new System.Object[] {{ {parametersArray} }}).Wait();"; } propsCollection.Add((frontend, method)); @@ -649,7 +610,8 @@ namespace mROA.Codegen _classTemplateOriginal = TemplateReader.FromEmbeddedResource("Proxy.cstmpl"); _binderTemplate = TemplateReader.FromEmbeddedResource("RemoteTypeBinder.cstmpl"); _interfaceTemplateOriginal = TemplateReader.FromEmbeddedResource("PartialInterface.cstmpl"); - + _indexerTemplate = TemplateReader.FromEmbeddedResource("IndexProvider.cstmpl"); + var syntaxes = context.SyntaxProvider.CreateSyntaxProvider( (static (node, _) => node is InterfaceDeclarationSyntax), static (node, _) => ContainsSoiAttribute(node)).Where(i => i.usefull).Select((node, _) => node.node); diff --git a/mROA/Abstract/ICallIndexProvider.cs b/mROA/Abstract/ICallIndexProvider.cs index f4f6c7c..bef6018 100644 --- a/mROA/Abstract/ICallIndexProvider.cs +++ b/mROA/Abstract/ICallIndexProvider.cs @@ -1,11 +1,37 @@ using System; +using System.Collections; using System.Collections.Generic; +using mROA.Implementation; namespace mROA.Abstract { public interface ICallIndexProvider : IInjectableModule { - int[] GetIndecies(Type type); + Dictionary> Activators { get; } + void SetupOffset(int offset); + int[] GetIndices(Type type); } -} \ No newline at end of file + + // public class GeneratedInvokersCollection : IReadOnlyList + // { + // private readonly List _invokers = new() + // { + // + // }; + // + // public IEnumerator GetEnumerator() + // { + // return _invokers.GetEnumerator(); + // } + // + // IEnumerator IEnumerable.GetEnumerator() + // { + // return GetEnumerator(); + // } + // + // public int Count => _invokers.Count; + // + // public IMethodInvoker this[int index] => _invokers[index]; + // } +} \ No newline at end of file diff --git a/mROA/Abstract/IChannelInteractionModule.cs b/mROA/Abstract/IChannelInteractionModule.cs index db7a3b6..9b56492 100644 --- a/mROA/Abstract/IChannelInteractionModule.cs +++ b/mROA/Abstract/IChannelInteractionModule.cs @@ -8,6 +8,7 @@ namespace mROA.Abstract public interface IChannelInteractionModule : IInjectableModule, IDisposable { int ConnectionId { get; set; } + IEndPointContext Context { get; } Channel ReceiveChanel { get; } ChannelReader TrustedPostChanel { get; } ChannelReader UntrustedPostChanel { get; } diff --git a/mROA/Abstract/IEndPointContext.cs b/mROA/Abstract/IEndPointContext.cs index ca2a288..e66cd85 100644 --- a/mROA/Abstract/IEndPointContext.cs +++ b/mROA/Abstract/IEndPointContext.cs @@ -4,9 +4,9 @@ namespace mROA.Abstract { public interface IEndPointContext : IInjectableModule { - IInstanceRepository RealRepository { get; } - IInstanceRepository RemoteRepository { get; } - ICallIndexProvider CallIndexProvider { get; } + IInstanceRepository RealRepository { get; set; } + IInstanceRepository RemoteRepository { get; set; } + ICallIndexProvider CallIndexProvider { get; set; } int HostId { get; set; } int OwnerId { get; set; } } diff --git a/mROA/Abstract/IRepresentationModule.cs b/mROA/Abstract/IRepresentationModule.cs index 101b399..c75d64f 100644 --- a/mROA/Abstract/IRepresentationModule.cs +++ b/mROA/Abstract/IRepresentationModule.cs @@ -9,7 +9,7 @@ namespace mROA.Abstract public interface IRepresentationModule : IInjectableModule { int Id { get; } - + IEndPointContext Context { get; } Task<(object? Deserialized, EMessageType MessageType)> GetSingle(Predicate rule, IEndPointContext? context, CancellationToken token = default, params Func[] converter); diff --git a/mROA/Implementation/Backend/HubRequestExtractor.cs b/mROA/Implementation/Backend/HubRequestExtractor.cs index 7a51339..c561e40 100644 --- a/mROA/Implementation/Backend/HubRequestExtractor.cs +++ b/mROA/Implementation/Backend/HubRequestExtractor.cs @@ -55,10 +55,7 @@ namespace mROA.Implementation.Backend private IRequestExtractor CreateExtractor(IRepresentationModule interaction) { var extractor = new RequestExtractor(); - var context = new EndPointContext - { - HostId = 0, OwnerId = -interaction.Id - }; + var context = interaction.Context; extractor.Inject(interaction); if (_contextRepository is IContextRepositoryHub contextHub) context.RealRepository = contextHub.GetRepository(interaction.Id); diff --git a/mROA/Implementation/Backend/NetworkGatewayModule.cs b/mROA/Implementation/Backend/NetworkGatewayModule.cs index f4e9d3c..44a917d 100644 --- a/mROA/Implementation/Backend/NetworkGatewayModule.cs +++ b/mROA/Implementation/Backend/NetworkGatewayModule.cs @@ -16,6 +16,7 @@ namespace mROA.Implementation.Backend private IConnectionHub? _hub; private IContextualSerializationToolKit? _serialization; private Dictionary _extractorsCTS = new(); + private ICallIndexProvider _callIndexProvider; public NetworkGatewayModule(IPEndPoint endpoint, Type interactionModuleType, IInjectableModule[] injectableModules) @@ -49,6 +50,9 @@ namespace mROA.Implementation.Backend case IContextualSerializationToolKit serializationToolkit: _serialization = serializationToolkit; break; + case ICallIndexProvider callIndexProvider: + _callIndexProvider = callIndexProvider; + break; } } @@ -70,7 +74,7 @@ namespace mROA.Implementation.Backend //TODO сделать контекст var context = new EndPointContext(); - + context.CallIndexProvider = _callIndexProvider; var streamExtractor = new ChannelInteractionModule.StreamExtractor(client.GetStream(), _serialization, context); interaction.IsConnected = () => streamExtractor.IsConnected; @@ -87,6 +91,7 @@ namespace mROA.Implementation.Backend case EMessageType.ClientConnect: context.HostId = 0; context.OwnerId = -interaction.ConnectionId; + interaction.Inject(context); Task.Run(async () => await streamExtractor.LoopedReceive(cts.Token)); _ = streamExtractor.SendFromChannel(interaction.TrustedPostChanel, cts.Token); interaction.PostMessageAsync(new NetworkMessageHeader(_serialization!, diff --git a/mROA/Implementation/ChannelInteractionModule.cs b/mROA/Implementation/ChannelInteractionModule.cs index d8440c1..2e80252 100644 --- a/mROA/Implementation/ChannelInteractionModule.cs +++ b/mROA/Implementation/ChannelInteractionModule.cs @@ -46,6 +46,7 @@ namespace mROA.Implementation public int ConnectionId { get; set; } + public IEndPointContext Context => _context; public Channel ReceiveChanel { get; } public ChannelReader TrustedPostChanel => _outputTrustedChannel.Reader; diff --git a/mROA/Implementation/CollectableMethodRepository.cs b/mROA/Implementation/CollectableMethodRepository.cs new file mode 100644 index 0000000..b37213f --- /dev/null +++ b/mROA/Implementation/CollectableMethodRepository.cs @@ -0,0 +1,30 @@ +using System.Collections.Generic; +using mROA.Abstract; + +namespace mROA.Implementation +{ + public class CollectableMethodRepository : IMethodRepository + { + private List _methods = new(); + public void Inject(T dependency) + { + + } + + public void AppendInvokers(IEnumerable methodInvokers) + { + _methods.AddRange(methodInvokers); + } + + public IMethodInvoker GetMethod(int id) + { + if (id == -1) + return MethodInvoker.Dispose; + + if (_methods.Count <= id) + return null; + + return _methods[id]; + } + } +} \ No newline at end of file diff --git a/mROA/Implementation/EndPointContext.cs b/mROA/Implementation/EndPointContext.cs index b99de17..8f951f4 100644 --- a/mROA/Implementation/EndPointContext.cs +++ b/mROA/Implementation/EndPointContext.cs @@ -5,9 +5,9 @@ namespace mROA.Implementation { public class EndPointContext : IEndPointContext { - public IInstanceRepository RealRepository { get; set; } + public IInstanceRepository RealRepository { get; set; } public IInstanceRepository RemoteRepository { get; set; } - public ICallIndexProvider CallIndexProvider { get; } + public ICallIndexProvider CallIndexProvider { get; set; } public CallIndexConfig CallIndexConfig { get; set; } public int HostId { get; set; } diff --git a/mROA/Implementation/Frontend/NetworkFrontendBridge.cs b/mROA/Implementation/Frontend/NetworkFrontendBridge.cs index 8611418..59184b6 100644 --- a/mROA/Implementation/Frontend/NetworkFrontendBridge.cs +++ b/mROA/Implementation/Frontend/NetworkFrontendBridge.cs @@ -48,7 +48,7 @@ namespace mROA.Implementation.Frontend throw new NullReferenceException("Serialization toolkit is not initialized"); _tcpClient.Connect(_serverEndPoint); - + _tcpClient.NoDelay = true; PrepareExtractor(); _interactionModule.IsConnected = () => _currentExtractor.IsConnected; _interactionModule.OnDisconnected += _ => { Reconnect(); }; diff --git a/mROA/Implementation/RemoteInstanceRepository.cs b/mROA/Implementation/RemoteInstanceRepository.cs index 8d39993..a0a12b5 100644 --- a/mROA/Implementation/RemoteInstanceRepository.cs +++ b/mROA/Implementation/RemoteInstanceRepository.cs @@ -8,9 +8,7 @@ namespace mROA.Implementation public class RemoteInstanceRepository : IInstanceRepository { private List _producedProxys = new(); - - public static Dictionary> - RemoteTypeFactories = new(); + private ICallIndexProvider _callIndexProvider; private IRepresentationModuleProducer? _representationProducer; @@ -34,11 +32,11 @@ namespace mROA.Implementation if (_representationProducer == null) throw new NullReferenceException("representation producer is not initialized"); - if (!RemoteTypeFactories.TryGetValue(typeof(T), out var remoteType)) throw new NotSupportedException(); + if (!_callIndexProvider.Activators.TryGetValue(typeof(T), out var remoteType)) throw new NotSupportedException(); var representationModule = _representationProducer.Produce(context.OwnerId); var remote = remoteType(id.ContextId, - representationModule, context); + representationModule, context, _callIndexProvider.GetIndices(typeof(T))); _producedProxys.Add(remote!); @@ -58,7 +56,7 @@ namespace mROA.Implementation var representationModule = _representationProducer.Produce(context.OwnerId); - var instance = RemoteTypeFactories[type](-1, representationModule, context)!; + var instance = _callIndexProvider.Activators[type](-1, representationModule, context, _callIndexProvider.GetIndices(type))!; var remoteObjectBase = instance; @@ -79,8 +77,15 @@ namespace mROA.Implementation public void Inject(T dependency) { - if (dependency is IRepresentationModuleProducer serialisationModule) - _representationProducer = serialisationModule; + switch (dependency) + { + case IRepresentationModuleProducer serialisationModule: + _representationProducer = serialisationModule; + break; + case ICallIndexProvider callIndexProvider: + _callIndexProvider = callIndexProvider; + break; + } } } } \ No newline at end of file diff --git a/mROA/Implementation/RemoteObjectBase.cs b/mROA/Implementation/RemoteObjectBase.cs index 3410e97..58ad1e5 100644 --- a/mROA/Implementation/RemoteObjectBase.cs +++ b/mROA/Implementation/RemoteObjectBase.cs @@ -32,12 +32,13 @@ namespace mROA.Implementation private readonly ComplexObjectIdentifier _identifier; private readonly IRepresentationModule _representationModule; - - protected RemoteObjectBase(int id, IRepresentationModule representationModule, IEndPointContext context) + protected readonly int[] _callIndices; + protected RemoteObjectBase(int id, IRepresentationModule representationModule, IEndPointContext context, int[] indices) { _identifier = new ComplexObjectIdentifier { ContextId = id, OwnerId = representationModule.Id }; _representationModule = representationModule; _context = context; + _callIndices = indices; } public int Id => _identifier.ContextId; diff --git a/mROA/Implementation/RepresentationModule.cs b/mROA/Implementation/RepresentationModule.cs index d406d59..ce38bf9 100644 --- a/mROA/Implementation/RepresentationModule.cs +++ b/mROA/Implementation/RepresentationModule.cs @@ -31,6 +31,8 @@ namespace mROA.Implementation public int Id => (_interaction ?? throw new NullReferenceException("Interaction is not initialized")) .ConnectionId; + public IEndPointContext Context => _interaction.Context; + public async Task<(object? Deserialized, EMessageType MessageType)> GetSingle( Predicate rule, IEndPointContext? context, CancellationToken token = default, params Func[] converter)