Skip to content

Commit 201970e

Browse files
authored
[C#] Update module bindings to use new View ABI (#4146)
# Description of Changes This change implements the module bindings changes to Views that where updated with core in #3685 and the Rust module bindings implementation in #3819. Updates the C# module bindings to use new header-first view ABI (`ViewResultHeader`) and updates the return codes for the `__call_view__` and `__call_view_anon__` module exports. This is a prerequsite for `Query` builder support being added to C# modules. # API and ABI breaking changes Not breaking. Existing modules will continue to use the old ABI. New modules will use the new ABI. However previous host versions will not support modules built using this version of the bindings. # Expected complexity level and risk 2 # Testing This is an internal refactor. All existing tests should continue to pass. All existing tests should continue to pass. The only tests that needed updating were the C# codegen snapshot tests (`Codegen.Tests`) because the generated view dispatcher bodies changed (they now prefix `ViewResultHeader.RowData` before the existing row payload).
1 parent cbfc0ba commit 201970e

5 files changed

Lines changed: 93 additions & 2 deletions

File tree

crates/bindings-csharp/Codegen.Tests/fixtures/diag/snapshots/Module#FFI.verified.cs

Lines changed: 30 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/bindings-csharp/Codegen.Tests/fixtures/server/snapshots/Module#FFI.verified.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1162,8 +1162,11 @@ public byte[] Invoke(
11621162
PublicTable.BSATN
11631163
>.GetListSerializer();
11641164
var listValue = ModuleRegistration.ToListOrEmpty(returnValue);
1165+
var header = new global::SpacetimeDB.Internal.ViewResultHeader.RowData(default);
1166+
var headerRW = new global::SpacetimeDB.Internal.ViewResultHeader.BSATN();
11651167
using var output = new System.IO.MemoryStream();
11661168
using var writer = new System.IO.BinaryWriter(output);
1169+
headerRW.Write(writer, header);
11671170
listSerializer.Write(writer, listValue);
11681171
return output.ToArray();
11691172
}
@@ -1208,8 +1211,11 @@ public byte[] Invoke(
12081211
PublicTable.BSATN
12091212
>.GetListSerializer();
12101213
var listValue = ModuleRegistration.ToListOrEmpty(returnValue);
1214+
var header = new global::SpacetimeDB.Internal.ViewResultHeader.RowData(default);
1215+
var headerRW = new global::SpacetimeDB.Internal.ViewResultHeader.BSATN();
12111216
using var output = new System.IO.MemoryStream();
12121217
using var writer = new System.IO.BinaryWriter(output);
1218+
headerRW.Write(writer, header);
12131219
listSerializer.Write(writer, listValue);
12141220
return output.ToArray();
12151221
}

crates/bindings-csharp/Codegen/Module.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1039,15 +1039,21 @@ public string GenerateDispatcherClass(uint index)
10391039
? $$$"""
10401040
var listSerializer = {{{ReturnType.BSATNName}}}.GetListSerializer();
10411041
var listValue = ModuleRegistration.ToListOrEmpty(returnValue);
1042+
var header = new global::SpacetimeDB.Internal.ViewResultHeader.RowData(default);
1043+
var headerRW = new global::SpacetimeDB.Internal.ViewResultHeader.BSATN();
10421044
using var output = new System.IO.MemoryStream();
10431045
using var writer = new System.IO.BinaryWriter(output);
1046+
headerRW.Write(writer, header);
10441047
listSerializer.Write(writer, listValue);
10451048
return output.ToArray();
10461049
"""
10471050
: $$$"""
10481051
{{{ReturnType.BSATNName}}} returnRW = new();
1052+
var header = new global::SpacetimeDB.Internal.ViewResultHeader.RowData(default);
1053+
var headerRW = new global::SpacetimeDB.Internal.ViewResultHeader.BSATN();
10491054
using var output = new System.IO.MemoryStream();
10501055
using var writer = new System.IO.BinaryWriter(output);
1056+
headerRW.Write(writer, header);
10511057
returnRW.Write(writer, returnValue);
10521058
return output.ToArray();
10531059
""";

crates/bindings-csharp/Runtime/Internal/Module.cs

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,30 @@ BytesSink resultSink
366366
}
367367
}
368368

369+
/// <summary>
370+
/// Called by the host to execute a view when the sender calls the view identified by <paramref name="id" />.
371+
/// </summary>
372+
/// <remarks>
373+
/// <para>
374+
/// The sender identity is passed as 4 <see cref="ulong" /> values (<paramref name="sender_0" /> through
375+
/// <paramref name="sender_3" />) representing a little-endian <see cref="SpacetimeDB.Identity" />.
376+
/// </para>
377+
/// <para>
378+
/// <paramref name="args" /> is a host-registered <see cref="BytesSource" /> containing the BSATN-encoded
379+
/// view arguments. For empty arguments, <paramref name="args" /> will be invalid.
380+
/// </para>
381+
/// <para>
382+
/// The view output is written to <paramref name="rows" />, a host-registered <see cref="BytesSink" />.
383+
/// </para>
384+
/// <para>
385+
/// Note: a previous view ABI wrote the return rows directly to the sink.
386+
/// The current ABI writes a BSATN-encoded <see cref="ViewResultHeader" /> first, in order to distinguish
387+
/// between views that return row data and views that return queries.
388+
/// </para>
389+
/// <para>
390+
/// The current ABI is identified by returning error code <c>2</c>.
391+
/// </para>
392+
/// </remarks>
369393
public static Errno __call_view__(
370394
uint id,
371395
ulong sender_0,
@@ -386,7 +410,7 @@ BytesSink rows
386410
using var reader = new BinaryReader(stream);
387411
var bytes = viewDispatchers[(int)id].Invoke(reader, ctx);
388412
rows.Write(bytes);
389-
return Errno.OK;
413+
return (Errno)2;
390414
}
391415
catch (Exception e)
392416
{
@@ -395,6 +419,26 @@ BytesSink rows
395419
}
396420
}
397421

422+
/// <summary>
423+
/// Called by the host to execute an anonymous view.
424+
/// </summary>
425+
/// <remarks>
426+
/// <para>
427+
/// <paramref name="args" /> is a host-registered <see cref="BytesSource" /> containing the BSATN-encoded
428+
/// view arguments. For empty arguments, <paramref name="args" /> will be invalid.
429+
/// </para>
430+
/// <para>
431+
/// The view output is written to <paramref name="rows" />, a host-registered <see cref="BytesSink" />.
432+
/// </para>
433+
/// <para>
434+
/// Note: a previous view ABI wrote the return rows directly to the sink.
435+
/// The current ABI writes a BSATN-encoded <see cref="ViewResultHeader" /> first, in order to distinguish
436+
/// between views that return row data and views that return queries.
437+
/// </para>
438+
/// <para>
439+
/// The current ABI is identified by returning error code <c>2</c>.
440+
/// </para>
441+
/// </remarks>
398442
public static Errno __call_view_anon__(uint id, BytesSource args, BytesSink rows)
399443
{
400444
try
@@ -404,7 +448,7 @@ public static Errno __call_view_anon__(uint id, BytesSource args, BytesSink rows
404448
using var reader = new BinaryReader(stream);
405449
var bytes = anonymousViewDispatchers[(int)id].Invoke(reader, ctx);
406450
rows.Write(bytes);
407-
return Errno.OK;
451+
return (Errno)2;
408452
}
409453
catch (Exception e)
410454
{
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
namespace SpacetimeDB.Internal;
2+
3+
[SpacetimeDB.Type]
4+
public partial record ViewResultHeader
5+
: SpacetimeDB.TaggedEnum<(SpacetimeDB.Unit RowData, string RawSql)>;

0 commit comments

Comments
 (0)