Skip to content

Commit 5831494

Browse files
[2.0 Breaking] Sender changes for C# modules (#4143)
# Description of Changes Make `Sender` a method on [Reducer|View|Procedure|Tx]Context in C#. Equivalent changes to #4101. # API and ABI breaking changes API breaking # Expected complexity level and risk 1 # Testing Pure refactor, no additional testing.
1 parent 19a0a85 commit 5831494

29 files changed

Lines changed: 155 additions & 114 deletions

File tree

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

Lines changed: 16 additions & 5 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: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//HintName: FFI.cs
1+
//HintName: FFI.cs
22
// <auto-generated />
33
#nullable enable
44
// The runtime already defines SpacetimeDB.Internal.LocalReadOnly in Runtime\Internal\Module.cs as an empty partial type.
@@ -17,7 +17,6 @@ namespace SpacetimeDB
1717
{
1818
public sealed record ReducerContext : DbContext<Local>, Internal.IReducerContext
1919
{
20-
public readonly Identity Sender;
2120
public readonly ConnectionId? ConnectionId;
2221
public readonly Random Rng;
2322
public readonly Timestamp Timestamp;
@@ -29,6 +28,8 @@ public sealed record ReducerContext : DbContext<Local>, Internal.IReducerContext
2928
// We need this property to be non-static for parity with client SDK.
3029
public Identity Identity => Internal.IReducerContext.GetIdentity();
3130

31+
private readonly Identity _sender;
32+
3233
internal ReducerContext(
3334
Identity identity,
3435
ConnectionId? connectionId,
@@ -37,14 +38,19 @@ internal ReducerContext(
3738
AuthCtx? senderAuth = null
3839
)
3940
{
40-
Sender = identity;
41+
_sender = identity;
4142
ConnectionId = connectionId;
4243
Rng = random;
4344
Timestamp = time;
4445
SenderAuth = senderAuth ?? AuthCtx.BuildFromSystemTables(connectionId, identity);
4546
CounterUuid = 0;
4647
}
4748

49+
/// <summary>
50+
/// The identity of the client that invoked the reducer.
51+
/// </summary>
52+
public Identity Sender() => _sender;
53+
4854
/// <summary>
4955
/// Create a new random <see cref="Uuid"/> `v4` using the built-in RNG.
5056
/// </summary>
@@ -199,13 +205,18 @@ public sealed class Local : global::SpacetimeDB.LocalBase
199205

200206
public sealed record ViewContext : DbContext<Internal.LocalReadOnly>, Internal.IViewContext
201207
{
202-
public Identity Sender { get; }
208+
private readonly Identity _sender;
203209

204210
internal ViewContext(Identity sender, Internal.LocalReadOnly db)
205211
: base(db)
206212
{
207-
Sender = sender;
213+
_sender = sender;
208214
}
215+
216+
/// <summary>
217+
/// The identity of the client that invoked the view.
218+
/// </summary>
219+
public Identity Sender() => _sender;
209220
}
210221

211222
public sealed record AnonymousViewContext

crates/bindings-csharp/Codegen/Module.cs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1737,7 +1737,6 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
17371737
17381738
namespace SpacetimeDB {
17391739
public sealed record ReducerContext : DbContext<Local>, Internal.IReducerContext {
1740-
public readonly Identity Sender;
17411740
public readonly ConnectionId? ConnectionId;
17421741
public readonly Random Rng;
17431742
public readonly Timestamp Timestamp;
@@ -1747,16 +1746,24 @@ public sealed record ReducerContext : DbContext<Local>, Internal.IReducerContext
17471746
// We need this property to be non-static for parity with client SDK.
17481747
public Identity Identity => Internal.IReducerContext.GetIdentity();
17491748
1749+
private readonly Identity _sender;
1750+
17501751
internal ReducerContext(Identity identity, ConnectionId? connectionId, Random random,
17511752
Timestamp time, AuthCtx? senderAuth = null)
17521753
{
1753-
Sender = identity;
1754+
_sender = identity;
17541755
ConnectionId = connectionId;
17551756
Rng = random;
17561757
Timestamp = time;
17571758
SenderAuth = senderAuth ?? AuthCtx.BuildFromSystemTables(connectionId, identity);
17581759
CounterUuid = 0;
17591760
}
1761+
1762+
/// <summary>
1763+
/// The identity of the client that invoked the reducer.
1764+
/// </summary>
1765+
public Identity Sender() => _sender;
1766+
17601767
/// <summary>
17611768
/// Create a new random <see cref="Uuid"/> `v4` using the built-in RNG.
17621769
/// </summary>
@@ -1891,13 +1898,18 @@ public sealed class Local : global::SpacetimeDB.LocalBase {
18911898
18921899
public sealed record ViewContext : DbContext<Internal.LocalReadOnly>, Internal.IViewContext
18931900
{
1894-
public Identity Sender { get; }
1901+
private readonly Identity _sender;
18951902
18961903
internal ViewContext(Identity sender, Internal.LocalReadOnly db)
18971904
: base(db)
18981905
{
1899-
Sender = sender;
1906+
_sender = sender;
19001907
}
1908+
1909+
/// <summary>
1910+
/// The identity of the client that invoked the view.
1911+
/// </summary>
1912+
public Identity Sender() => _sender;
19011913
}
19021914
19031915
public sealed record AnonymousViewContext : DbContext<Internal.LocalReadOnly>, Internal.IAnonymousViewContext

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,16 @@ public sealed class TxContext(
99
Random rng
1010
)
1111
{
12+
private readonly Identity _sender = sender;
13+
1214
public Local Db { get; } = db;
13-
public Identity Sender { get; } = sender;
1415
public ConnectionId? ConnectionId { get; } = connectionId;
1516
public Timestamp Timestamp { get; } = timestamp;
1617
public AuthCtx SenderAuth { get; } = senderAuth;
1718
public Random Rng { get; } = rng;
1819

20+
public Identity Sender() => _sender;
21+
1922
public TxContext WithTimestamp(Timestamp ts) =>
20-
new(Db, Sender, ConnectionId, ts, SenderAuth, Rng);
23+
new(Db, _sender, ConnectionId, ts, SenderAuth, Rng);
2124
}

crates/bindings-csharp/Runtime/ProcedureContext.cs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,11 @@ public abstract class ProcedureContextBase(
1010
Timestamp time
1111
) : Internal.IInternalProcedureContext
1212
{
13+
private readonly Identity _sender = sender;
14+
15+
public Identity Sender() => _sender;
16+
1317
public static Identity Identity => Internal.IProcedureContext.GetIdentity();
14-
public Identity Sender { get; } = sender;
1518
public ConnectionId? ConnectionId { get; } = connectionId;
1619
public Random Rng { get; } = random;
1720
public Timestamp Timestamp { get; private set; } = time;
@@ -47,7 +50,7 @@ public Internal.TxContext EnterTxContext(long timestampMicros)
4750
txContext?.WithTimestamp(timestamp)
4851
?? new Internal.TxContext(
4952
CreateLocal(),
50-
Sender,
53+
_sender,
5154
ConnectionId,
5255
timestamp,
5356
SenderAuth,
@@ -229,8 +232,9 @@ public abstract class ProcedureTxContextBase(Internal.TxContext inner)
229232

230233
internal void Refresh(Internal.TxContext inner) => Inner = inner;
231234

235+
public Identity Sender() => Inner.Sender();
236+
232237
public LocalBase Db => (LocalBase)Inner.Db;
233-
public Identity Sender => Inner.Sender;
234238
public ConnectionId? ConnectionId => Inner.ConnectionId;
235239
public Timestamp Timestamp => Inner.Timestamp;
236240
public AuthCtx SenderAuth => Inner.SenderAuth;

demo/Blackholio/server-csharp/Lib.cs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ public static void Init(ReducerContext ctx)
138138
[Reducer(ReducerKind.ClientConnected)]
139139
public static void Connect(ReducerContext ctx)
140140
{
141-
var player = ctx.Db.logged_out_player.identity.Find(ctx.Sender);
141+
var player = ctx.Db.logged_out_player.identity.Find(ctx.Sender());
142142
if (player != null)
143143
{
144144
ctx.Db.player.Insert(player.Value);
@@ -157,7 +157,7 @@ public static void Connect(ReducerContext ctx)
157157
{
158158
ctx.Db.player.Insert(new Player
159159
{
160-
identity = ctx.Sender,
160+
identity = ctx.Sender(),
161161
name = "",
162162
});
163163
}
@@ -166,7 +166,7 @@ public static void Connect(ReducerContext ctx)
166166
[Reducer(ReducerKind.ClientDisconnected)]
167167
public static void Disconnect(ReducerContext ctx)
168168
{
169-
var player = ctx.Db.player.identity.Find(ctx.Sender) ?? throw new Exception("Player not found");
169+
var player = ctx.Db.player.identity.Find(ctx.Sender()) ?? throw new Exception("Player not found");
170170
foreach (var circle in ctx.Db.circle.player_id.Filter(player.player_id))
171171
{
172172
var entity = ctx.Db.entity.entity_id.Find(circle.entity_id) ?? throw new Exception("Could not find circle");
@@ -183,7 +183,7 @@ public static void Disconnect(ReducerContext ctx)
183183
public static void EnterGame(ReducerContext ctx, string name)
184184
{
185185
Log.Info($"Creating player with name {name}");
186-
var player = ctx.Db.player.identity.Find(ctx.Sender) ?? throw new Exception("Player not found");
186+
var player = ctx.Db.player.identity.Find(ctx.Sender()) ?? throw new Exception("Player not found");
187187
player.name = name;
188188
ctx.Db.player.identity.Update(player);
189189
SpawnPlayerInitialCircle(ctx, player.player_id);
@@ -192,15 +192,15 @@ public static void EnterGame(ReducerContext ctx, string name)
192192
[Reducer]
193193
public static void Respawn(ReducerContext ctx)
194194
{
195-
var player = ctx.Db.player.identity.Find(ctx.Sender) ?? throw new Exception("No such player found");
195+
var player = ctx.Db.player.identity.Find(ctx.Sender()) ?? throw new Exception("No such player found");
196196

197197
SpawnPlayerInitialCircle(ctx, player.player_id);
198198
}
199199

200200
[Reducer]
201201
public static void Suicide(ReducerContext ctx)
202202
{
203-
var player = ctx.Db.player.identity.Find(ctx.Sender) ?? throw new Exception("No such player found");
203+
var player = ctx.Db.player.identity.Find(ctx.Sender()) ?? throw new Exception("No such player found");
204204

205205
foreach (var circle in ctx.Db.circle.player_id.Filter(player.player_id))
206206
{
@@ -246,7 +246,7 @@ public static Entity SpawnCircleAt(ReducerContext ctx, int player_id, int mass,
246246
[Reducer]
247247
public static void UpdatePlayerInput(ReducerContext ctx, DbVector2 direction)
248248
{
249-
var player = ctx.Db.player.identity.Find(ctx.Sender) ?? throw new Exception("Player not found");
249+
var player = ctx.Db.player.identity.Find(ctx.Sender()) ?? throw new Exception("Player not found");
250250
foreach (var c in ctx.Db.circle.player_id.Filter(player.player_id))
251251
{
252252
var circle = c;
@@ -449,7 +449,7 @@ public static void DestroyEntity(ReducerContext ctx, int entityId)
449449
[Reducer]
450450
public static void PlayerSplit(ReducerContext ctx)
451451
{
452-
var player = ctx.Db.player.identity.Find(ctx.Sender) ?? throw new Exception("Sender has no player");
452+
var player = ctx.Db.player.identity.Find(ctx.Sender()) ?? throw new Exception("Sender has no player");
453453
List<Circle> circles = ctx.Db.circle.player_id.Filter(player.player_id).ToList();
454454
var circle_count = circles.Count;
455455
if (circle_count >= MAX_CIRCLES_PER_PLAYER)

docs/docs/00100-intro/00100-getting-started/00400-key-architecture.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -439,7 +439,7 @@ A view can be written in C# like so:
439439
[SpacetimeDB.View(Name = "MyPlayer", Public = true)]
440440
public static Player? MyPlayer(ViewContext ctx)
441441
{
442-
return ctx.Db.Player.Identity.Find(ctx.Sender) as Player;
442+
return ctx.Db.Player.Identity.Find(ctx.Sender()) as Player;
443443
}
444444
```
445445

docs/docs/00100-intro/00300-tutorials/00100-chat-app.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ public static void SetName(ReducerContext ctx, string name)
322322
{
323323
name = ValidateName(name);
324324

325-
if (ctx.Db.User.Identity.Find(ctx.Sender) is User user)
325+
if (ctx.Db.User.Identity.Find(ctx.Sender()) is User user)
326326
{
327327
user.Name = name;
328328
ctx.Db.User.Identity.Update(user);
@@ -411,7 +411,7 @@ public static void SendMessage(ReducerContext ctx, string text)
411411
ctx.Db.Message.Insert(
412412
new Message
413413
{
414-
Sender = ctx.Sender,
414+
Sender = ctx.Sender(),
415415
Text = text,
416416
Sent = ctx.Timestamp,
417417
}
@@ -504,9 +504,9 @@ In `spacetimedb/Lib.cs`, add to the `Module` class:
504504
[Reducer(ReducerKind.ClientConnected)]
505505
public static void ClientConnected(ReducerContext ctx)
506506
{
507-
Log.Info($"Connect {ctx.Sender}");
507+
Log.Info($"Connect {ctx.Sender()}");
508508

509-
if (ctx.Db.User.Identity.Find(ctx.Sender) is User user)
509+
if (ctx.Db.User.Identity.Find(ctx.Sender()) is User user)
510510
{
511511
user.Online = true;
512512
ctx.Db.User.Identity.Update(user);
@@ -517,7 +517,7 @@ public static void ClientConnected(ReducerContext ctx)
517517
new User
518518
{
519519
Name = null,
520-
Identity = ctx.Sender,
520+
Identity = ctx.Sender(),
521521
Online = true,
522522
}
523523
);
@@ -527,7 +527,7 @@ public static void ClientConnected(ReducerContext ctx)
527527
[Reducer(ReducerKind.ClientDisconnected)]
528528
public static void ClientDisconnected(ReducerContext ctx)
529529
{
530-
if (ctx.Db.User.Identity.Find(ctx.Sender) is User user)
530+
if (ctx.Db.User.Identity.Find(ctx.Sender()) is User user)
531531
{
532532
user.Online = false;
533533
ctx.Db.User.Identity.Update(user);

docs/docs/00100-intro/00300-tutorials/00300-unity-tutorial/00300-part-2.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,7 @@ Add this function to the `Module` class in `Lib.cs`:
335335
[Reducer]
336336
public static void Debug(ReducerContext ctx)
337337
{
338-
Log.Info($"This reducer was called by {ctx.Sender}");
338+
Log.Info($"This reducer was called by {ctx.Sender()}");
339339
}
340340
```
341341

@@ -444,7 +444,7 @@ Next let's connect our client to our database. Let's start by modifying our `Deb
444444
[Reducer(ReducerKind.ClientConnected)]
445445
public static void Connect(ReducerContext ctx)
446446
{
447-
Log.Info($"{ctx.Sender} just connected.");
447+
Log.Info($"{ctx.Sender()} just connected.");
448448
}
449449
```
450450

0 commit comments

Comments
 (0)