Just events not works

This commit is contained in:
2025-07-03 17:37:25 +03:00
parent aa3606401b
commit 9ec62536fe
22 changed files with 206 additions and 118 deletions
+6 -3
View File
@@ -2,6 +2,7 @@
using System.Linq; using System.Linq;
using System.Net; using System.Net;
using Example.Backend; using Example.Backend;
using Example.Shared;
using mROA.Abstract; using mROA.Abstract;
using mROA.Cbor; using mROA.Cbor;
using mROA.Codegen; using mROA.Codegen;
@@ -13,7 +14,6 @@ class Program
{ {
public static void Main(string[] args) public static void Main(string[] args)
{ {
new CoCodegenMethodRepository();
var builder = new FullMixBuilder(); var builder = new FullMixBuilder();
// builder.UseJsonSerialisation(); // builder.UseJsonSerialisation();
builder.Modules.Add(new CborSerializationToolkit()); builder.Modules.Add(new CborSerializationToolkit());
@@ -40,8 +40,11 @@ class Program
repo.Inject(builder.Modules.OfType<CreativeRepresentationModuleProducer>().First()); repo.Inject(builder.Modules.OfType<CreativeRepresentationModuleProducer>().First());
return repo; 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.Modules.Add(new CancellationRepository());
builder.Build(); builder.Build();
+2 -2
View File
@@ -10,11 +10,11 @@
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' "> <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<DefineConstants>TRACE;JUST_LOAD</DefineConstants> <DefineConstants>TRACE;</DefineConstants>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' "> <PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<DefineConstants>JUST_LOAD</DefineConstants> <DefineConstants></DefineConstants>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
+5 -1
View File
@@ -14,6 +14,7 @@ using mROA.Implementation.Backend;
using mROA.Implementation.Bootstrap; using mROA.Implementation.Bootstrap;
using mROA.Implementation.Frontend; using mROA.Implementation.Frontend;
class Program class Program
{ {
public static async Task Main(string[] args) public static async Task Main(string[] args)
@@ -32,7 +33,10 @@ class Program
builder.Modules.Add(new StaticRepresentationModuleProducer()); builder.Modules.Add(new StaticRepresentationModuleProducer());
builder.Modules.Add(new RequestExtractor()); builder.Modules.Add(new RequestExtractor());
builder.Modules.Add(new BasicExecutionModule()); 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.UseCollectableContextRepository();
builder.Modules.Add(new CancellationRepository()); builder.Modules.Add(new CancellationRepository());
+47
View File
@@ -0,0 +1,47 @@
using System;
using System.Linq;
using mROA.Abstract;
using mROA.Implementation;
using System.Collections.Generic;
namespace <!L namespace>
{
public class GeneratedCallIndexProvider : ICallIndexProvider
{
public Dictionary<Type, Func<int, IRepresentationModule, IEndPointContext, int[], RemoteObjectBase>> _activators = new () {
<!I remoteTypePair r sep typesSep><!D typesSep>,
<!D>
};
public Dictionary<Type, Func<int, IRepresentationModule, IEndPointContext, int[], RemoteObjectBase>> Activators => _activators;
private IndexSpan _span = new ()
{
ApiLevel = <!L level>,
Identifier = "<!L namespace>",
Length = <!L len>,
Offset = 0,
};
public IndexSpan Span => _span;
private Dictionary<Type, int[]> Indexes = new()
{
<!I indexSpan r sep nl><!D nl>
<!D>
};
public void Inject<T>(T dependency)
{
}
public void SetupOffset(int offset)
{
_span.Offset = offset;
}
public int[] GetIndices(Type type)
{
return Indexes[type].Select(i => i + _span.Offset).ToArray();
}
}
}
+12 -11
View File
@@ -4,13 +4,15 @@ using System.Reflection;
using mROA.Abstract; using mROA.Abstract;
using mROA.Implementation; using mROA.Implementation;
using System; using System;
using System.Collections;
using System.Threading; using System.Threading;
namespace mROA.Codegen namespace mROA.Codegen
{ {
public class CoCodegenMethodRepository : IMethodRepository public class GeneratedInvokersCollection : IReadOnlyList<IMethodInvoker>
{ {
private readonly List<IMethodInvoker> _methods = new () { private readonly List<IMethodInvoker> _invokers = new()
{
<!I invoker r sep invokerSep><!D invokerSep>, <!I invoker r sep invokerSep><!D invokerSep>,
<!D> <!D>
<!T asyncInvoker> <!T asyncInvoker>
@@ -35,19 +37,18 @@ namespace mROA.Codegen
}<!T> }<!T>
}; };
public IMethodInvoker GetMethod(int id) public IEnumerator<IMethodInvoker> GetEnumerator()
{ {
if (id == -1) return _invokers.GetEnumerator();
return mROA.Implementation.MethodInvoker.Dispose;
if (_methods.Count <= id)
return null;
return _methods[id];
} }
public void Inject<T>(T dependency) IEnumerator IEnumerable.GetEnumerator()
{ {
return GetEnumerator();
} }
public int Count => _invokers.Count;
public IMethodInvoker this[int index] => _invokers[index];
} }
} }
+2 -2
View File
@@ -10,8 +10,8 @@ namespace <!L namespaceName>
partial class <!L className> partial class <!L className>
: RemoteObjectBase, <!L originalName> : RemoteObjectBase, <!L originalName>
{ {
public <!L className>(int id, IRepresentationModule representationModule, IEndPointContext context) public <!L className>(int id, IRepresentationModule representationModule, IEndPointContext context, int[] callIndices)
: base(id, representationModule, context) : base(id, representationModule, context, callIndices)
{ {
} }
+2 -5
View File
@@ -11,12 +11,9 @@ namespace mROA.Codegen
public sealed class RemoteTypeBinder public sealed class RemoteTypeBinder
{ {
static RemoteTypeBinder(){ static RemoteTypeBinder(){
RemoteInstanceRepository.RemoteTypeFactories = new Dictionary<Type, Func<int, IRepresentationModule, IEndPointContext, RemoteObjectBase>> {
<!I remoteTypePair r sep typesSep><!D typesSep>,
<!D>
};
InstanceRepository.EventBinders = new object[] { InstanceRepository.EventBinders = new object[] {
<!I eventBinder r sep typesSep> <!I eventBinder r sep typesSep><!D typesSep>,
<!D>
<!T objectBinderTemplate> <!T objectBinderTemplate>
new EventBinder<<!L type>> new EventBinder<<!L type>>
{ {
+6
View File
@@ -43,4 +43,10 @@
</ItemGroup> </ItemGroup>
<ItemGroup>
<None Remove="IndexProvider.cstmpl" />
<EmbeddedResource Include="IndexProvider.cstmpl" />
</ItemGroup>
</Project> </Project>
+29 -67
View File
@@ -30,6 +30,7 @@ namespace mROA.Codegen
private static readonly Predicate<ITypeSymbol> ParameterFilterForType = private static readonly Predicate<ITypeSymbol> ParameterFilterForType =
i => i.Name is "CancellationToken" or "RequestContext"; i => i.Name is "CancellationToken" or "RequestContext";
private TemplateDocument _indexerTemplate;
private TemplateDocument _binderTemplate; private TemplateDocument _binderTemplate;
private TemplateDocument _classTemplate; private TemplateDocument _classTemplate;
private TemplateDocument _classTemplateOriginal; private TemplateDocument _classTemplateOriginal;
@@ -37,66 +38,21 @@ namespace mROA.Codegen
private TemplateDocument _interfaceTemplateOriginal; private TemplateDocument _interfaceTemplateOriginal;
private TemplateDocument _methodInvokerOriginal; private TemplateDocument _methodInvokerOriginal;
private TemplateDocument _methodRepoTemplate; 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<InterfaceDeclarationSyntax>();
// 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, private void GenerateCode(SourceProductionContext context, Compilation compilation,
ImmutableArray<InterfaceDeclarationSyntax> classes) ImmutableArray<InterfaceDeclarationSyntax> classes)
{ {
var totalMethods = new List<IMethodSymbol>(); var totalMethods = new List<IMethodSymbol>();
_indexerTemplate.AddDefine("namespace", compilation.AssemblyName!);
var invokers = new List<string>(); var invokers = new List<string>();
var declarations = classes.ToList(); var declarations = classes.ToList();
var apiLevel = 0;
foreach (var classDeclarationSyntax in declarations) foreach (var classDeclarationSyntax in declarations)
{ {
_currentInternalCallIndex = 0;
var semanticModel = compilation.GetSemanticModel(classDeclarationSyntax.SyntaxTree); var semanticModel = compilation.GetSemanticModel(classDeclarationSyntax.SyntaxTree);
if (semanticModel.GetDeclaredSymbol(classDeclarationSyntax) is not INamedTypeSymbol classSymbol) if (semanticModel.GetDeclaredSymbol(classDeclarationSyntax) is not INamedTypeSymbol classSymbol)
@@ -121,6 +77,7 @@ namespace mROA.Codegen
_classTemplate = (TemplateDocument)_classTemplateOriginal.Clone(); _classTemplate = (TemplateDocument)_classTemplateOriginal.Clone();
var propertiesAccessMethods = new List<(string, IMethodSymbol)>(); var propertiesAccessMethods = new List<(string, IMethodSymbol)>();
int startInvokers = invokers.Count;
foreach (var method in innerMethods) foreach (var method in innerMethods)
switch (method.MethodKind) switch (method.MethodKind)
{ {
@@ -162,7 +119,8 @@ namespace mROA.Codegen
} }
GenerateEventImplementation(classSymbol, invokers, context); 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("className", className);
_classTemplate.AddDefine("originalName", originalName); _classTemplate.AddDefine("originalName", originalName);
_classTemplate.AddDefine("namespaceName", namespaceName); _classTemplate.AddDefine("namespaceName", namespaceName);
@@ -174,23 +132,29 @@ namespace mROA.Codegen
#if !DONT_ADD #if !DONT_ADD
context.AddSource($"{className}.g.cs", SourceText.From(code, Encoding.UTF8)); context.AddSource($"{className}.g.cs", SourceText.From(code, Encoding.UTF8));
#endif #endif
_binderTemplate.Insert("remoteTypePair", _indexerTemplate.Insert("remoteTypePair",
$"{{ typeof({classSymbol.ToUnityString()}), (i, r, c) => new {namespaceName}.{className}(i, r, c) }}"); $"{{ typeof({classSymbol.ToUnityString()}), (id, r, c, indices) => new {namespaceName}.{className}(id, r, c, indices) }}");
} }
if (totalMethods.Count != 0) if (totalMethods.Count != 0)
{ {
var coCodegenRepoCode = _methodRepoTemplate.Compile(); var coCodegenRepoCode = _methodRepoTemplate.Compile();
_indexerTemplate.AddDefine("level", apiLevel.ToString());
_indexerTemplate.AddDefine("len", invokers.Count.ToString());
var providerCode = _indexerTemplate.Compile();
#if !DONT_ADD #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 #endif
} }
if (_binderTemplate["remoteTypePair+"] != null) if (_indexerTemplate["remoteTypePair+"] != null)
{ {
var fronendRepoCode = _binderTemplate.Compile(); var frontendRepoCode = _binderTemplate.Compile();
#if !DONT_ADD #if !DONT_ADD
context.AddSource("RemoteTypeBinder.g.cs", SourceText.From(fronendRepoCode, Encoding.UTF8)); context.AddSource("RemoteTypeBinder.g.cs", SourceText.From(frontendRepoCode, Encoding.UTF8));
#endif #endif
} }
} }
@@ -264,7 +228,6 @@ namespace mROA.Codegen
private void GenerateDeclaredMethod(IMethodSymbol method, List<string> invokers, private void GenerateDeclaredMethod(IMethodSymbol method, List<string> invokers,
INamedTypeSymbol baseInterace) INamedTypeSymbol baseInterace)
{ {
var index = invokers.Count;
var sb = new StringBuilder(); var sb = new StringBuilder();
bool isParametrized; bool isParametrized;
@@ -299,7 +262,6 @@ namespace mROA.Codegen
: " ") + : " ") +
$"{method.ReturnType.ToUnityString()} {method.Name}({string.Join(", ", method.Parameters.Select(ToFullString))}){{"); $"{method.ReturnType.ToUnityString()} {method.Name}({string.Join(", ", method.Parameters.Select(ToFullString))}){{");
var isUntrusted = method.GetAttributes().Any(i => i.AttributeClass.Name == "UntrustedAttribute"); var isUntrusted = method.GetAttributes().Any(i => i.AttributeClass.Name == "UntrustedAttribute");
var prefix = isAsync ? "await " : ""; var prefix = isAsync ? "await " : "";
@@ -312,7 +274,7 @@ namespace mROA.Codegen
if (isUntrusted) if (isUntrusted)
{ {
caller = $"CallUntrustedAsync({index}{parameterLink})"; caller = $"CallUntrustedAsync(_callIndices[{_currentInternalCallIndex++}]{parameterLink})";
} }
else else
{ {
@@ -323,10 +285,10 @@ namespace mROA.Codegen
: string.Empty; : string.Empty;
caller = isVoid caller = isVoid
? $"CallAsync({index}{parameterLink}{tokenInsert})" ? $"CallAsync(_callIndices[{_currentInternalCallIndex++}]{parameterLink}{tokenInsert})"
: isAsync : isAsync
? $"GetResultAsync<{ExtractTaskType(method.ReturnType)}>({index}{parameterLink}{tokenInsert})" ? $"GetResultAsync<{ExtractTaskType(method.ReturnType)}>(_callIndices[{_currentInternalCallIndex++}]{parameterLink}{tokenInsert})"
: $"GetResultAsync<{ToFullString(method.ReturnType)}>({index}{parameterLink}{tokenInsert})"; : $"GetResultAsync<{ToFullString(method.ReturnType)}>(_callIndices[{_currentInternalCallIndex++}]{parameterLink}{tokenInsert})";
if (!isVoid) if (!isVoid)
prefix = "return " + prefix; prefix = "return " + prefix;
@@ -415,7 +377,7 @@ namespace mROA.Codegen
var eventBinderTemplate = var eventBinderTemplate =
(TemplateDocument)((InnerTemplateSection)document["eventBinderTemplate"]!).InnerTemplate.Clone(); (TemplateDocument)((InnerTemplateSection)document["eventBinderTemplate"]!).InnerTemplate.Clone();
var index = invokers.Count - 1; var index = _currentInternalCallIndex - 1;
var parameters = (eventSymbol.Type as INamedTypeSymbol)!.TypeArguments.ToList(); var parameters = (eventSymbol.Type as INamedTypeSymbol)!.TypeArguments.ToList();
var parametersDeclaration = string.Join(", ", var parametersDeclaration = string.Join(", ",
JoinWithComa(Enumerable.Range(0, parameters.Count).Select(i => "p" + i))); JoinWithComa(Enumerable.Range(0, parameters.Count).Select(i => "p" + i)));
@@ -436,7 +398,7 @@ namespace mROA.Codegen
eventBinderTemplate.AddDefine("type", baseType.ToUnityString()); eventBinderTemplate.AddDefine("type", baseType.ToUnityString());
eventBinderTemplate.AddDefine("eventName", eventSymbol.Name); eventBinderTemplate.AddDefine("eventName", eventSymbol.Name);
eventBinderTemplate.AddDefine("parametersDeclaration", parametersDeclaration); eventBinderTemplate.AddDefine("parametersDeclaration", parametersDeclaration);
eventBinderTemplate.AddDefine("commandId", index.ToString()); eventBinderTemplate.AddDefine("commandId", $"context.CallIndexProvider.GetIndices(typeof({baseType.ToUnityString()}))[{index}]");
eventBinderTemplate.AddDefine("transferParameters", transferParameters); eventBinderTemplate.AddDefine("transferParameters", transferParameters);
var eventBinderCode = eventBinderTemplate.Compile(); var eventBinderCode = eventBinderTemplate.Compile();
document.Insert("eventBinder", eventBinderCode); document.Insert("eventBinder", eventBinderCode);
@@ -498,7 +460,6 @@ namespace mROA.Codegen
private void GeneratePropertyMethod(IMethodSymbol method, private void GeneratePropertyMethod(IMethodSymbol method,
List<(string, IMethodSymbol)> propsCollection, List<string> invokers, INamedTypeSymbol baseInterace) List<(string, IMethodSymbol)> propsCollection, List<string> invokers, INamedTypeSymbol baseInterace)
{ {
var index = invokers.Count;
string frontend; string frontend;
string backend; string backend;
if (method.MethodKind == MethodKind.PropertyGet) if (method.MethodKind == MethodKind.PropertyGet)
@@ -540,7 +501,7 @@ namespace mROA.Codegen
} }
frontend = frontend =
$"get => GetResultAsync<{method.ReturnType.ToUnityString()}>({index}{parametersArray}).GetAwaiter().GetResult();"; $"get => GetResultAsync<{method.ReturnType.ToUnityString()}>(_callIndices[{_currentInternalCallIndex++}]{parametersArray}).GetAwaiter().GetResult();";
} }
else else
{ {
@@ -586,7 +547,7 @@ namespace mROA.Codegen
backend = invokerTemplate.Compile(); 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)); propsCollection.Add((frontend, method));
@@ -649,6 +610,7 @@ namespace mROA.Codegen
_classTemplateOriginal = TemplateReader.FromEmbeddedResource("Proxy.cstmpl"); _classTemplateOriginal = TemplateReader.FromEmbeddedResource("Proxy.cstmpl");
_binderTemplate = TemplateReader.FromEmbeddedResource("RemoteTypeBinder.cstmpl"); _binderTemplate = TemplateReader.FromEmbeddedResource("RemoteTypeBinder.cstmpl");
_interfaceTemplateOriginal = TemplateReader.FromEmbeddedResource("PartialInterface.cstmpl"); _interfaceTemplateOriginal = TemplateReader.FromEmbeddedResource("PartialInterface.cstmpl");
_indexerTemplate = TemplateReader.FromEmbeddedResource("IndexProvider.cstmpl");
var syntaxes = context.SyntaxProvider.CreateSyntaxProvider( var syntaxes = context.SyntaxProvider.CreateSyntaxProvider(
(static (node, _) => node is InterfaceDeclarationSyntax), static (node, _) => ContainsSoiAttribute(node)).Where(i => i.usefull).Select((node, _) => node.node); (static (node, _) => node is InterfaceDeclarationSyntax), static (node, _) => ContainsSoiAttribute(node)).Where(i => i.usefull).Select((node, _) => node.node);
+27 -1
View File
@@ -1,11 +1,37 @@
using System; using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using mROA.Implementation;
namespace mROA.Abstract namespace mROA.Abstract
{ {
public interface ICallIndexProvider : IInjectableModule public interface ICallIndexProvider : IInjectableModule
{ {
int[] GetIndecies(Type type); Dictionary<Type, Func<int, IRepresentationModule, IEndPointContext, int[], RemoteObjectBase>> Activators { get; }
void SetupOffset(int offset);
int[] GetIndices(Type type);
} }
// public class GeneratedInvokersCollection : IReadOnlyList<IMethodInvoker>
// {
// private readonly List<IMethodInvoker> _invokers = new()
// {
//
// };
//
// public IEnumerator<IMethodInvoker> GetEnumerator()
// {
// return _invokers.GetEnumerator();
// }
//
// IEnumerator IEnumerable.GetEnumerator()
// {
// return GetEnumerator();
// }
//
// public int Count => _invokers.Count;
//
// public IMethodInvoker this[int index] => _invokers[index];
// }
} }
@@ -8,6 +8,7 @@ namespace mROA.Abstract
public interface IChannelInteractionModule : IInjectableModule, IDisposable public interface IChannelInteractionModule : IInjectableModule, IDisposable
{ {
int ConnectionId { get; set; } int ConnectionId { get; set; }
IEndPointContext Context { get; }
Channel<NetworkMessageHeader> ReceiveChanel { get; } Channel<NetworkMessageHeader> ReceiveChanel { get; }
ChannelReader<NetworkMessageHeader> TrustedPostChanel { get; } ChannelReader<NetworkMessageHeader> TrustedPostChanel { get; }
ChannelReader<NetworkMessageHeader> UntrustedPostChanel { get; } ChannelReader<NetworkMessageHeader> UntrustedPostChanel { get; }
+3 -3
View File
@@ -4,9 +4,9 @@ namespace mROA.Abstract
{ {
public interface IEndPointContext : IInjectableModule public interface IEndPointContext : IInjectableModule
{ {
IInstanceRepository RealRepository { get; } IInstanceRepository RealRepository { get; set; }
IInstanceRepository RemoteRepository { get; } IInstanceRepository RemoteRepository { get; set; }
ICallIndexProvider CallIndexProvider { get; } ICallIndexProvider CallIndexProvider { get; set; }
int HostId { get; set; } int HostId { get; set; }
int OwnerId { get; set; } int OwnerId { get; set; }
} }
+1 -1
View File
@@ -9,7 +9,7 @@ namespace mROA.Abstract
public interface IRepresentationModule : IInjectableModule public interface IRepresentationModule : IInjectableModule
{ {
int Id { get; } int Id { get; }
IEndPointContext Context { get; }
Task<(object? Deserialized, EMessageType MessageType)> GetSingle(Predicate<NetworkMessageHeader> rule, Task<(object? Deserialized, EMessageType MessageType)> GetSingle(Predicate<NetworkMessageHeader> rule,
IEndPointContext? context, CancellationToken token = default, IEndPointContext? context, CancellationToken token = default,
params Func<NetworkMessageHeader, Type?>[] converter); params Func<NetworkMessageHeader, Type?>[] converter);
@@ -55,10 +55,7 @@ namespace mROA.Implementation.Backend
private IRequestExtractor CreateExtractor(IRepresentationModule interaction) private IRequestExtractor CreateExtractor(IRepresentationModule interaction)
{ {
var extractor = new RequestExtractor(); var extractor = new RequestExtractor();
var context = new EndPointContext var context = interaction.Context;
{
HostId = 0, OwnerId = -interaction.Id
};
extractor.Inject(interaction); extractor.Inject(interaction);
if (_contextRepository is IContextRepositoryHub contextHub) if (_contextRepository is IContextRepositoryHub contextHub)
context.RealRepository = contextHub.GetRepository(interaction.Id); context.RealRepository = contextHub.GetRepository(interaction.Id);
@@ -16,6 +16,7 @@ namespace mROA.Implementation.Backend
private IConnectionHub? _hub; private IConnectionHub? _hub;
private IContextualSerializationToolKit? _serialization; private IContextualSerializationToolKit? _serialization;
private Dictionary<int, CancellationTokenSource> _extractorsCTS = new(); private Dictionary<int, CancellationTokenSource> _extractorsCTS = new();
private ICallIndexProvider _callIndexProvider;
public NetworkGatewayModule(IPEndPoint endpoint, Type interactionModuleType, public NetworkGatewayModule(IPEndPoint endpoint, Type interactionModuleType,
IInjectableModule[] injectableModules) IInjectableModule[] injectableModules)
@@ -49,6 +50,9 @@ namespace mROA.Implementation.Backend
case IContextualSerializationToolKit serializationToolkit: case IContextualSerializationToolKit serializationToolkit:
_serialization = serializationToolkit; _serialization = serializationToolkit;
break; break;
case ICallIndexProvider callIndexProvider:
_callIndexProvider = callIndexProvider;
break;
} }
} }
@@ -70,7 +74,7 @@ namespace mROA.Implementation.Backend
//TODO сделать контекст //TODO сделать контекст
var context = new EndPointContext(); var context = new EndPointContext();
context.CallIndexProvider = _callIndexProvider;
var streamExtractor = var streamExtractor =
new ChannelInteractionModule.StreamExtractor(client.GetStream(), _serialization, context); new ChannelInteractionModule.StreamExtractor(client.GetStream(), _serialization, context);
interaction.IsConnected = () => streamExtractor.IsConnected; interaction.IsConnected = () => streamExtractor.IsConnected;
@@ -87,6 +91,7 @@ namespace mROA.Implementation.Backend
case EMessageType.ClientConnect: case EMessageType.ClientConnect:
context.HostId = 0; context.HostId = 0;
context.OwnerId = -interaction.ConnectionId; context.OwnerId = -interaction.ConnectionId;
interaction.Inject(context);
Task.Run(async () => await streamExtractor.LoopedReceive(cts.Token)); Task.Run(async () => await streamExtractor.LoopedReceive(cts.Token));
_ = streamExtractor.SendFromChannel(interaction.TrustedPostChanel, cts.Token); _ = streamExtractor.SendFromChannel(interaction.TrustedPostChanel, cts.Token);
interaction.PostMessageAsync(new NetworkMessageHeader(_serialization!, interaction.PostMessageAsync(new NetworkMessageHeader(_serialization!,
@@ -46,6 +46,7 @@ namespace mROA.Implementation
public int ConnectionId { get; set; } public int ConnectionId { get; set; }
public IEndPointContext Context => _context;
public Channel<NetworkMessageHeader> ReceiveChanel { get; } public Channel<NetworkMessageHeader> ReceiveChanel { get; }
public ChannelReader<NetworkMessageHeader> TrustedPostChanel => _outputTrustedChannel.Reader; public ChannelReader<NetworkMessageHeader> TrustedPostChanel => _outputTrustedChannel.Reader;
@@ -0,0 +1,30 @@
using System.Collections.Generic;
using mROA.Abstract;
namespace mROA.Implementation
{
public class CollectableMethodRepository : IMethodRepository
{
private List<IMethodInvoker> _methods = new();
public void Inject<T>(T dependency)
{
}
public void AppendInvokers(IEnumerable<IMethodInvoker> methodInvokers)
{
_methods.AddRange(methodInvokers);
}
public IMethodInvoker GetMethod(int id)
{
if (id == -1)
return MethodInvoker.Dispose;
if (_methods.Count <= id)
return null;
return _methods[id];
}
}
}
+1 -1
View File
@@ -7,7 +7,7 @@ namespace mROA.Implementation
{ {
public IInstanceRepository RealRepository { get; set; } public IInstanceRepository RealRepository { get; set; }
public IInstanceRepository RemoteRepository { get; set; } public IInstanceRepository RemoteRepository { get; set; }
public ICallIndexProvider CallIndexProvider { get; } public ICallIndexProvider CallIndexProvider { get; set; }
public CallIndexConfig CallIndexConfig { get; set; } public CallIndexConfig CallIndexConfig { get; set; }
public int HostId { get; set; } public int HostId { get; set; }
@@ -48,7 +48,7 @@ namespace mROA.Implementation.Frontend
throw new NullReferenceException("Serialization toolkit is not initialized"); throw new NullReferenceException("Serialization toolkit is not initialized");
_tcpClient.Connect(_serverEndPoint); _tcpClient.Connect(_serverEndPoint);
_tcpClient.NoDelay = true;
PrepareExtractor(); PrepareExtractor();
_interactionModule.IsConnected = () => _currentExtractor.IsConnected; _interactionModule.IsConnected = () => _currentExtractor.IsConnected;
_interactionModule.OnDisconnected += _ => { Reconnect(); }; _interactionModule.OnDisconnected += _ => { Reconnect(); };
@@ -8,9 +8,7 @@ namespace mROA.Implementation
public class RemoteInstanceRepository : IInstanceRepository public class RemoteInstanceRepository : IInstanceRepository
{ {
private List<RemoteObjectBase> _producedProxys = new(); private List<RemoteObjectBase> _producedProxys = new();
private ICallIndexProvider _callIndexProvider;
public static Dictionary<Type, Func<int, IRepresentationModule, IEndPointContext, RemoteObjectBase>>
RemoteTypeFactories = new();
private IRepresentationModuleProducer? _representationProducer; private IRepresentationModuleProducer? _representationProducer;
@@ -34,11 +32,11 @@ namespace mROA.Implementation
if (_representationProducer == null) if (_representationProducer == null)
throw new NullReferenceException("representation producer is not initialized"); 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 = var representationModule =
_representationProducer.Produce(context.OwnerId); _representationProducer.Produce(context.OwnerId);
var remote = remoteType(id.ContextId, var remote = remoteType(id.ContextId,
representationModule, context); representationModule, context, _callIndexProvider.GetIndices(typeof(T)));
_producedProxys.Add(remote!); _producedProxys.Add(remote!);
@@ -58,7 +56,7 @@ namespace mROA.Implementation
var representationModule = var representationModule =
_representationProducer.Produce(context.OwnerId); _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; var remoteObjectBase = instance;
@@ -79,8 +77,15 @@ namespace mROA.Implementation
public void Inject<T>(T dependency) public void Inject<T>(T dependency)
{ {
if (dependency is IRepresentationModuleProducer serialisationModule) switch (dependency)
_representationProducer = serialisationModule; {
case IRepresentationModuleProducer serialisationModule:
_representationProducer = serialisationModule;
break;
case ICallIndexProvider callIndexProvider:
_callIndexProvider = callIndexProvider;
break;
}
} }
} }
} }
+3 -2
View File
@@ -32,12 +32,13 @@ namespace mROA.Implementation
private readonly ComplexObjectIdentifier _identifier; private readonly ComplexObjectIdentifier _identifier;
private readonly IRepresentationModule _representationModule; private readonly IRepresentationModule _representationModule;
protected readonly int[] _callIndices;
protected RemoteObjectBase(int id, IRepresentationModule representationModule, IEndPointContext context) protected RemoteObjectBase(int id, IRepresentationModule representationModule, IEndPointContext context, int[] indices)
{ {
_identifier = new ComplexObjectIdentifier { ContextId = id, OwnerId = representationModule.Id }; _identifier = new ComplexObjectIdentifier { ContextId = id, OwnerId = representationModule.Id };
_representationModule = representationModule; _representationModule = representationModule;
_context = context; _context = context;
_callIndices = indices;
} }
public int Id => _identifier.ContextId; public int Id => _identifier.ContextId;
@@ -31,6 +31,8 @@ namespace mROA.Implementation
public int Id => (_interaction ?? throw new NullReferenceException("Interaction is not initialized")) public int Id => (_interaction ?? throw new NullReferenceException("Interaction is not initialized"))
.ConnectionId; .ConnectionId;
public IEndPointContext Context => _interaction.Context;
public async Task<(object? Deserialized, EMessageType MessageType)> GetSingle( public async Task<(object? Deserialized, EMessageType MessageType)> GetSingle(
Predicate<NetworkMessageHeader> rule, IEndPointContext? context, Predicate<NetworkMessageHeader> rule, IEndPointContext? context,
CancellationToken token = default, params Func<NetworkMessageHeader, Type?>[] converter) CancellationToken token = default, params Func<NetworkMessageHeader, Type?>[] converter)