diff --git a/Esiur/Core/AsyncChunk.cs b/Esiur/Core/AsyncChunk.cs deleted file mode 100644 index 6e04fb4..0000000 --- a/Esiur/Core/AsyncChunk.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace Esiur.Core -{ - // This interface is used to provide return type for templates and support chunk callbacks using IAsyncEnumerable feature of C# 8 - public interface IAsyncChunk : IAsyncEnumerable - { - - } -} diff --git a/Esiur/Core/InvocationContext.cs b/Esiur/Core/InvocationContext.cs index 6ad6090..0118f8f 100644 --- a/Esiur/Core/InvocationContext.cs +++ b/Esiur/Core/InvocationContext.cs @@ -9,13 +9,22 @@ namespace Esiur.Core { private uint CallbackId; + internal bool Ended; + public void Chunk(object value) { + if (Ended) + throw new Exception("Execution has ended."); + Connection.SendChunk(CallbackId, value); } - public void Progress(int value) { + public void Progress(int value, int max) { + if (Ended) + throw new Exception("Execution has ended."); + + Connection.SendProgress(CallbackId, value, max); } public DistributedConnection Connection { get; internal set; } diff --git a/Esiur/Net/IIP/DistributedConnectionProtocol.cs b/Esiur/Net/IIP/DistributedConnectionProtocol.cs index 7b76626..e505527 100644 --- a/Esiur/Net/IIP/DistributedConnectionProtocol.cs +++ b/Esiur/Net/IIP/DistributedConnectionProtocol.cs @@ -268,7 +268,7 @@ partial class DistributedConnection .Done(); } - void SendProgress(uint callbackId, int value, int max) + internal void SendProgress(uint callbackId, int value, int max) { SendParams() .AddUInt8((byte)(0xC0 | (byte)IIPPacketReport.ProgressReport)) @@ -279,7 +279,7 @@ partial class DistributedConnection //SendParams(, callbackId, value, max); } - void SendChunk(uint callbackId, object chunk) + internal void SendChunk(uint callbackId, object chunk) { var c = Codec.Compose(chunk, this); SendParams() @@ -353,7 +353,7 @@ partial class DistributedConnection attachedResources.Remove(resourceId); } - + } else if (neededResources.Contains(resourceId)) { @@ -1472,6 +1472,8 @@ partial class DistributedConnection object[] args = new object[pis.Length]; + InvocationContext context = null; + if (pis.Length > 0) { if (pis.Last().ParameterType == typeof(DistributedConnection)) @@ -1480,16 +1482,33 @@ partial class DistributedConnection { if (arguments.ContainsKey(i)) args[i] = DC.CastConvert(arguments[i], pis[i].ParameterType); - else if (ft.Arguments[i].Type.Nullable)// Nullable.GetUnderlyingType(pis[i].ParameterType) != null) + else if (ft.Arguments[i].Type.Nullable) args[i] = null; else args[i] = Type.Missing; } - //args[i] = arguments.ContainsKey(i) ? - // DC.CastConvert(arguments[i], pis[i].ParameterType) : Type.Missing; + args[args.Length - 1] = this; } + else if (pis.Last().ParameterType == typeof(InvocationContext)) + { + context = new InvocationContext(this, callback); + + for (byte i = 0; i < pis.Length - 1; i++) + { + if (arguments.ContainsKey(i)) + args[i] = DC.CastConvert(arguments[i], pis[i].ParameterType); + else if (ft.Arguments[i].Type.Nullable) + args[i] = null; + else + args[i] = Type.Missing; + + } + + args[args.Length - 1] = context; + + } else { for (byte i = 0; i < pis.Length; i++) @@ -1509,6 +1528,7 @@ partial class DistributedConnection try { rt = ft.MethodInfo.Invoke(target, args); + context.Ended = true; } catch (Exception ex) { diff --git a/Esiur/Resource/ExportAttribute.cs b/Esiur/Resource/ExportAttribute.cs index c7fa916..c2a983b 100644 --- a/Esiur/Resource/ExportAttribute.cs +++ b/Esiur/Resource/ExportAttribute.cs @@ -10,7 +10,6 @@ namespace Esiur.Resource; public class ExportAttribute : Attribute { public string Name { get; private set; } = null; - public Type ReturnType { get; private set; } = null; public ExportAttribute() { @@ -22,16 +21,4 @@ public class ExportAttribute : Attribute Name = name; } - public ExportAttribute(Type returnType) - { - ReturnType = returnType; - } - - public ExportAttribute(string name, Type returnType) - { - Name = name; - ReturnType = returnType; - } - - } diff --git a/Esiur/Resource/Template/FunctionTemplate.cs b/Esiur/Resource/Template/FunctionTemplate.cs index 981f6c7..0538eeb 100644 --- a/Esiur/Resource/Template/FunctionTemplate.cs +++ b/Esiur/Resource/Template/FunctionTemplate.cs @@ -91,17 +91,13 @@ public class FunctionTemplate : MemberTemplate else if (genericRtType == typeof(IEnumerable<>) || genericRtType == typeof(IAsyncEnumerable<>)) { // get export - rtType = RepresentationType.FromType(mi.GetCustomAttribute()?.ReturnType ?? typeof(object)); + rtType = RepresentationType.FromType(mi.ReturnType.GetGenericArguments()[0]); } else { rtType = RepresentationType.FromType(mi.ReturnType); } - //var rtType = genericRtType == typeof(AsyncReply<>) ? - // RepresentationType.FromType(mi.ReturnType.GetGenericArguments()[0]) : - // RepresentationType.FromType(mi.ReturnType); - if (rtType == null) throw new Exception($"Unsupported type `{mi.ReturnType}` in method `{type.Name}.{mi.Name}` return");