diff --git a/Capnp.Net.Runtime/Capnp.Net.Runtime.csproj b/Capnp.Net.Runtime/Capnp.Net.Runtime.csproj
index 984ff3f..bb63b16 100644
--- a/Capnp.Net.Runtime/Capnp.Net.Runtime.csproj
+++ b/Capnp.Net.Runtime/Capnp.Net.Runtime.csproj
@@ -20,12 +20,13 @@
capnp "Cap'n Proto" RPC serialization cerealization
1.2-local$([System.DateTime]::UtcNow.ToString(yyMMddHHmm))
Debug;Release
+ true
TRACE
-
+
diff --git a/Capnp.Net.Runtime/FramePump.cs b/Capnp.Net.Runtime/FramePump.cs
index c882fd7..fa841cc 100644
--- a/Capnp.Net.Runtime/FramePump.cs
+++ b/Capnp.Net.Runtime/FramePump.cs
@@ -186,6 +186,10 @@ namespace Capnp
}
}
+ ///
+ /// Attaches an observer for tracing RPC traffic
+ ///
+ /// observer implementation
public void AttachTracer(IFrameTracer tracer)
{
_tracers.Add(tracer);
diff --git a/Capnp.Net.Runtime/FrameTracing/IFrameTracer.cs b/Capnp.Net.Runtime/FrameTracing/IFrameTracer.cs
index 115a6f1..3255b29 100644
--- a/Capnp.Net.Runtime/FrameTracing/IFrameTracer.cs
+++ b/Capnp.Net.Runtime/FrameTracing/IFrameTracer.cs
@@ -1,17 +1,33 @@
using System;
-using System.Collections.Generic;
-using System.Text;
namespace Capnp.FrameTracing
{
+ ///
+ /// Send or receive
+ ///
public enum FrameDirection
{
+ ///
+ /// Receive direction
+ ///
Rx,
+
+ ///
+ /// Send direction
+ ///
Tx
}
+ ///
+ /// Client interface for observing RPC traffic
+ ///
public interface IFrameTracer: IDisposable
{
+ ///
+ /// Called whenever an RPC frame was sent or received
+ ///
+ /// frame direction
+ /// actual frame
void TraceFrame(FrameDirection direction, WireFrame frame);
}
}
diff --git a/Capnp.Net.Runtime/FrameTracing/RpcFrameTracer.cs b/Capnp.Net.Runtime/FrameTracing/RpcFrameTracer.cs
index 83e1b50..f2c3ca1 100644
--- a/Capnp.Net.Runtime/FrameTracing/RpcFrameTracer.cs
+++ b/Capnp.Net.Runtime/FrameTracing/RpcFrameTracer.cs
@@ -8,6 +8,9 @@ using System.Threading;
namespace Capnp.FrameTracing
{
+ ///
+ /// Default implementation of an RPC observer
+ ///
public class RpcFrameTracer : IFrameTracer
{
const string Header = "Ticks | Thread | Dir | Message";
@@ -16,12 +19,19 @@ namespace Capnp.FrameTracing
readonly Stopwatch _timer = new Stopwatch();
readonly TextWriter _traceWriter;
+ ///
+ /// Constructs an instance
+ ///
+ /// textual logging target
public RpcFrameTracer(TextWriter traceWriter)
{
_traceWriter = traceWriter ?? throw new ArgumentNullException(nameof(traceWriter));
_traceWriter.WriteLine(Header);
}
+ ///
+ /// Dispose pattern implementation
+ ///
public void Dispose()
{
_traceWriter.WriteLine("");
@@ -91,6 +101,11 @@ namespace Capnp.FrameTracing
}
}
+ ///
+ /// Processes a sent or received RPC frame
+ ///
+ /// frame direction
+ /// actual frame
public void TraceFrame(FrameDirection dir, WireFrame frame)
{
if (!_timer.IsRunning)
diff --git a/Capnp.Net.Runtime/Rpc/BareProxy.cs b/Capnp.Net.Runtime/Rpc/BareProxy.cs
index db68fc4..50d993d 100644
--- a/Capnp.Net.Runtime/Rpc/BareProxy.cs
+++ b/Capnp.Net.Runtime/Rpc/BareProxy.cs
@@ -43,7 +43,6 @@
/// Target interface ID
/// Target method ID
/// Method arguments
- /// Whether it is a tail call
/// Answer promise
public IPromisedAnswer Call(ulong interfaceId, ushort methodId, DynamicSerializerState args)
{
diff --git a/Capnp.Net.Runtime/Rpc/Interception/CallContext.cs b/Capnp.Net.Runtime/Rpc/Interception/CallContext.cs
index 67bb1e6..8daaaba 100644
--- a/Capnp.Net.Runtime/Rpc/Interception/CallContext.cs
+++ b/Capnp.Net.Runtime/Rpc/Interception/CallContext.cs
@@ -281,7 +281,6 @@ namespace Capnp.Rpc.Interception
///
/// Forwards this intercepted call to the target capability ("Bob").
///
- /// Optional cancellation token, requesting Bob to cancel the call
public void ForwardToBob()
{
if (Bob == null)
diff --git a/Capnp.Net.Runtime/Rpc/TcpRpcServer.cs b/Capnp.Net.Runtime/Rpc/TcpRpcServer.cs
index 5b9b816..6ac5cb1 100644
--- a/Capnp.Net.Runtime/Rpc/TcpRpcServer.cs
+++ b/Capnp.Net.Runtime/Rpc/TcpRpcServer.cs
@@ -4,16 +4,24 @@ using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
-using System.Text;
using System.Threading;
-using System.Threading.Tasks;
namespace Capnp.Rpc
{
+ ///
+ /// Carries information on RPC connection state changes.
+ ///
public class ConnectionEventArgs: EventArgs
{
+ ///
+ /// Affected connection
+ ///
public IConnection Connection { get; }
+ ///
+ /// Constructs an instance
+ ///
+ /// RPC connection object
public ConnectionEventArgs(IConnection connection)
{
Connection = connection;
diff --git a/CapnpC.CSharp.Generator.Tests/Embedded Resources/test.cs b/CapnpC.CSharp.Generator.Tests/Embedded Resources/test.cs
index 80b2310..84c9f1d 100644
--- a/CapnpC.CSharp.Generator.Tests/Embedded Resources/test.cs
+++ b/CapnpC.CSharp.Generator.Tests/Embedded Resources/test.cs
@@ -9015,7 +9015,7 @@ namespace Capnproto_test.Capnp.Test
where TT : class where TU : class
{
var in_ = CapnpSerializable.Create>(d_);
- return Impatient.MaybeTailCall(Impl.Call(in_.Foo, in_.Bar, cancellationToken_), r_ =>
+ return Impatient.MaybeTailCall(Impl.Call(in_.Foo, in_.Bar, cancellationToken_), r_ =>
{
var s_ = SerializerState.CreateForRpc.WRITER>();
r_.serialize(s_);
@@ -9142,7 +9142,7 @@ namespace Capnproto_test.Capnp.Test
where TT : class where TU : class
{
var in_ = CapnpSerializable.Create.Params_call>(d_);
- return Impatient.MaybeTailCall(Impl.Call(in_.Foo, in_.Bar, cancellationToken_), r_ =>
+ return Impatient.MaybeTailCall(Impl.Call(in_.Foo, in_.Bar, cancellationToken_), r_ =>
{
var s_ = SerializerState.CreateForRpc.WRITER>();
r_.serialize(s_);
diff --git a/CapnpC.CSharp.Generator/CodeGen/InterfaceSnippetGen.cs b/CapnpC.CSharp.Generator/CodeGen/InterfaceSnippetGen.cs
index 0c8b23a..6344b85 100644
--- a/CapnpC.CSharp.Generator/CodeGen/InterfaceSnippetGen.cs
+++ b/CapnpC.CSharp.Generator/CodeGen/InterfaceSnippetGen.cs
@@ -551,11 +551,26 @@ namespace CapnpC.CSharp.Generator.CodeGen
IEnumerable MakeSkeletonMethodBody(Method method)
{
+ SimpleNameSyntax methodName;
+
+ if (method.GenericParameters.Count == 0)
+ {
+ methodName = _names.GetCodeIdentifier(method).IdentifierName;
+ }
+ else
+ {
+ methodName = GenericName(_names.GetCodeIdentifier(method).Identifier)
+ .AddTypeArgumentListArguments(
+ method.GenericParameters.Select(
+ p => _names.GetGenericTypeParameter(p).IdentifierName)
+ .ToArray());
+ }
+
var call = InvocationExpression(
MemberAccessExpression(
SyntaxKind.SimpleMemberAccessExpression,
IdentifierName(SkeletonWorder.ImplName),
- _names.GetCodeIdentifier(method).IdentifierName));
+ methodName));
if (method.Params.Count > 0)
{
diff --git a/MsBuildGenerationTest/Issue33.capnp b/MsBuildGenerationTest/Issue33.capnp
new file mode 100644
index 0000000..155a60b
--- /dev/null
+++ b/MsBuildGenerationTest/Issue33.capnp
@@ -0,0 +1,11 @@
+@0xaa62d76b329585e5;
+
+interface Frobnicator(T)
+{
+ frobnicate @0 (value: T);
+}
+
+interface FrobnicatorFactory
+{
+ createFrobnicator @0 [T] (id: Text) -> (result: Frobnicator(T));
+}