-
Notifications
You must be signed in to change notification settings - Fork 1k
Expand file tree
/
Copy pathcircles.cs
More file actions
151 lines (131 loc) · 4.34 KB
/
circles.cs
File metadata and controls
151 lines (131 loc) · 4.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
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(Name = "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(Name = "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(Name = "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);
}
}