Files
Ryan e03b7d7516 Updated C# Name attribute to Accessor (#4306)
# Description of Changes

Implementation of #4295

Convert existing `Name` attribute to `Accessor` to support new Canonical
Case conversation of 2.0

# API and ABI breaking changes

Yes, in C# modules, we no longer use the attribute name `Name`, it
should now be `Accessor`

# Expected complexity level and risk

1

# Testing

- [X] Build and tested locally
- [X] Ran regression tests locally
2026-02-17 01:16:16 +00:00

152 lines
4.4 KiB
C#

using SpacetimeDB;
namespace Benchmarks;
public static partial class circles
{
[SpacetimeDB.Type]
public partial struct Vector2(float x, float y)
{
public float x = x;
public float y = y;
}
[SpacetimeDB.Table(Accessor = "entity")]
public partial struct Entity(uint id, float x, float y, uint mass)
{
[AutoInc]
[PrimaryKey]
public uint id = id;
public Vector2 position = new(x, y);
public uint mass = mass;
}
[SpacetimeDB.Table(Accessor = "circle")]
public partial struct Circle(uint entity_id, uint player_id, float x, float y, float magnitude)
{
[PrimaryKey]
public uint entity_id = entity_id;
[SpacetimeDB.Index.BTree]
public uint player_id = player_id;
public Vector2 direction = new(x, y);
public float magnitude = magnitude;
public Timestamp last_split_time = (Timestamp)DateTimeOffset.UtcNow;
}
[SpacetimeDB.Table(Accessor = "food")]
public partial struct Food(uint entity_id)
{
[PrimaryKey]
public uint entity_id = entity_id;
}
public static float MassToRadius(uint mass)
{
return (float)Math.Sqrt(mass);
}
public static bool IsOverlapping(Entity entity1, Entity entity2)
{
float entity1_radius = MassToRadius(entity1.mass);
float entity2_radius = MassToRadius(entity2.mass);
float distance = (float)
Math.Sqrt(
Math.Pow(entity1.position.x - entity2.position.x, 2)
+ Math.Pow(entity1.position.y - entity2.position.y, 2)
);
return distance < Math.Max(entity1_radius, entity2_radius);
}
[SpacetimeDB.Reducer]
public static void insert_bulk_entity(ReducerContext ctx, uint count)
{
for (uint id = 0; id < count; id++)
{
ctx.Db.entity.Insert(new(0, id, id + 5, id * 5));
}
Log.Info($"INSERT ENTITY: {count}");
}
[SpacetimeDB.Reducer]
public static void insert_bulk_circle(ReducerContext ctx, uint count)
{
for (uint id = 0; id < count; id++)
{
ctx.Db.circle.Insert(new(id, id, id, id + 5, id * 5));
}
Log.Info($"INSERT CIRCLE: {count}");
}
[SpacetimeDB.Reducer]
public static void insert_bulk_food(ReducerContext ctx, uint count)
{
for (uint id = 1; id <= count; id++)
{
ctx.Db.food.Insert(new(id));
}
Log.Info($"INSERT FOOD: {count}");
}
[SpacetimeDB.Reducer]
public static void cross_join_all(ReducerContext ctx, uint expected)
{
uint count = 0;
foreach (Circle circle in ctx.Db.circle.Iter())
{
foreach (Entity entity in ctx.Db.entity.Iter())
{
foreach (Food food in ctx.Db.food.Iter())
{
count++;
}
}
}
Log.Info($"CROSS JOIN ALL: {expected}, processed: {count}");
}
[SpacetimeDB.Reducer]
public static void cross_join_circle_food(ReducerContext ctx, uint expected)
{
uint count = 0;
foreach (Circle circle in ctx.Db.circle.Iter())
{
if (ctx.Db.entity.id.Find(circle.entity_id) is not { } circle_entity)
{
continue;
}
foreach (Food food in ctx.Db.food.Iter())
{
count++;
Entity food_entity =
ctx.Db.entity.id.Find(food.entity_id)
?? throw new Exception($"Entity not found: {food.entity_id}");
Bench.BlackBox(IsOverlapping(circle_entity, food_entity));
}
}
Log.Info($"CROSS JOIN CIRCLE FOOD: {expected}, processed: {count}");
}
[SpacetimeDB.Reducer]
public static void init_game_circles(ReducerContext ctx, uint initial_load)
{
Load load = new(initial_load);
insert_bulk_food(ctx, load.initial_load);
insert_bulk_entity(ctx, load.initial_load);
insert_bulk_circle(ctx, load.small_table);
}
[SpacetimeDB.Reducer]
public static void run_game_circles(ReducerContext ctx, uint initial_load)
{
Load load = new(initial_load);
cross_join_circle_food(ctx, initial_load * load.small_table);
cross_join_all(ctx, initial_load * initial_load * load.small_table);
}
}