билдится на старом дотнете
This commit is contained in:
@@ -2,9 +2,11 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
|
||||
<Nullable>enable</Nullable>
|
||||
|
||||
<LangVersion>9</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
using Example.Shared;
|
||||
using System;
|
||||
using Example.Shared;
|
||||
using mROA.Implementation.Attributes;
|
||||
|
||||
namespace Example.Backend;
|
||||
|
||||
[SharedObjectSingleton]
|
||||
public class LoadTestImp : ILoadTest
|
||||
namespace Example.Backend
|
||||
{
|
||||
[SharedObjectSingleton]
|
||||
public class LoadTestImp : ILoadTest
|
||||
{
|
||||
public int Next(int last)
|
||||
{
|
||||
return last + 1;
|
||||
@@ -25,4 +26,5 @@ public class LoadTestImp : ILoadTest
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,14 @@
|
||||
using System.Text;
|
||||
using Example.Shared;
|
||||
|
||||
namespace Example.Backend;
|
||||
|
||||
public class Page : IPage
|
||||
namespace Example.Backend
|
||||
{
|
||||
public class Page : IPage
|
||||
{
|
||||
public string Text;
|
||||
public byte[] GetData()
|
||||
{
|
||||
return Encoding.UTF8.GetBytes(Text);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,12 @@
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Example.Shared;
|
||||
using mROA.Implementation;
|
||||
|
||||
namespace Example.Backend;
|
||||
|
||||
|
||||
public class Printer : IPrinter
|
||||
namespace Example.Backend
|
||||
{
|
||||
public class Printer : IPrinter
|
||||
{
|
||||
public string Name;
|
||||
public string GetName()
|
||||
{
|
||||
@@ -17,4 +18,5 @@ public class Printer : IPrinter
|
||||
// throw new Exception("The method or operation is not implemented.");
|
||||
return new Page {Text = text};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,16 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Example.Shared;
|
||||
using mROA.Implementation;
|
||||
using mROA.Implementation.Attributes;
|
||||
|
||||
namespace Example.Backend;
|
||||
|
||||
[SharedObjectSingleton]
|
||||
public class PrinterFactory : IPrinterFactory
|
||||
namespace Example.Backend
|
||||
{
|
||||
private List<IPrinter> _printers = new();
|
||||
[SharedObjectSingleton]
|
||||
public class PrinterFactory : IPrinterFactory
|
||||
{
|
||||
private List<IPrinter> _printers = new List<IPrinter>();
|
||||
|
||||
public SharedObject<IPrinter> Create(string printerName)
|
||||
{
|
||||
@@ -37,4 +40,5 @@ public class PrinterFactory : IPrinterFactory
|
||||
Console.WriteLine("Collecting all printers");
|
||||
return _printers.Select(i => i.GetName()).ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
+27
-21
@@ -7,37 +7,43 @@ using mROA.Implementation.Backend;
|
||||
using mROA.Implementation.Bootstrap;
|
||||
using mROA.Implementation.Frontend;
|
||||
|
||||
|
||||
var builder = new FullMixBuilder();
|
||||
builder.UseJsonSerialisation();
|
||||
builder.Modules.Add(new BackendIdentityGenerator());
|
||||
builder.UseNetworkGateway(new IPEndPoint(IPAddress.Loopback, 4567), typeof(NextGenerationInteractionModule),
|
||||
class Program
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
var builder = new FullMixBuilder();
|
||||
builder.UseJsonSerialisation();
|
||||
builder.Modules.Add(new BackendIdentityGenerator());
|
||||
builder.UseNetworkGateway(new IPEndPoint(IPAddress.Loopback, 4567), typeof(NextGenerationInteractionModule),
|
||||
builder.GetModule<IIdentityGenerator>()!);
|
||||
|
||||
builder.Modules.Add(new ConnectionHub());
|
||||
builder.Modules.Add(new HubRequestExtractor(typeof(RequestExtractor)));
|
||||
builder.Modules.Add(new ConnectionHub());
|
||||
builder.Modules.Add(new HubRequestExtractor(typeof(RequestExtractor)));
|
||||
|
||||
builder.UseBasicExecution();
|
||||
builder.UseBasicExecution();
|
||||
|
||||
builder.Modules.Add(new RemoteContextRepository());
|
||||
builder.Modules.Add(new RemoteContextRepository());
|
||||
// builder.UseCollectableContextRepository(typeof(PrinterFactory).Assembly);
|
||||
builder.Modules.Add(new MultiClientContextRepository(i =>
|
||||
{
|
||||
builder.Modules.Add(new MultiClientContextRepository(i =>
|
||||
{
|
||||
var repo = new ContextRepository();
|
||||
repo.FillSingletons(typeof(PrinterFactory).Assembly);
|
||||
return repo;
|
||||
}));
|
||||
builder.SetupMethodsRepository(new CoCodegenMethodRepository());
|
||||
builder.Modules.Add(new CreativeRepresentationModuleProducer([builder.GetModule<JsonSerializationToolkit>()!],
|
||||
}));
|
||||
builder.SetupMethodsRepository(new CoCodegenMethodRepository());
|
||||
builder.Modules.Add(new CreativeRepresentationModuleProducer(
|
||||
new IInjectableModule[] { builder.GetModule<JsonSerializationToolkit>()! },
|
||||
typeof(RepresentationModule)));
|
||||
|
||||
builder.Build();
|
||||
new RemoteTypeBinder();
|
||||
builder.Build();
|
||||
new RemoteTypeBinder();
|
||||
|
||||
TransmissionConfig.RealContextRepository = builder.GetModule<MultiClientContextRepository>();
|
||||
TransmissionConfig.RemoteEndpointContextRepository = builder.GetModule<RemoteContextRepository>();
|
||||
TransmissionConfig.OwnershipRepository = new MultiClientOwnershipRepository();
|
||||
TransmissionConfig.RealContextRepository = builder.GetModule<MultiClientContextRepository>();
|
||||
TransmissionConfig.RemoteEndpointContextRepository = builder.GetModule<RemoteContextRepository>();
|
||||
TransmissionConfig.OwnershipRepository = new MultiClientOwnershipRepository();
|
||||
|
||||
var gateway = builder.GetModule<IGatewayModule>();
|
||||
var gateway = builder.GetModule<IGatewayModule>();
|
||||
|
||||
gateway.Run();
|
||||
gateway.Run();
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,13 @@
|
||||
using Example.Shared;
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Example.Shared;
|
||||
using mROA.Implementation;
|
||||
|
||||
namespace Example.Frontend;
|
||||
|
||||
public class ClientBasedPrinter : IPrinter
|
||||
namespace Example.Frontend
|
||||
{
|
||||
public class ClientBasedPrinter : IPrinter
|
||||
{
|
||||
public string GetName()
|
||||
{
|
||||
Console.WriteLine("ClientBasedPrinter called from server!!!!!!!!!!! Vova likes that:)");
|
||||
@@ -17,12 +20,13 @@ public class ClientBasedPrinter : IPrinter
|
||||
await Task.Yield();
|
||||
return new ClientBasedPage();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class ClientBasedPage : IPage
|
||||
{
|
||||
public class ClientBasedPage : IPage
|
||||
{
|
||||
public byte[] GetData()
|
||||
{
|
||||
return [1, 2, 3];
|
||||
return new byte[] { 1, 2, 3 };
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,9 +2,11 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
|
||||
<Nullable>enable</Nullable>
|
||||
|
||||
<LangVersion>9</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
+60
-52
@@ -1,6 +1,8 @@
|
||||
using System.Diagnostics;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using Example.Frontend;
|
||||
using Example.Shared;
|
||||
using mROA.Codegen;
|
||||
@@ -9,71 +11,77 @@ using mROA.Implementation.Backend;
|
||||
using mROA.Implementation.Bootstrap;
|
||||
using mROA.Implementation.Frontend;
|
||||
|
||||
var builder = new FullMixBuilder();
|
||||
new RemoteTypeBinder();
|
||||
builder.Modules.Add(new JsonSerializationToolkit());
|
||||
builder.Modules.Add(new RemoteContextRepository());
|
||||
builder.Modules.Add(new NextGenerationInteractionModule());
|
||||
builder.Modules.Add(new RepresentationModule());
|
||||
builder.Modules.Add(new NetworkFrontendBridge(new IPEndPoint(IPAddress.Loopback, 4567)));
|
||||
builder.Modules.Add(new StaticRepresentationModuleProducer());
|
||||
builder.Modules.Add(new RequestExtractor());
|
||||
builder.Modules.Add(new BasicExecutionModule());
|
||||
builder.Modules.Add(new CoCodegenMethodRepository());
|
||||
builder.UseCollectableContextRepository();
|
||||
builder.Build();
|
||||
class Program
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
var builder = new FullMixBuilder();
|
||||
new RemoteTypeBinder();
|
||||
builder.Modules.Add(new JsonSerializationToolkit());
|
||||
builder.Modules.Add(new RemoteContextRepository());
|
||||
builder.Modules.Add(new NextGenerationInteractionModule());
|
||||
builder.Modules.Add(new RepresentationModule());
|
||||
builder.Modules.Add(new NetworkFrontendBridge(new IPEndPoint(IPAddress.Loopback, 4567)));
|
||||
builder.Modules.Add(new StaticRepresentationModuleProducer());
|
||||
builder.Modules.Add(new RequestExtractor());
|
||||
builder.Modules.Add(new BasicExecutionModule());
|
||||
builder.Modules.Add(new CoCodegenMethodRepository());
|
||||
builder.UseCollectableContextRepository();
|
||||
builder.Build();
|
||||
|
||||
|
||||
TransmissionConfig.RealContextRepository = builder.GetModule<ContextRepository>();
|
||||
TransmissionConfig.RemoteEndpointContextRepository = builder.GetModule<RemoteContextRepository>();
|
||||
TransmissionConfig.RealContextRepository = builder.GetModule<ContextRepository>();
|
||||
TransmissionConfig.RemoteEndpointContextRepository = builder.GetModule<RemoteContextRepository>();
|
||||
|
||||
builder.GetModule<NetworkFrontendBridge>()!.Connect();
|
||||
_ = builder.GetModule<RequestExtractor>()!.StartExtraction();
|
||||
Console.WriteLine(TransmissionConfig.OwnershipRepository.GetOwnershipId());
|
||||
var context = builder.GetModule<RemoteContextRepository>();
|
||||
builder.GetModule<NetworkFrontendBridge>()!.Connect();
|
||||
_ = builder.GetModule<RequestExtractor>()!.StartExtraction();
|
||||
Console.WriteLine(TransmissionConfig.OwnershipRepository.GetOwnershipId());
|
||||
var context = builder.GetModule<RemoteContextRepository>();
|
||||
|
||||
var factory = context.GetSingleObject(typeof(IPrinterFactory)) as IPrinterFactory;
|
||||
var factory = context.GetSingleObject(typeof(IPrinterFactory)) as IPrinterFactory;
|
||||
|
||||
//правильный порядок команд 8-5-10-7
|
||||
var printer = factory.Create("Test");
|
||||
Console.WriteLine("Printer created");
|
||||
Thread.Sleep(100);
|
||||
var printer = factory.Create("Test");
|
||||
Console.WriteLine("Printer created");
|
||||
Thread.Sleep(100);
|
||||
|
||||
var name = printer.Value.GetName();
|
||||
Console.WriteLine("Printer name : {0}", name);
|
||||
Thread.Sleep(100);
|
||||
var name = printer.Value.GetName();
|
||||
Console.WriteLine("Printer name : {0}", name);
|
||||
Thread.Sleep(100);
|
||||
|
||||
factory.Register(new SharedObject<IPrinter>(new ClientBasedPrinter()));
|
||||
Console.WriteLine("Registered printer");
|
||||
Thread.Sleep(100);
|
||||
factory.Register(new SharedObject<IPrinter>(new ClientBasedPrinter()));
|
||||
Console.WriteLine("Registered printer");
|
||||
Thread.Sleep(100);
|
||||
|
||||
|
||||
var registred = factory.GetFirstPrinter();
|
||||
Console.WriteLine("First printer");
|
||||
Thread.Sleep(100);
|
||||
var registred = factory.GetFirstPrinter();
|
||||
Console.WriteLine("First printer");
|
||||
Thread.Sleep(100);
|
||||
|
||||
Console.WriteLine(registred.Value);
|
||||
Console.WriteLine("Collecting all printers");
|
||||
var names = factory.CollectAllNames();
|
||||
Thread.Sleep(100);
|
||||
Console.WriteLine(registred.Value);
|
||||
Console.WriteLine("Collecting all printers");
|
||||
var names = factory.CollectAllNames();
|
||||
Thread.Sleep(100);
|
||||
|
||||
Console.WriteLine(string.Join(", ", names));
|
||||
Console.WriteLine(string.Join(", ", names));
|
||||
|
||||
var page = printer.Value.Print("Test Page", new CancellationToken()).GetAwaiter().GetResult();
|
||||
var data = page.Value.GetData();
|
||||
Console.WriteLine("Data : {0}", Encoding.UTF8.GetString(data));
|
||||
var page = printer.Value.Print("Test Page", new CancellationToken()).GetAwaiter().GetResult();
|
||||
var data = page.Value.GetData();
|
||||
Console.WriteLine("Data : {0}", Encoding.UTF8.GetString(data));
|
||||
|
||||
var loadSingleton = context.GetSingleObject(typeof(ILoadTest)) as ILoadTest;
|
||||
var loadSingleton = context.GetSingleObject(typeof(ILoadTest)) as ILoadTest;
|
||||
|
||||
const int iterations = 10000;
|
||||
var timer = Stopwatch.StartNew();
|
||||
var x = 0;
|
||||
for (int i = 0; i < iterations; i++)
|
||||
{
|
||||
const int iterations = 10000;
|
||||
var timer = Stopwatch.StartNew();
|
||||
var x = 0;
|
||||
for (int i = 0; i < iterations; i++)
|
||||
{
|
||||
x = loadSingleton.Next(x);
|
||||
}
|
||||
}
|
||||
|
||||
timer.Stop();
|
||||
Console.WriteLine("X is {0}", x);
|
||||
Console.WriteLine("Time : {0}", timer.Elapsed.TotalMilliseconds);
|
||||
Console.WriteLine($"Time per call: {timer.Elapsed.TotalMilliseconds / iterations} ms");
|
||||
timer.Stop();
|
||||
Console.WriteLine("X is {0}", x);
|
||||
Console.WriteLine("Time : {0}", timer.Elapsed.TotalMilliseconds);
|
||||
Console.WriteLine($"Time per call: {timer.Elapsed.TotalMilliseconds / iterations} ms");
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,11 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
|
||||
<Nullable>enable</Nullable>
|
||||
|
||||
<LangVersion>9</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
using mROA.Implementation.Attributes;
|
||||
|
||||
namespace Example.Shared;
|
||||
|
||||
[SharedObjectInterface]
|
||||
public interface ILoadTest
|
||||
namespace Example.Shared
|
||||
{
|
||||
[SharedObjectInterface]
|
||||
public interface ILoadTest
|
||||
{
|
||||
int Next(int last);
|
||||
int Last(int next);
|
||||
void C();
|
||||
void A();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
using mROA.Implementation.Attributes;
|
||||
|
||||
namespace Example.Shared;
|
||||
|
||||
[SharedObjectInterface]
|
||||
public interface IPage
|
||||
namespace Example.Shared
|
||||
{
|
||||
[SharedObjectInterface]
|
||||
public interface IPage
|
||||
{
|
||||
byte[] GetData();
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,15 @@
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using mROA.Implementation;
|
||||
using mROA.Implementation.Attributes;
|
||||
|
||||
namespace Example.Shared;
|
||||
|
||||
[SharedObjectInterface]
|
||||
public interface IPrinter
|
||||
namespace Example.Shared
|
||||
{
|
||||
[SharedObjectInterface]
|
||||
public interface IPrinter
|
||||
{
|
||||
string GetName();
|
||||
Task<SharedObject<IPage>> Print(string text, CancellationToken cancellationToken);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,16 @@
|
||||
using mROA.Implementation;
|
||||
using mROA.Implementation.Attributes;
|
||||
|
||||
namespace Example.Shared;
|
||||
|
||||
[SharedObjectInterface]
|
||||
public interface IPrinterFactory
|
||||
namespace Example.Shared
|
||||
{
|
||||
[SharedObjectInterface]
|
||||
public interface IPrinterFactory
|
||||
{
|
||||
SharedObject<IPrinter> Create(string printerName);
|
||||
void Register(SharedObject<IPrinter> printer);
|
||||
SharedObject<IPrinter> GetPrinterByName(string printerName);
|
||||
SharedObject<IPrinter> GetFirstPrinter();
|
||||
string[] CollectAllNames();
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,20 +1,23 @@
|
||||
using BenchmarkDotNet.Attributes;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using BenchmarkDotNet.Attributes;
|
||||
using BenchmarkDotNet.Running;
|
||||
|
||||
namespace mROA.Benchmark;
|
||||
|
||||
class Program
|
||||
namespace mROA.Benchmark
|
||||
{
|
||||
class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
Console.WriteLine("Hello, World!");
|
||||
var summary = BenchmarkRunner.Run<CollectionsSpeed>();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class CollectionsSpeed
|
||||
{
|
||||
public class CollectionsSpeed
|
||||
{
|
||||
private const int N = 1000;
|
||||
|
||||
private readonly List<int> _immutable;
|
||||
@@ -47,4 +50,5 @@ public class CollectionsSpeed
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
@@ -25,8 +25,7 @@
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.3.0" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.3.0" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.8.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -7,15 +7,15 @@ using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using Microsoft.CodeAnalysis.Text;
|
||||
|
||||
|
||||
namespace mROA.Codegen;
|
||||
|
||||
/// <summary>
|
||||
/// A sample source generator that creates a custom report based on class properties. The target class should be annotated with the 'Generators.ReportAttribute' attribute.
|
||||
/// When using the source code as a baseline, an incremental source generator is preferable because it reduces the performance overhead.
|
||||
/// </summary>
|
||||
[Generator]
|
||||
public class mROASourceGenerator : IIncrementalGenerator
|
||||
namespace mROA.Codegen
|
||||
{
|
||||
/// <summary>
|
||||
/// A sample source generator that creates a custom report based on class properties. The target class should be annotated with the 'Generators.ReportAttribute' attribute.
|
||||
/// When using the source code as a baseline, an incremental source generator is preferable because it reduces the performance overhead.
|
||||
/// </summary>
|
||||
[Generator]
|
||||
public class mROASourceGenerator : ISourceGenerator
|
||||
{
|
||||
private const string Namespace = "mROA.Implementation";
|
||||
private const string AttributeName = "SharedObjectInterafceAttribute";
|
||||
|
||||
@@ -29,47 +29,47 @@ namespace {Namespace}
|
||||
}}
|
||||
}}";
|
||||
|
||||
public void Initialize(IncrementalGeneratorInitializationContext context)
|
||||
{
|
||||
// Filter classes annotated with the [Report] attribute. Only filtered Syntax Nodes can trigger code generation.
|
||||
var provider = context.SyntaxProvider
|
||||
.CreateSyntaxProvider(
|
||||
(s, _) => s is InterfaceDeclarationSyntax,
|
||||
(ctx, _) => GetClassDeclarationForSourceGen(ctx))
|
||||
.Where(t => t.reportAttributeFound)
|
||||
.Select((t, _) => t.Item1);
|
||||
|
||||
// Generate the source code.
|
||||
context.RegisterSourceOutput(context.CompilationProvider.Combine(provider.Collect()),
|
||||
((ctx, t) => GenerateCode(ctx, t.Left, t.Right)));
|
||||
}
|
||||
// public void Initialize(IncrementalGeneratorInitializationContext context)
|
||||
// {
|
||||
// // Filter classes annotated with the [Report] attribute. Only filtered Syntax Nodes can trigger code generation.
|
||||
// var provider = context.SyntaxProvider
|
||||
// .CreateSyntaxProvider(
|
||||
// (s, _) => s is InterfaceDeclarationSyntax,
|
||||
// (ctx, _) => GetClassDeclarationForSourceGen(ctx))
|
||||
// .Where(t => t.reportAttributeFound)
|
||||
// .Select((t, _) => t.Item1);
|
||||
//
|
||||
// // Generate the source code.
|
||||
// context.RegisterSourceOutput(context.CompilationProvider.Combine(provider.Collect()),
|
||||
// ((ctx, t) => GenerateCode(ctx, t.Left, t.Right)));
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether the Node is annotated with the [Report] attribute and maps syntax context to the specific node type (ClassDeclarationSyntax).
|
||||
/// </summary>
|
||||
/// <param name="context">Syntax context, based on CreateSyntaxProvider predicate</param>
|
||||
/// <returns>The specific cast and whether the attribute was found.</returns>
|
||||
private static (InterfaceDeclarationSyntax, bool reportAttributeFound) GetClassDeclarationForSourceGen(
|
||||
GeneratorSyntaxContext context)
|
||||
{
|
||||
var classDeclarationSyntax = (InterfaceDeclarationSyntax)context.Node;
|
||||
|
||||
// Go through all attributes of the class.
|
||||
foreach (AttributeListSyntax attributeListSyntax in classDeclarationSyntax.AttributeLists)
|
||||
foreach (AttributeSyntax attributeSyntax in attributeListSyntax.Attributes)
|
||||
{
|
||||
if (context.SemanticModel.GetSymbolInfo(attributeSyntax).Symbol is not IMethodSymbol attributeSymbol)
|
||||
continue; // if we can't get the symbol, ignore it
|
||||
|
||||
string attributeName = attributeSymbol.ContainingType.ToDisplayString();
|
||||
|
||||
// Check the full name of the [Report] attribute.
|
||||
if (attributeName == "mROA.Implementation.Attributes.SharedObjectInterfaceAttribute")
|
||||
return (classDeclarationSyntax, true);
|
||||
}
|
||||
|
||||
return (classDeclarationSyntax, false);
|
||||
}
|
||||
// private static (InterfaceDeclarationSyntax, bool reportAttributeFound) GetClassDeclarationForSourceGen(
|
||||
// GeneratorSyntaxContext context)
|
||||
// {
|
||||
// var classDeclarationSyntax = (InterfaceDeclarationSyntax)context.Node;
|
||||
//
|
||||
// // Go through all attributes of the class.
|
||||
// foreach (AttributeListSyntax attributeListSyntax in classDeclarationSyntax.AttributeLists)
|
||||
// foreach (AttributeSyntax attributeSyntax in attributeListSyntax.Attributes)
|
||||
// {
|
||||
// if (context.SemanticModel.GetSymbolInfo(attributeSyntax).Symbol is not IMethodSymbol attributeSymbol)
|
||||
// continue; // if we can't get the symbol, ignore it
|
||||
//
|
||||
// string attributeName = attributeSymbol.ContainingType.ToDisplayString();
|
||||
//
|
||||
// // Check the full name of the [Report] attribute.
|
||||
// if (attributeName == "mROA.Implementation.Attributes.SharedObjectInterfaceAttribute")
|
||||
// return (classDeclarationSyntax, true);
|
||||
// }
|
||||
//
|
||||
// return (classDeclarationSyntax, false);
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// Generate code action.
|
||||
@@ -78,7 +78,7 @@ namespace {Namespace}
|
||||
/// <param name="context">Source generation context used to add source files.</param>
|
||||
/// <param name="compilation">Compilation used to provide access to the Semantic Model.</param>
|
||||
/// <param name="classes">Nodes annotated with the [Report] attribute that trigger the generate action.</param>
|
||||
private void GenerateCode(SourceProductionContext context, Compilation compilation,
|
||||
private void GenerateCode(GeneratorExecutionContext context, Compilation compilation,
|
||||
ImmutableArray<InterfaceDeclarationSyntax> classes)
|
||||
{
|
||||
var methods = new List<(string, IMethodSymbol)>();
|
||||
@@ -133,7 +133,7 @@ namespace {Namespace}
|
||||
|
||||
|
||||
var prefix = isAsync ? "await " : "";
|
||||
var postfix = !isAsync ? (isVoid? ".Wait()" : ".GetAwaiter().GetResult()") : "";
|
||||
var postfix = !isAsync ? (isVoid ? ".Wait()" : ".GetAwaiter().GetResult()") : "";
|
||||
var parameterLink = isParametrized ? ", " + method.Parameters.First().Name : string.Empty;
|
||||
var caller = isVoid ? $"CallAsync({index}{parameterLink})" :
|
||||
isAsync ? $"GetResultAsync<{ExtractTaskType(method.ReturnType)}>({index}{parameterLink})" :
|
||||
@@ -166,9 +166,9 @@ namespace {Namespace}
|
||||
//
|
||||
// sb.AppendLine("\t}");
|
||||
|
||||
sb.AppendLine("\t\t" + prefix + caller + postfix+ ";");
|
||||
sb.AppendLine("\t\t\t" + prefix + caller + postfix + ";");
|
||||
|
||||
sb.AppendLine("\t}");
|
||||
sb.AppendLine("\t\t}");
|
||||
|
||||
methodsText.Add(sb.ToString());
|
||||
}
|
||||
@@ -181,19 +181,21 @@ using mROA.Implementation;
|
||||
using System.Collections.Generic;
|
||||
using mROA.Abstract;
|
||||
|
||||
namespace {namespaceName};
|
||||
|
||||
partial class {className} : RemoteObjectBase, {originalName}
|
||||
namespace {namespaceName}
|
||||
{{
|
||||
partial class {className} : RemoteObjectBase, {originalName}
|
||||
{{
|
||||
public {className}(int id, IRepresentationModule representationModule) : base(id, representationModule)
|
||||
{{
|
||||
}}
|
||||
|
||||
{string.Join("\r\n\t", methodsText)}
|
||||
}}
|
||||
}}
|
||||
";
|
||||
|
||||
|
||||
|
||||
// Add the source code to the compilation.
|
||||
context.AddSource($"{className}.g.cs", SourceText.From(code, Encoding.UTF8));
|
||||
|
||||
@@ -204,21 +206,23 @@ partial class {className} : RemoteObjectBase, {originalName}
|
||||
if (methods.Count != 0)
|
||||
{
|
||||
var methodsStringed = methods.Select(i =>
|
||||
$"typeof({i.Item1}).GetMethod(\"{i.Item2.Name}\", [{string.Join(", ", i.Item2.Parameters.Select(p => $"typeof({p.Type.ToDisplayString()})"))}])")
|
||||
$"typeof({i.Item1}).GetMethod(\"{i.Item2.Name}\", new Type[] {{{string.Join(", ", i.Item2.Parameters.Select(p => $"typeof({p.Type.ToDisplayString()})"))}}})")
|
||||
.ToList();
|
||||
|
||||
var coCodegenRepoCode = @$"// <auto-generated/>
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using mROA.Abstract;
|
||||
using System;
|
||||
|
||||
namespace mROA.Codegen;
|
||||
|
||||
public class CoCodegenMethodRepository : IMethodRepository
|
||||
namespace mROA.Codegen
|
||||
{{
|
||||
private readonly List<MethodInfo> _methods = [
|
||||
{string.Join(", // test comment\r\n\t\t", methodsStringed)}
|
||||
];
|
||||
public class CoCodegenMethodRepository : IMethodRepository
|
||||
{{
|
||||
private readonly List<MethodInfo> _methods = new () {{
|
||||
{string.Join(",\r\n\t\t\t", methodsStringed)}
|
||||
}};
|
||||
|
||||
public MethodInfo GetMethod(int id)
|
||||
{{
|
||||
if (_methods.Count <= id)
|
||||
@@ -241,6 +245,7 @@ public class CoCodegenMethodRepository : IMethodRepository
|
||||
public void Inject<T>(T dependency)
|
||||
{{
|
||||
}}
|
||||
}}
|
||||
}}
|
||||
";
|
||||
context.AddSource($"CoCodegenMethodRepository.g.cs", SourceText.From(coCodegenRepoCode, Encoding.UTF8));
|
||||
@@ -249,17 +254,20 @@ public class CoCodegenMethodRepository : IMethodRepository
|
||||
if (frontendContextRepo.Count != 0)
|
||||
{
|
||||
var fronendRepoCode = @$"// <auto-generated/>
|
||||
using System.Collections.Frozen;
|
||||
using mROA.Implementation;
|
||||
using mROA.Abstract;
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
namespace mROA.Codegen;
|
||||
|
||||
public sealed class RemoteTypeBinder
|
||||
namespace mROA.Codegen
|
||||
{{
|
||||
public sealed class RemoteTypeBinder
|
||||
{{
|
||||
static RemoteTypeBinder(){{
|
||||
RemoteContextRepository.RemoteTypes = new Dictionary<Type, Type> {{
|
||||
{string.Join(", \r\n\t\t", frontendContextRepo)}}}.ToFrozenDictionary();
|
||||
{string.Join(", \r\n\t\t\t", frontendContextRepo)}}};
|
||||
}}
|
||||
}}
|
||||
}}
|
||||
";
|
||||
@@ -283,4 +291,58 @@ public sealed class RemoteTypeBinder
|
||||
type = type.Substring(type.IndexOf('<') + 1);
|
||||
return type.Substring(0, type.Length - 1);
|
||||
}
|
||||
|
||||
public void Initialize(GeneratorInitializationContext context)
|
||||
{
|
||||
}
|
||||
|
||||
public void Execute(GeneratorExecutionContext context)
|
||||
{
|
||||
var trees = context.Compilation.SyntaxTrees;
|
||||
|
||||
var interfaces = new List<InterfaceDeclarationSyntax>();
|
||||
foreach (var tree in trees)
|
||||
{
|
||||
var node = tree.GetRoot() as CompilationUnitSyntax;
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
private bool ContainsSOIAttribute(SyntaxList<AttributeListSyntax> attributes, GeneratorExecutionContext context,
|
||||
InterfaceDeclarationSyntax interfaceDeclarationSyntax)
|
||||
{
|
||||
foreach (AttributeListSyntax attributeListSyntax in attributes)
|
||||
foreach (AttributeSyntax attributeSyntax in attributeListSyntax.Attributes)
|
||||
{
|
||||
if (context.Compilation.GetSemanticModel(interfaceDeclarationSyntax.SyntaxTree)
|
||||
.GetSymbolInfo(attributeSyntax).Symbol is not IMethodSymbol attributeSymbol)
|
||||
continue; // if we can't get the symbol, ignore it
|
||||
|
||||
string attributeName = attributeSymbol.ContainingType.ToDisplayString();
|
||||
|
||||
// Check the full name of the [Report] attribute.
|
||||
if (attributeName == "mROA.Implementation.Attributes.SharedObjectInterfaceAttribute")
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,16 +1,19 @@
|
||||
using System.Net;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using mROA.Implementation;
|
||||
|
||||
namespace mROA.Test;
|
||||
|
||||
public class NextGenTest
|
||||
namespace mROA.Test
|
||||
{
|
||||
public class NextGenTest
|
||||
{
|
||||
private TcpListener _listener;
|
||||
private NextGenerationInteractionModule _interactionModuleA;
|
||||
private NextGenerationInteractionModule _interactionModuleB;
|
||||
private Guid[] guids = [Guid.NewGuid(), Guid.NewGuid(), Guid.NewGuid()];
|
||||
private Guid[] guids = new[] { Guid.NewGuid(), Guid.NewGuid(), Guid.NewGuid() };
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
@@ -69,4 +72,5 @@ public class NextGenTest
|
||||
{
|
||||
_listener.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
|
||||
<Nullable>enable</Nullable>
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
namespace mROA.Abstract;
|
||||
using System;
|
||||
|
||||
public interface ICommandExecution
|
||||
namespace mROA.Abstract
|
||||
{
|
||||
Guid Id { get; init; }
|
||||
public interface ICommandExecution
|
||||
{
|
||||
Guid Id { get; set; }
|
||||
int ClientId { get; set; }
|
||||
int CommandId { get; }
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,13 @@
|
||||
namespace mROA.Abstract;
|
||||
|
||||
public delegate void ConnectionHandler(IRepresentationModule representationModule);
|
||||
public delegate void DisconnectionHandler(IRepresentationModule representationModule);
|
||||
|
||||
public interface IConnectionHub : IInjectableModule
|
||||
namespace mROA.Abstract
|
||||
{
|
||||
public delegate void ConnectionHandler(IRepresentationModule representationModule);
|
||||
public delegate void DisconnectionHandler(IRepresentationModule representationModule);
|
||||
|
||||
public interface IConnectionHub : IInjectableModule
|
||||
{
|
||||
void RegisterInteraction(INextGenerationInteractionModule interaction);
|
||||
INextGenerationInteractionModule GetInteracion(int id);
|
||||
event ConnectionHandler? OnConnected;
|
||||
event DisconnectionHandler? OnDisconnected;
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,14 @@
|
||||
namespace mROA.Abstract;
|
||||
using System;
|
||||
|
||||
public interface IContextRepository : IInjectableModule
|
||||
namespace mROA.Abstract
|
||||
{
|
||||
public interface IContextRepository : IInjectableModule
|
||||
{
|
||||
int ResisterObject(object o);
|
||||
void ClearObject(int id);
|
||||
object GetObject(int id);
|
||||
T? GetObject<T>(int id);
|
||||
object GetSingleObject(Type type);
|
||||
int GetObjectIndex(object o);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
namespace mROA.Abstract;
|
||||
|
||||
public interface IContextRepositoryHub
|
||||
namespace mROA.Abstract
|
||||
{
|
||||
public interface IContextRepositoryHub
|
||||
{
|
||||
IContextRepository GetRepository(int clientId);
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,9 @@
|
||||
using mROA.Implementation;
|
||||
|
||||
namespace mROA.Abstract;
|
||||
|
||||
public interface IExecuteModule : IInjectableModule
|
||||
namespace mROA.Abstract
|
||||
{
|
||||
public interface IExecuteModule : IInjectableModule
|
||||
{
|
||||
ICommandExecution Execute(ICallRequest command, IContextRepository contextRepository);
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,7 @@
|
||||
namespace mROA.Abstract;
|
||||
namespace mROA.Abstract
|
||||
{
|
||||
public interface IFrontendBridge : IInjectableModule
|
||||
{
|
||||
|
||||
public interface IFrontendBridge : IInjectableModule;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,9 @@
|
||||
namespace mROA.Abstract;
|
||||
using System;
|
||||
|
||||
public interface IGatewayModule : IDisposable, IInjectableModule
|
||||
namespace mROA.Abstract
|
||||
{
|
||||
public interface IGatewayModule : IDisposable, IInjectableModule
|
||||
{
|
||||
void Run();
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
namespace mROA.Abstract;
|
||||
|
||||
public interface IIdentityGenerator : IInjectableModule
|
||||
namespace mROA.Abstract
|
||||
{
|
||||
public interface IIdentityGenerator : IInjectableModule
|
||||
{
|
||||
int GetNextIdentity();
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
namespace mROA.Abstract;
|
||||
|
||||
public interface IInjectableModule
|
||||
namespace mROA.Abstract
|
||||
{
|
||||
public interface IInjectableModule
|
||||
{
|
||||
void Inject<T>(T dependency);
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,12 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using mROA.Implementation;
|
||||
|
||||
namespace mROA.Abstract;
|
||||
|
||||
public interface INextGenerationInteractionModule : IInjectableModule
|
||||
namespace mROA.Abstract
|
||||
{
|
||||
public interface INextGenerationInteractionModule : IInjectableModule
|
||||
{
|
||||
int ConnectionId { get; }
|
||||
public Stream? BaseStream { get; set; }
|
||||
Task<NetworkMessage> GetNextMessageReceiving();
|
||||
@@ -11,4 +14,5 @@ public interface INextGenerationInteractionModule : IInjectableModule
|
||||
void HandleMessage(NetworkMessage message);
|
||||
NetworkMessage[] UnhandledMessages { get; }
|
||||
NetworkMessage? FirstByFilter(Predicate<NetworkMessage> predicate);
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,13 @@
|
||||
using System.Reflection;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
|
||||
namespace mROA.Abstract;
|
||||
|
||||
public interface IMethodRepository : IInjectableModule
|
||||
namespace mROA.Abstract
|
||||
{
|
||||
public interface IMethodRepository : IInjectableModule
|
||||
{
|
||||
MethodInfo GetMethod(int id);
|
||||
int RegisterMethod(MethodInfo method);
|
||||
|
||||
IEnumerable<MethodInfo> GetMethods();
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,8 @@
|
||||
namespace mROA.Abstract;
|
||||
|
||||
public interface IOwnershipRepository
|
||||
namespace mROA.Abstract
|
||||
{
|
||||
public interface IOwnershipRepository
|
||||
{
|
||||
int GetOwnershipId();
|
||||
int GetHostOwnershipId();
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
namespace mROA.Abstract;
|
||||
|
||||
public interface IRepresentationModuleProducer : IInjectableModule
|
||||
namespace mROA.Abstract
|
||||
{
|
||||
public interface IRepresentationModuleProducer : IInjectableModule
|
||||
{
|
||||
IRepresentationModule Produce(int id);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,9 @@
|
||||
namespace mROA.Abstract;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
public interface IRequestExtractor : IInjectableModule
|
||||
namespace mROA.Abstract
|
||||
{
|
||||
public interface IRequestExtractor : IInjectableModule
|
||||
{
|
||||
Task StartExtraction();
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,12 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using mROA.Implementation;
|
||||
using mROA.Implementation.CommandExecution;
|
||||
|
||||
namespace mROA.Abstract;
|
||||
|
||||
public interface ISerialisationModule : IInjectableModule
|
||||
namespace mROA.Abstract
|
||||
{
|
||||
public interface ISerialisationModule : IInjectableModule
|
||||
{
|
||||
void HandleIncomingRequest(int clientId, byte[] message);
|
||||
void PostResponse(NetworkMessage message, int clientId);
|
||||
void SendWelcomeMessage(int clientId);
|
||||
@@ -15,10 +17,10 @@ public interface ISerialisationModule : IInjectableModule
|
||||
Task<FinalCommandExecution<T>> GetFinalCommandExecution<T>(Guid requestId);
|
||||
void PostCallRequest(ICallRequest callRequest);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public interface IRepresentationModule : IInjectableModule
|
||||
{
|
||||
public interface IRepresentationModule : IInjectableModule
|
||||
{
|
||||
int Id { get; }
|
||||
Task<T> GetMessageAsync<T>(Guid? requestId = null, MessageType? messageType = null);
|
||||
T GetMessage<T>(Guid? requestId = null, MessageType? messageType = null);
|
||||
@@ -28,4 +30,5 @@ public interface IRepresentationModule : IInjectableModule
|
||||
Task PostCallMessageAsync(Guid id, MessageType messageType, object payload, Type payloadType);
|
||||
void PostCallMessage<T>(Guid id, MessageType messageType, T payload) where T : notnull;
|
||||
void PostCallMessage(Guid id, MessageType messageType, object payload, Type payloadType);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,9 @@
|
||||
namespace mROA.Abstract;
|
||||
using System;
|
||||
|
||||
public interface ISerializationToolkit : IInjectableModule
|
||||
namespace mROA.Abstract
|
||||
{
|
||||
public interface ISerializationToolkit : IInjectableModule
|
||||
{
|
||||
byte[] Serialize<T>(T objectToSerialize);
|
||||
byte[] Serialize(object objectToSerialize, Type type);
|
||||
T? Deserialize<T>(byte[] rawData);
|
||||
@@ -11,4 +13,5 @@ public interface ISerializationToolkit : IInjectableModule
|
||||
T Cast<T>(object nonCasted);
|
||||
object Cast(object nonCasted, Type type);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,6 @@
|
||||
namespace mROA.Implementation.Attributes;
|
||||
using System;
|
||||
|
||||
public class SharedObjectInterfaceAttribute : Attribute;
|
||||
namespace mROA.Implementation.Attributes
|
||||
{
|
||||
public class SharedObjectInterfaceAttribute : Attribute { }
|
||||
}
|
||||
@@ -1,3 +1,6 @@
|
||||
namespace mROA.Implementation.Attributes;
|
||||
using System;
|
||||
|
||||
public class SharedObjectSingletonAttribute : Attribute;
|
||||
namespace mROA.Implementation.Attributes
|
||||
{
|
||||
public class SharedObjectSingletonAttribute : Attribute { }
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
using mROA.Abstract;
|
||||
|
||||
namespace mROA.Implementation.Backend;
|
||||
|
||||
public class BackendIdentityGenerator : IIdentityGenerator
|
||||
namespace mROA.Implementation.Backend
|
||||
{
|
||||
public class BackendIdentityGenerator : IIdentityGenerator
|
||||
{
|
||||
private int _currentId;
|
||||
|
||||
public int GetNextIdentity()
|
||||
@@ -14,4 +14,5 @@ public class BackendIdentityGenerator : IIdentityGenerator
|
||||
public void Inject<T>(T dependency)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,13 @@
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Reflection;
|
||||
using mROA.Abstract;
|
||||
using mROA.Implementation.Bootstrap;
|
||||
|
||||
namespace mROA.Implementation.Backend;
|
||||
|
||||
public static class BasicConfigurationExtensions
|
||||
namespace mROA.Implementation.Backend
|
||||
{
|
||||
public static class BasicConfigurationExtensions
|
||||
{
|
||||
public static void UseJsonSerialisation(this FullMixBuilder builder)
|
||||
{
|
||||
builder.Modules.Add(new JsonSerializationToolkit());
|
||||
@@ -34,4 +35,5 @@ public static class BasicConfigurationExtensions
|
||||
{
|
||||
builder.Modules.Add(methodRepository);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,14 @@
|
||||
using System.Reflection;
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using mROA.Abstract;
|
||||
using mROA.Implementation.CommandExecution;
|
||||
|
||||
namespace mROA.Implementation.Backend;
|
||||
|
||||
public class BasicExecutionModule : IExecuteModule
|
||||
namespace mROA.Implementation.Backend
|
||||
{
|
||||
public class BasicExecutionModule : IExecuteModule
|
||||
{
|
||||
private IMethodRepository? _methodRepo;
|
||||
|
||||
public void Inject<T>(T dependency)
|
||||
@@ -45,7 +48,8 @@ public class BasicExecutionModule : IExecuteModule
|
||||
{
|
||||
try
|
||||
{
|
||||
var finalResult = currentCommand.Invoke(context, parameter is null ? [] : [parameter]);
|
||||
var finalResult = currentCommand.Invoke(context, parameter is null ? new object[0] : new[]
|
||||
{ parameter });
|
||||
return new TypedFinalCommandExecution
|
||||
{
|
||||
CommandId = command.CommandId, Result = finalResult,
|
||||
@@ -70,7 +74,8 @@ public class BasicExecutionModule : IExecuteModule
|
||||
var token = tokenSource.Token;
|
||||
try
|
||||
{
|
||||
var result = (Task)currentCommand.Invoke(context, parameter is null ? [token] : [parameter, token])!;
|
||||
var result = (Task)currentCommand.Invoke(context, parameter is null ? new object[] { token } : new[]
|
||||
{ parameter, token })!;
|
||||
|
||||
|
||||
result.Wait(token);
|
||||
@@ -96,7 +101,8 @@ public class BasicExecutionModule : IExecuteModule
|
||||
try
|
||||
{
|
||||
var result =
|
||||
(Task)currentCommand.Invoke(context, parameter is null ? [token] : [parameter, token])!;
|
||||
(Task)currentCommand.Invoke(context, parameter is null ? new object[] { token } : new[]
|
||||
{ parameter, token })!;
|
||||
|
||||
result.Wait(token);
|
||||
|
||||
@@ -118,4 +124,5 @@ public class BasicExecutionModule : IExecuteModule
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,11 @@
|
||||
using mROA.Abstract;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using mROA.Abstract;
|
||||
|
||||
namespace mROA.Implementation.Backend;
|
||||
|
||||
public class ConnectionHub : IConnectionHub
|
||||
namespace mROA.Implementation.Backend
|
||||
{
|
||||
public class ConnectionHub : IConnectionHub
|
||||
{
|
||||
private readonly Dictionary<int, INextGenerationInteractionModule> _connections = new();
|
||||
private ISerializationToolkit? _serializationToolkit;
|
||||
|
||||
@@ -32,4 +34,5 @@ public class ConnectionHub : IConnectionHub
|
||||
_serializationToolkit = serializationToolkit;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,16 @@
|
||||
using System.Collections.Frozen;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using mROA.Abstract;
|
||||
using mROA.Implementation.Attributes;
|
||||
|
||||
namespace mROA.Implementation.Backend;
|
||||
|
||||
public class ContextRepository : IContextRepository
|
||||
namespace mROA.Implementation.Backend
|
||||
{
|
||||
private FrozenDictionary<int, object?>? _singletons;
|
||||
public class ContextRepository : IContextRepository
|
||||
{
|
||||
private Dictionary<int, object?>? _singletons;
|
||||
private object?[] _storage = new object[StartupSize];
|
||||
|
||||
private Task<int> _lastIndexFinder = Task.FromResult(0);
|
||||
@@ -22,7 +25,7 @@ public class ContextRepository : IContextRepository
|
||||
type is { IsClass: true, IsAbstract: false, IsGenericType: false } &&
|
||||
type.GetCustomAttributes(typeof(SharedObjectSingletonAttribute), true).Length > 0);
|
||||
_singletons =
|
||||
types.ToFrozenDictionary(
|
||||
types.ToDictionary(
|
||||
t => t.GetInterfaces().FirstOrDefault(i =>
|
||||
i.GetCustomAttributes(typeof(SharedObjectInterfaceAttribute), true).Length > 0)!.GetHashCode(),
|
||||
Activator.CreateInstance);
|
||||
@@ -85,4 +88,5 @@ public class ContextRepository : IContextRepository
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,22 @@
|
||||
using System;
|
||||
using mROA.Abstract;
|
||||
|
||||
namespace mROA.Implementation.Backend;
|
||||
|
||||
public class HubRequestExtractor(Type extractoType) : IInjectableModule
|
||||
namespace mROA.Implementation.Backend
|
||||
{
|
||||
public class HubRequestExtractor : IInjectableModule
|
||||
{
|
||||
private IConnectionHub? _hub;
|
||||
|
||||
private IContextRepository? _contextRepository;
|
||||
private IMethodRepository? _methodRepository;
|
||||
private ISerializationToolkit? _serializationToolkit;
|
||||
private IExecuteModule? _executeModule;
|
||||
private readonly Type _extractorType;
|
||||
|
||||
public HubRequestExtractor(Type extractorType)
|
||||
{
|
||||
_extractorType = extractorType;
|
||||
}
|
||||
|
||||
public void Inject<T>(T dependency)
|
||||
{
|
||||
@@ -36,7 +43,7 @@ public class HubRequestExtractor(Type extractoType) : IInjectableModule
|
||||
|
||||
private void HubOnOnConnected(IRepresentationModule interaction)
|
||||
{
|
||||
var extractor = (IRequestExtractor)Activator.CreateInstance(extractoType)!;
|
||||
var extractor = (IRequestExtractor)Activator.CreateInstance(_extractorType)!;
|
||||
extractor.Inject(interaction);
|
||||
if (_contextRepository is IContextRepositoryHub contextHub)
|
||||
extractor.Inject(contextHub.GetRepository(interaction.Id));
|
||||
@@ -47,4 +54,5 @@ public class HubRequestExtractor(Type extractoType) : IInjectableModule
|
||||
extractor.Inject(_executeModule);
|
||||
_ = extractor.StartExtraction();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,25 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using mROA.Abstract;
|
||||
|
||||
namespace mROA.Implementation.Backend;
|
||||
|
||||
public class MultiClientContextRepository(Func<int, IContextRepository> produceRepository) : IContextRepository, IContextRepositoryHub
|
||||
namespace mROA.Implementation.Backend
|
||||
{
|
||||
public class MultiClientContextRepository : IContextRepository, IContextRepositoryHub
|
||||
{
|
||||
private Dictionary<int, IContextRepository> _repositories = new();
|
||||
private readonly Func<int, IContextRepository> _produceRepository;
|
||||
|
||||
public MultiClientContextRepository(Func<int, IContextRepository> produceRepository)
|
||||
{
|
||||
_produceRepository = produceRepository;
|
||||
}
|
||||
|
||||
private IContextRepository GetRepositoryByClientId(int clientId)
|
||||
{
|
||||
if (_repositories.TryGetValue(clientId, out var repository))
|
||||
return repository;
|
||||
|
||||
var created = produceRepository(clientId);
|
||||
var created = _produceRepository(clientId);
|
||||
_repositories.Add(clientId, created);
|
||||
return created;
|
||||
}
|
||||
@@ -53,4 +61,5 @@ public class MultiClientContextRepository(Func<int, IContextRepository> produceR
|
||||
{
|
||||
return GetRepositoryByClientId(clientId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,11 @@
|
||||
using mROA.Abstract;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using mROA.Abstract;
|
||||
|
||||
namespace mROA.Implementation.Backend;
|
||||
|
||||
public class MultiClientOwnershipRepository : IOwnershipRepository
|
||||
namespace mROA.Implementation.Backend
|
||||
{
|
||||
public class MultiClientOwnershipRepository : IOwnershipRepository
|
||||
{
|
||||
private Dictionary<int, int> _ownerships = new();
|
||||
|
||||
public int GetOwnershipId()
|
||||
@@ -25,4 +27,5 @@ public class MultiClientOwnershipRepository : IOwnershipRepository
|
||||
{
|
||||
_ownerships.Remove(Environment.CurrentManagedThreadId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,13 @@
|
||||
using System.Net;
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Threading.Tasks;
|
||||
using mROA.Abstract;
|
||||
|
||||
namespace mROA.Implementation.Backend;
|
||||
|
||||
public class NetworkGatewayModule : IGatewayModule
|
||||
namespace mROA.Implementation.Backend
|
||||
{
|
||||
public class NetworkGatewayModule : IGatewayModule
|
||||
{
|
||||
private readonly Type? _interactionModuleType;
|
||||
private readonly IInjectableModule[]? _injectableModules;
|
||||
private readonly TcpListener _tcpListener;
|
||||
@@ -40,7 +42,6 @@ public class NetworkGatewayModule : IGatewayModule
|
||||
public void Dispose()
|
||||
{
|
||||
_tcpListener.Stop();
|
||||
_tcpListener.Dispose();
|
||||
}
|
||||
|
||||
private void HandleIncomingConnections()
|
||||
@@ -86,4 +87,5 @@ public class NetworkGatewayModule : IGatewayModule
|
||||
if (dependency is ISerializationToolkit serializationToolkit)
|
||||
_serialization = serializationToolkit;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,12 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using mROA.Abstract;
|
||||
|
||||
namespace mROA.Implementation.Bootstrap;
|
||||
|
||||
public class FullMixBuilder
|
||||
namespace mROA.Implementation.Bootstrap
|
||||
{
|
||||
public List<IInjectableModule> Modules { get; } = [];
|
||||
public class FullMixBuilder
|
||||
{
|
||||
public List<IInjectableModule> Modules { get; } = new() { };
|
||||
|
||||
public void Build()
|
||||
{
|
||||
@@ -17,4 +19,5 @@ public class FullMixBuilder
|
||||
{
|
||||
return Modules.OfType<T>().FirstOrDefault();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,24 +1,26 @@
|
||||
using System.Text.Json.Serialization;
|
||||
using System;
|
||||
using System.Text.Json.Serialization;
|
||||
// ReSharper disable UnusedAutoPropertyAccessor.Global
|
||||
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
|
||||
|
||||
namespace mROA.Implementation;
|
||||
|
||||
public interface ICallRequest
|
||||
namespace mROA.Implementation
|
||||
{
|
||||
public interface ICallRequest
|
||||
{
|
||||
Guid Id { get; }
|
||||
int CommandId { get; }
|
||||
int ObjectId { get; }
|
||||
object? Parameter { get; }
|
||||
}
|
||||
}
|
||||
|
||||
public class DefaultCallRequest : ICallRequest
|
||||
{
|
||||
public class DefaultCallRequest : ICallRequest
|
||||
{
|
||||
public Guid Id { get; set; } = Guid.NewGuid();
|
||||
public int CommandId { get; init; }
|
||||
public int ObjectId { get; init; } = -1;
|
||||
public int CommandId { get; set; }
|
||||
public int ObjectId { get; set; } = -1;
|
||||
|
||||
[JsonIgnore]
|
||||
public Type? ParameterType { get; init; }
|
||||
public Type? ParameterType { get; set; }
|
||||
public object? Parameter { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,19 @@
|
||||
using mROA.Abstract;
|
||||
using System;
|
||||
using mROA.Abstract;
|
||||
using mROA.Implementation.Frontend;
|
||||
|
||||
namespace mROA.Implementation.CommandExecution;
|
||||
|
||||
public class ExceptionCommandExecution : ICommandExecution
|
||||
namespace mROA.Implementation.CommandExecution
|
||||
{
|
||||
public Guid Id { get; init; }
|
||||
public class ExceptionCommandExecution : ICommandExecution
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public int ClientId { get; set; }
|
||||
public int CommandId { get; init; }
|
||||
public required string Exception { get; set; }
|
||||
public int CommandId { get; set; }
|
||||
public string Exception { get; set; }
|
||||
|
||||
public RemoteException GetException()
|
||||
{
|
||||
return new RemoteException(Exception) { CallRequestId = Id };
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,20 +1,22 @@
|
||||
using System.Text.Json.Serialization;
|
||||
using System;
|
||||
using System.Text.Json.Serialization;
|
||||
using mROA.Abstract;
|
||||
|
||||
// ReSharper disable UnusedAutoPropertyAccessor.Global
|
||||
|
||||
namespace mROA.Implementation.CommandExecution;
|
||||
|
||||
public class FinalCommandExecution : ICommandExecution
|
||||
namespace mROA.Implementation.CommandExecution
|
||||
{
|
||||
public Guid Id { get; init; }
|
||||
public class FinalCommandExecution : ICommandExecution
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
[JsonIgnore]
|
||||
public int ClientId { get; set; }
|
||||
[JsonIgnore]
|
||||
public int CommandId { get; init; }
|
||||
}
|
||||
public int CommandId { get; set; }
|
||||
}
|
||||
|
||||
public class FinalCommandExecution<T> : FinalCommandExecution
|
||||
{
|
||||
public T? Result { get; init; }
|
||||
public class FinalCommandExecution<T> : FinalCommandExecution
|
||||
{
|
||||
public T? Result { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,12 @@
|
||||
using System.Text.Json.Serialization;
|
||||
using System;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace mROA.Implementation.CommandExecution;
|
||||
|
||||
public class TypedFinalCommandExecution : FinalCommandExecution<object>
|
||||
namespace mROA.Implementation.CommandExecution
|
||||
{
|
||||
public class TypedFinalCommandExecution : FinalCommandExecution<object>
|
||||
{
|
||||
[JsonIgnore]
|
||||
// ReSharper disable once UnusedAutoPropertyAccessor.Global
|
||||
public Type? Type { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,10 @@
|
||||
using mROA.Abstract;
|
||||
using System;
|
||||
using mROA.Abstract;
|
||||
|
||||
namespace mROA.Implementation;
|
||||
|
||||
public class CreativeRepresentationModuleProducer : IRepresentationModuleProducer
|
||||
namespace mROA.Implementation
|
||||
{
|
||||
public class CreativeRepresentationModuleProducer : IRepresentationModuleProducer
|
||||
{
|
||||
private Type _reprModuleType;
|
||||
private IInjectableModule[] _creationModules;
|
||||
private IConnectionHub? _hub;
|
||||
@@ -37,4 +38,5 @@ public class CreativeRepresentationModuleProducer : IRepresentationModuleProduce
|
||||
|
||||
return produced;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
namespace mROA.Implementation.Frontend;
|
||||
using System;
|
||||
|
||||
// public class JsonFrontendSerialisationModule
|
||||
namespace mROA.Implementation.Frontend
|
||||
{
|
||||
// public class JsonFrontendSerialisationModule
|
||||
// : ISerialisationModule.IFrontendSerialisationModule
|
||||
// {
|
||||
// private IInteractionModule.IFrontendInteractionModule? _interactionModule;
|
||||
@@ -77,8 +79,16 @@ namespace mROA.Implementation.Frontend;
|
||||
// }
|
||||
// }
|
||||
|
||||
public class RemoteException(string error) : Exception
|
||||
{
|
||||
public class RemoteException : Exception
|
||||
{
|
||||
public Guid CallRequestId;
|
||||
public override string Message => $"Error in request {CallRequestId} : {error}";
|
||||
private readonly string _error;
|
||||
|
||||
public RemoteException(string error)
|
||||
{
|
||||
_error = error;
|
||||
}
|
||||
|
||||
public override string Message => $"Error in request {CallRequestId} : {_error}";
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,21 @@
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using mROA.Abstract;
|
||||
|
||||
namespace mROA.Implementation.Frontend;
|
||||
|
||||
public class NetworkFrontendBridge(IPEndPoint ipEndPoint) : IFrontendBridge
|
||||
namespace mROA.Implementation.Frontend
|
||||
{
|
||||
public class NetworkFrontendBridge : IFrontendBridge
|
||||
{
|
||||
private readonly TcpClient _tcpClient = new();
|
||||
private NextGenerationInteractionModule? _interactionModule;
|
||||
private ISerializationToolkit? _serialization;
|
||||
private readonly IPEndPoint _ipEndPoint;
|
||||
|
||||
public NetworkFrontendBridge(IPEndPoint ipEndPoint)
|
||||
{
|
||||
_ipEndPoint = ipEndPoint;
|
||||
}
|
||||
|
||||
public void Inject<T>(T dependency)
|
||||
{
|
||||
@@ -30,7 +37,7 @@ public class NetworkFrontendBridge(IPEndPoint ipEndPoint) : IFrontendBridge
|
||||
if (_serialization == null)
|
||||
throw new NullReferenceException("Serialization toolkit is not initialized");
|
||||
|
||||
_tcpClient.Connect(ipEndPoint);
|
||||
_tcpClient.Connect(_ipEndPoint);
|
||||
_interactionModule.BaseStream = _tcpClient.GetStream();
|
||||
var welcomeMessage = _interactionModule.GetNextMessageReceiving().GetAwaiter().GetResult();
|
||||
if (welcomeMessage.SchemaId != MessageType.IdAssigning)
|
||||
@@ -40,4 +47,5 @@ public class NetworkFrontendBridge(IPEndPoint ipEndPoint) : IFrontendBridge
|
||||
|
||||
TransmissionConfig.OwnershipRepository = new StaticOwnershipRepository(_serialization.Deserialize<IdAssingnment>(welcomeMessage.Data)!.Id);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,16 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using mROA.Abstract;
|
||||
using mROA.Implementation.Backend;
|
||||
using mROA.Implementation.CommandExecution;
|
||||
|
||||
// ReSharper disable MethodHasAsyncOverload
|
||||
|
||||
namespace mROA.Implementation.Frontend;
|
||||
|
||||
public class RequestExtractor : IRequestExtractor
|
||||
namespace mROA.Implementation.Frontend
|
||||
{
|
||||
public class RequestExtractor : IRequestExtractor
|
||||
{
|
||||
private IRepresentationModule? _representationModule;
|
||||
private IContextRepository? _contextRepository;
|
||||
private IMethodRepository? _methodRepository;
|
||||
@@ -85,4 +88,5 @@ public class RequestExtractor : IRequestExtractor
|
||||
multiClientOwnershipRepository?.RegisterOwnership(_representationModule.Id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,16 +1,24 @@
|
||||
using mROA.Abstract;
|
||||
|
||||
namespace mROA.Implementation.Frontend;
|
||||
|
||||
public class StaticOwnershipRepository(int id) : IOwnershipRepository
|
||||
namespace mROA.Implementation.Frontend
|
||||
{
|
||||
public class StaticOwnershipRepository : IOwnershipRepository
|
||||
{
|
||||
private readonly int _id;
|
||||
|
||||
public StaticOwnershipRepository(int id)
|
||||
{
|
||||
_id = id;
|
||||
}
|
||||
|
||||
public int GetOwnershipId()
|
||||
{
|
||||
return id;
|
||||
return _id;
|
||||
}
|
||||
|
||||
public int GetHostOwnershipId()
|
||||
{
|
||||
return id;
|
||||
return _id;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
namespace mROA.Implementation;
|
||||
|
||||
public class IdAssingnment
|
||||
namespace mROA.Implementation
|
||||
{
|
||||
public class IdAssingnment
|
||||
{
|
||||
public int Id { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,11 @@
|
||||
using System.Text.Json;
|
||||
using System;
|
||||
using System.Text.Json;
|
||||
using mROA.Abstract;
|
||||
|
||||
namespace mROA.Implementation;
|
||||
|
||||
public class JsonSerializationToolkit : ISerializationToolkit
|
||||
namespace mROA.Implementation
|
||||
{
|
||||
public class JsonSerializationToolkit : ISerializationToolkit
|
||||
{
|
||||
public byte[] Serialize<T>(T objectToSerialize)
|
||||
{
|
||||
return JsonSerializer.SerializeToUtf8Bytes(objectToSerialize);
|
||||
@@ -56,4 +57,5 @@ public class JsonSerializationToolkit : ISerializationToolkit
|
||||
public void Inject<T>(T dependency)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,15 @@
|
||||
using System.Reflection;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using mROA.Abstract;
|
||||
using mROA.Implementation.Attributes;
|
||||
|
||||
namespace mROA.Implementation;
|
||||
|
||||
public class MethodRepository : IMethodRepository
|
||||
namespace mROA.Implementation
|
||||
{
|
||||
private readonly List<MethodInfo> _methods = [];
|
||||
public class MethodRepository : IMethodRepository
|
||||
{
|
||||
private readonly List<MethodInfo> _methods = new() { };
|
||||
|
||||
public MethodInfo GetMethod(int id)
|
||||
{
|
||||
@@ -40,4 +43,5 @@ public class MethodRepository : IMethodRepository
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,18 +1,20 @@
|
||||
using System.Text.Json.Serialization;
|
||||
using System;
|
||||
using System.Text.Json.Serialization;
|
||||
// ReSharper disable UnusedMember.Global
|
||||
|
||||
namespace mROA.Implementation;
|
||||
|
||||
public class NetworkMessage
|
||||
namespace mROA.Implementation
|
||||
{
|
||||
public Guid Id { get; init; }
|
||||
public class NetworkMessage
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
[JsonConverter(typeof(JsonStringEnumConverter))]
|
||||
public MessageType SchemaId { get; init; }
|
||||
public MessageType SchemaId { get; set; }
|
||||
|
||||
public required byte[] Data { get; init; }
|
||||
}
|
||||
public byte[] Data { get; set; }
|
||||
}
|
||||
|
||||
public enum MessageType
|
||||
{
|
||||
public enum MessageType
|
||||
{
|
||||
Unknown, FinishedCommandExecution, ExceptionCommandExecution, AsyncCancelCommandExecution, CallRequest, IdAssigning
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,14 @@
|
||||
using mROA.Abstract;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using mROA.Abstract;
|
||||
|
||||
namespace mROA.Implementation;
|
||||
|
||||
public class NextGenerationInteractionModule : INextGenerationInteractionModule
|
||||
namespace mROA.Implementation
|
||||
{
|
||||
public class NextGenerationInteractionModule : INextGenerationInteractionModule
|
||||
{
|
||||
private ISerializationToolkit? _serialization;
|
||||
public int ConnectionId { get; private set; }
|
||||
public Stream? BaseStream { get; set; }
|
||||
@@ -26,7 +31,6 @@ public class NextGenerationInteractionModule : INextGenerationInteractionModule
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public Task<NetworkMessage> GetNextMessageReceiving()
|
||||
{
|
||||
if (_currentReceiving != null) return _currentReceiving;
|
||||
@@ -62,7 +66,7 @@ public class NextGenerationInteractionModule : INextGenerationInteractionModule
|
||||
return _messageBuffer.FirstOrDefault(m => predicate(m));
|
||||
}
|
||||
|
||||
private NetworkMessage GetNextMessage()
|
||||
private async Task<NetworkMessage> GetNextMessage()
|
||||
{
|
||||
if (BaseStream == null)
|
||||
throw new NullReferenceException("BaseStream is null");
|
||||
@@ -72,16 +76,20 @@ public class NextGenerationInteractionModule : INextGenerationInteractionModule
|
||||
|
||||
|
||||
// Console.WriteLine("Receiving message");
|
||||
var len = BitConverter.ToUInt16([(byte)BaseStream.ReadByte(), (byte)BaseStream.ReadByte()]);
|
||||
var localSpan = _buffer.Span.Slice(0, len);
|
||||
BaseStream.ReadExactly(localSpan);
|
||||
var firstBit = (byte)BaseStream.ReadByte();
|
||||
var secondBit = (byte)BaseStream.ReadByte();
|
||||
|
||||
var len = BitConverter.ToUInt16(new[] { firstBit, secondBit});
|
||||
var localSpan = _buffer.Slice(0, len);
|
||||
await BaseStream.ReadExactlyAsync(localSpan);
|
||||
|
||||
// Console.WriteLine("Receiving {0}", Encoding.Default.GetString(_buffer[..len]));
|
||||
|
||||
var message = _serialization.Deserialize<NetworkMessage>(localSpan);
|
||||
var message = _serialization.Deserialize<NetworkMessage>(localSpan.Span);
|
||||
_messageBuffer.Add(message!);
|
||||
_currentReceiving = Task.Run(GetNextMessage);
|
||||
_currentReceiving = GetNextMessage();
|
||||
|
||||
return message!;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,13 @@
|
||||
using System.Collections.Frozen;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using mROA.Abstract;
|
||||
|
||||
namespace mROA.Implementation;
|
||||
|
||||
public class RemoteContextRepository : IContextRepository
|
||||
namespace mROA.Implementation
|
||||
{
|
||||
public class RemoteContextRepository : IContextRepository
|
||||
{
|
||||
private IRepresentationModuleProducer? _representationProducer;
|
||||
public static FrozenDictionary<Type, Type> RemoteTypes = FrozenDictionary<Type, Type>.Empty;
|
||||
public static Dictionary<Type, Type> RemoteTypes = new();
|
||||
public int ResisterObject(object o)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
@@ -54,4 +55,5 @@ public class RemoteContextRepository : IContextRepository
|
||||
if (dependency is IRepresentationModuleProducer serialisationModule)
|
||||
_representationProducer = serialisationModule;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,26 +1,36 @@
|
||||
using mROA.Abstract;
|
||||
using System.Threading.Tasks;
|
||||
using mROA.Abstract;
|
||||
using mROA.Implementation.CommandExecution;
|
||||
|
||||
// ReSharper disable UnusedMember.Global
|
||||
|
||||
namespace mROA.Implementation;
|
||||
|
||||
public abstract class RemoteObjectBase(int id, IRepresentationModule representationModule)
|
||||
namespace mROA.Implementation
|
||||
{
|
||||
public int Id => id;
|
||||
public int OwnerId => representationModule.Id;
|
||||
public abstract class RemoteObjectBase
|
||||
{
|
||||
private readonly int _id;
|
||||
private readonly IRepresentationModule _representationModule;
|
||||
|
||||
protected RemoteObjectBase(int id, IRepresentationModule representationModule)
|
||||
{
|
||||
_id = id;
|
||||
_representationModule = representationModule;
|
||||
}
|
||||
|
||||
public int Id => _id;
|
||||
public int OwnerId => _representationModule.Id;
|
||||
|
||||
protected async Task<T> GetResultAsync<T>(int methodId, object? parameter = default)
|
||||
{
|
||||
var request = new DefaultCallRequest
|
||||
{ CommandId = methodId, ObjectId = id, Parameter = parameter, ParameterType = parameter?.GetType() };
|
||||
await representationModule.PostCallMessageAsync(request.Id, MessageType.CallRequest, request);
|
||||
{ CommandId = methodId, ObjectId = _id, Parameter = parameter, ParameterType = parameter?.GetType() };
|
||||
await _representationModule.PostCallMessageAsync(request.Id, MessageType.CallRequest, request);
|
||||
|
||||
var successResponse =
|
||||
representationModule.GetMessageAsync<FinalCommandExecution<T>>(
|
||||
_representationModule.GetMessageAsync<FinalCommandExecution<T>>(
|
||||
messageType: MessageType.FinishedCommandExecution, requestId: request.Id);
|
||||
var errorResponse =
|
||||
representationModule.GetMessageAsync<ExceptionCommandExecution>(
|
||||
_representationModule.GetMessageAsync<ExceptionCommandExecution>(
|
||||
messageType: MessageType.ExceptionCommandExecution, requestId: request.Id);
|
||||
Task.WaitAny(successResponse, errorResponse);
|
||||
|
||||
@@ -33,14 +43,14 @@ public abstract class RemoteObjectBase(int id, IRepresentationModule representat
|
||||
protected async Task CallAsync(int methodId, object? parameter = default)
|
||||
{
|
||||
var request = new DefaultCallRequest
|
||||
{ CommandId = methodId, ObjectId = id, Parameter = parameter, ParameterType = parameter?.GetType() };
|
||||
await representationModule.PostCallMessageAsync(request.Id, MessageType.CallRequest, request);
|
||||
{ CommandId = methodId, ObjectId = _id, Parameter = parameter, ParameterType = parameter?.GetType() };
|
||||
await _representationModule.PostCallMessageAsync(request.Id, MessageType.CallRequest, request);
|
||||
|
||||
var successResponse =
|
||||
representationModule.GetMessageAsync<FinalCommandExecution>(
|
||||
_representationModule.GetMessageAsync<FinalCommandExecution>(
|
||||
messageType: MessageType.FinishedCommandExecution, requestId: request.Id);
|
||||
var errorResponse =
|
||||
representationModule.GetMessageAsync<ExceptionCommandExecution>(
|
||||
_representationModule.GetMessageAsync<ExceptionCommandExecution>(
|
||||
messageType: MessageType.ExceptionCommandExecution, requestId: request.Id);
|
||||
|
||||
Task.WaitAny(successResponse, errorResponse);
|
||||
@@ -50,4 +60,5 @@ public abstract class RemoteObjectBase(int id, IRepresentationModule representat
|
||||
|
||||
throw errorResponse.Result.GetException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,11 @@
|
||||
using mROA.Abstract;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using mROA.Abstract;
|
||||
|
||||
namespace mROA.Implementation;
|
||||
|
||||
public class RepresentationModule : IRepresentationModule
|
||||
namespace mROA.Implementation
|
||||
{
|
||||
public class RepresentationModule : IRepresentationModule
|
||||
{
|
||||
private ISerializationToolkit? _serialization;
|
||||
private INextGenerationInteractionModule? _interaction;
|
||||
|
||||
@@ -90,4 +92,5 @@ public class RepresentationModule : IRepresentationModule
|
||||
{
|
||||
PostCallMessageAsync(id, messageType, payload, payloadType).GetAwaiter().GetResult();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,13 @@
|
||||
using System.Text.Json.Serialization;
|
||||
using System;
|
||||
using System.Text.Json.Serialization;
|
||||
using mROA.Abstract;
|
||||
// ReSharper disable UnusedMember.Global
|
||||
#pragma warning disable CS8618, CS9264
|
||||
|
||||
namespace mROA.Implementation;
|
||||
|
||||
public static class TransmissionConfig
|
||||
namespace mROA.Implementation
|
||||
{
|
||||
public static class TransmissionConfig
|
||||
{
|
||||
private static IContextRepository? _realContextRepository;
|
||||
private static IContextRepository? _remoteEndpointContextRepository;
|
||||
private static IOwnershipRepository? _ownershipRepository;
|
||||
@@ -29,10 +30,10 @@ public static class TransmissionConfig
|
||||
set => _ownershipRepository = value;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public class SharedObject<T> where T : notnull
|
||||
{
|
||||
public class SharedObject<T> where T : notnull
|
||||
{
|
||||
private IContextRepository GetDefaultContextRepository() =>
|
||||
(OwnerId == TransmissionConfig.OwnershipRepository.GetHostOwnershipId()
|
||||
? TransmissionConfig.RealContextRepository
|
||||
@@ -50,7 +51,7 @@ public class SharedObject<T> where T : notnull
|
||||
_ownerId = _ownerId == -1 ? TransmissionConfig.OwnershipRepository.GetOwnershipId() : _ownerId;
|
||||
return _ownerId;
|
||||
}
|
||||
init => _ownerId = value;
|
||||
set => _ownerId = value;
|
||||
}
|
||||
|
||||
// ReSharper disable once MemberCanBePrivate.Global
|
||||
@@ -65,14 +66,14 @@ public class SharedObject<T> where T : notnull
|
||||
_contextId = TransmissionConfig.RealContextRepository.GetObjectIndex(Value);
|
||||
return _contextId;
|
||||
}
|
||||
init
|
||||
set
|
||||
{
|
||||
_contextId = value;
|
||||
Value = GetDefaultContextRepository().GetObject<T>(_contextId)!;
|
||||
}
|
||||
}
|
||||
|
||||
[JsonIgnore] public T Value { get; private init; }
|
||||
[JsonIgnore] public T Value { get; private set; }
|
||||
|
||||
// ReSharper disable once MemberCanBePrivate.Global
|
||||
// ReSharper disable once UnusedMember.Global
|
||||
@@ -98,4 +99,5 @@ public class SharedObject<T> where T : notnull
|
||||
|
||||
public static implicit operator SharedObject<T>(T value) =>
|
||||
new(value);
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,10 @@
|
||||
using mROA.Abstract;
|
||||
using System;
|
||||
using mROA.Abstract;
|
||||
|
||||
namespace mROA.Implementation;
|
||||
|
||||
public class StaticRepresentationModuleProducer : IRepresentationModuleProducer
|
||||
namespace mROA.Implementation
|
||||
{
|
||||
public class StaticRepresentationModuleProducer : IRepresentationModuleProducer
|
||||
{
|
||||
private IRepresentationModule? _representationModule;
|
||||
|
||||
public IRepresentationModule Produce(int ownership)
|
||||
@@ -18,4 +19,5 @@ public class StaticRepresentationModuleProducer : IRepresentationModuleProducer
|
||||
if (dependency is IRepresentationModule serialisationModule)
|
||||
_representationModule = serialisationModule;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
using System.Collections.Generic;
|
||||
using global::System;
|
||||
using global::System.IO;
|
||||
using global::System.Threading;
|
||||
using global::System.Threading.Tasks;
|
||||
|
||||
namespace mROA
|
||||
{
|
||||
public static class LegacyExtentions
|
||||
{
|
||||
public static async ValueTask<int> ReadExactlyAsync(this Stream stream, byte[] buffer, int offset, int count)
|
||||
{
|
||||
return await stream.ReadAtLeastAsyncCore(buffer.AsMemory(offset, count), count, true, default);
|
||||
}
|
||||
|
||||
public static ValueTask<int> ReadExactlyAsync(this Stream stream, Memory<byte> buffer,
|
||||
CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
return stream.ReadAtLeastAsyncCore(buffer, buffer.Length, true, cancellationToken);
|
||||
}
|
||||
|
||||
private static async ValueTask<int> ReadAtLeastAsyncCore(this Stream stream,
|
||||
Memory<byte> buffer,
|
||||
int minimumBytes,
|
||||
bool throwOnEndOfStream,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
int totalRead;
|
||||
int num;
|
||||
for (totalRead = 0; totalRead < minimumBytes; totalRead += num)
|
||||
{
|
||||
num = await stream.ReadAsync(buffer.Slice(totalRead), cancellationToken).ConfigureAwait(false);
|
||||
if (num == 0)
|
||||
{
|
||||
if (throwOnEndOfStream)
|
||||
throw new EndOfStreamException();
|
||||
return totalRead;
|
||||
}
|
||||
}
|
||||
return totalRead;
|
||||
}
|
||||
}
|
||||
}
|
||||
+6
-2
@@ -1,8 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<Title>mROA</Title>
|
||||
<Version>2.0.0</Version>
|
||||
@@ -12,6 +11,11 @@
|
||||
<PackageProjectUrl>https://github.com/YaslePoy/mROA</PackageProjectUrl>
|
||||
<RepositoryType>git</RepositoryType>
|
||||
<PackageTags>RPC</PackageTags>
|
||||
<LangVersion>9</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="System.Text.Json" Version="9.0.2" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
Reference in New Issue
Block a user