Compare commits

...
Sign in to create a new pull request.

1 commit

Author SHA1 Message Date
ookami125
551527e81c broken, some test improvements to the syntax 2025-04-07 13:21:41 -04:00
2 changed files with 108 additions and 187 deletions

View file

@ -1,5 +1,6 @@
const std = @import("std");
const spacetime = @import("spacetime.zig");
const utils = @import("spacetime/utils.zig");
comptime { _ = spacetime; }
pub const std_options = std.Options{
@ -7,208 +8,128 @@ pub const std_options = std.Options{
.logFn = spacetime.logFn,
};
pub const DbVector2 = struct {
x: f32,
y: f32,
const TableAttribs = struct {
scheduled: ?[]const u8,
autoinc: ?[]const []const u8,
primary_key: ?[]const u8,
unique: ?[]const []const u8,
};
pub const config: spacetime.Table = .{ .schema = Config, .primary_key = "id", .access = .Public, };
pub const Config = struct {
//#[primary_key]
id: u32,
world_size: u64,
const TableAttribsPair = struct {
schema: type,
attribs: TableAttribs,
};
pub const entity: spacetime.Table = .{ .schema = Entity, .primary_key = "entity_id", .access = .Public };
pub const Entity = struct {
//#[auto_inc]
//#[primary_key]
entity_id: u32,
position: DbVector2,
mass: u32,
};
comptime {
var attributeList: []const TableAttribsPair = &.{};
}
pub const circles: spacetime.Table = .{
.schema = Circle,
.primary_key = "entity_id",
.access = .Public,
.indexes = &.{ .{ .name = "player_id", .layout = .BTree } },
};
pub const Circle = struct {
//#[auto_inc]
//#[primary_key]
entity_id: u32,
//#[index(btree)]
player_id: u32,
direction: DbVector2,
speed: f32,
last_split_time: spacetime.Timestamp,
};
fn removeComptimeFields(data: type) type {
const typeInfo = @typeInfo(data).@"struct";
var newFields: []const std.builtin.Type.StructField = &.{};
pub const players: spacetime.Table = .{
.schema = Player,
.primary_key = "identity",
.access = .Public,
.unique = &.{ "player_id" },
.autoinc = &.{ "player_id" },
};
pub const logged_out_players: spacetime.Table = .{
.schema = Player,
.primary_key = "identity",
.unique = &.{ "player_id" }
};
pub const Player = struct {
//#[primary_key]
identity: spacetime.Identity,
//#[unique]
//#[auto_inc]
player_id: u32,
name: []const u8,
pub fn destroy(self: *@This(), allocator: std.mem.Allocator) void {
allocator.free(self.name);
allocator.destroy(self);
inline for(std.meta.fields(data)) |field| {
if(!field.is_comptime) {
newFields = newFields ++ &[_]std.builtin.Type.StructField{ field };
}
}
};
pub const food: spacetime.Table = .{ .schema = Food, .primary_key = "entity_id", .access = .Public };
pub const Food = struct {
//#[primary_key]
entity_id: u32,
};
return @Type(.{
.@"struct" = std.builtin.Type.Struct{
.backing_integer = typeInfo.backing_integer,
.decls = typeInfo.decls,
.fields = newFields,
.is_tuple = typeInfo.is_tuple,
.layout = typeInfo.layout,
}
});
}
//#[spacetimedb::table(name = spawn_food_timer, scheduled(spawn_food))]
pub const spawn_food_timer: spacetime.Table = .{ .schema = SpawnFoodTimer, .primary_key = "scheduled_id" };
pub const SpawnFoodTimer = struct {
//#[primary_key]
//#[auto_inc]
fn Table(data: type) spacetime.Table {
const fieldIdx = std.meta.fieldIndex(data, "__spacetime_10.0__attribs__");
if(fieldIdx == null) return .{ .schema = data, .schema_name = @typeName(data), };
const attribs: TableAttribs = utils.getMemberDefaultValue(data, "__spacetime_10.0__attribs__");
return .{
.schema = removeComptimeFields(data),
.schema_name = @typeName(data),
.primary_key = attribs.primary_key,
//.schedule_reducer = attribs.scheduled,
.unique = attribs.unique,
.autoinc = attribs.autoinc,
};
}
fn TableSchema(data: TableAttribsPair) type {
const attribs: TableAttribs = data.attribs;
attributeList = attributeList ++ &[1]TableAttribsPair{ data };
var newFields: []const std.builtin.Type.StructField = &.{};
newFields = newFields ++ &[_]std.builtin.Type.StructField{
std.builtin.Type.StructField{
.alignment = @alignOf(TableAttribs),
.default_value = @ptrCast(&attribs),
.is_comptime = false,
.name = "__spacetime_10.0__attribs__",
.type = TableAttribs,
}
};
newFields = newFields ++ std.meta.fields(data.schema);
const newStruct: std.builtin.Type.Struct = .{
.backing_integer = null,
.decls = &[_]std.builtin.Type.Declaration{},
.fields = newFields,
.is_tuple = false,
.layout = .auto
};
return @Type(.{
.@"struct" = newStruct,
});
}
//#[spacetimedb::table(name = move_all_players_timer, scheduled(move_all_players))]
pub const move_all_players_timer = Table(MoveAllPlayersTimer);
pub const MoveAllPlayersTimer = TableSchema(.{
.schema = struct {
scheduled_id: u64,
scheduled_at: spacetime.ScheduleAt,
};
//#[spacetimedb::table(name = circle_decay_timer, scheduled(circle_decay))]
pub const circle_decay_timer: spacetime.Table = .{ .schema = CircleDecayTimer, .primary_key = "scheduled_id" };
pub const CircleDecayTimer = struct {
//#[primary_key]
//#[auto_inc]
scheduled_id: u64,
scheduled_at: spacetime.ScheduleAt,
};
//#[spacetimedb::table(name = circle_recombine_timer, scheduled(circle_recombine))]
pub const circle_recombine_timer: spacetime.Table = .{ .schema = CircleRecombineTimer, .primary_key = "scheduled_id" };
pub const CircleRecombineTimer = struct {
//#[primary_key]
//#[auto_inc]
scheduled_id: u64,
scheduled_at: spacetime.ScheduleAt,
player_id: u32,
};
pub const consume_entity_timer: spacetime.Table = .{ .schema = ConsumeEntityTimer, .primary_key = "scheduled_id" };
pub const ConsumeEntityTimer = struct {
//#[primary_key]
//#[auto_inc]
scheduled_id: u64,
scheduled_at: spacetime.ScheduleAt,
consumed_entity_id: u32,
consumer_entity_id: u32,
};
},
.attribs = TableAttribs{
.scheduled = "move_all_players_reducer",
.autoinc = &.{"scheduled_id"},
.primary_key = "scheduled_id",
.unique = &.{},
}
});
pub const Init: spacetime.Reducer = .{ .func_type = @TypeOf(InitReducer), .func = @ptrCast(&InitReducer), .lifecycle = .Init, };
pub fn InitReducer(ctx: *spacetime.ReducerContext) !void {
std.log.info("Initializing...", .{});
try ctx.db.get("config").insert(Config {
.id = 0,
.world_size = 1000,
});
try ctx.db.get("circle_decay_timer").insert(CircleDecayTimer {
.scheduled_id = 0,
.scheduled_at = .{ .Interval = .{ .__time_duration_micros__ = 5 * std.time.us_per_s }},
});
try ctx.db.get("spawn_food_timer").insert(SpawnFoodTimer {
.scheduled_id = 0,
.scheduled_at = .{ .Interval = .{ .__time_duration_micros__ = 500 * std.time.us_per_ms }}
});
try ctx.db.get("move_all_players_timer").insert(MoveAllPlayersTimer {
try ctx.db.get("move_all_players_timer").insert(MoveAllPlayersTimer{
.scheduled_id = 0,
.scheduled_at = .{ .Interval = .{ .__time_duration_micros__ = 50 * std.time.us_per_ms }}
});
}
pub const OnConnect = spacetime.Reducer{ .func_type = @TypeOf(OnConnectReducer), .func = @ptrCast(&OnConnectReducer), .lifecycle = .OnConnect, };
pub fn OnConnectReducer(ctx: *spacetime.ReducerContext) !void {
// Called everytime a new client connects
std.log.info("[OnConnect]", .{});
const nPlayer = try ctx.db.get("logged_out_players").col("identity").find(.{ .identity = ctx.sender });
if (nPlayer) |player| {
try ctx.db.get("players").insert(player.*);
try ctx.db.get("logged_out_players").col("identity").delete(.{ .identity = player.identity });
} else {
try ctx.db.get("players").insert(Player {
.identity = ctx.sender,
.player_id = 0,
.name = "",
});
}
}
pub const OnDisconnect = spacetime.Reducer{ .func_type = @TypeOf(OnDisconnectReducer), .func = @ptrCast(&OnDisconnectReducer), .lifecycle = .OnDisconnect, };
pub fn OnDisconnectReducer(ctx: *spacetime.ReducerContext) !void {
// Called everytime a client disconnects
std.log.info("[OnDisconnect]", .{});
const nPlayer = try ctx.db.get("players").col("identity").find(.{ .identity = ctx.sender});
if(nPlayer == null) {
std.log.err("Disconnecting player doesn't have a valid players row!",.{});
return;
}
const player = nPlayer.?;
//std.log.info("{?}", .{player});
const player_id = player.player_id;
try ctx.db.get("logged_out_players").insert(player.*);
try ctx.db.get("players").col("identity").delete(.{ .identity = ctx.sender});
// Remove any circles from the arena
var iter = ctx.db.get("circles").col("player_id").filter(.{ .player_id = player_id });
//_ = player_id;
_ = &iter;
// std.log.info("blag", .{});
// while (try iter.next()) |circle_val| {
// try ctx.db.get("entity").col("entity_id").delete(.{ .entity_id = circle_val.entity_id, });
// try ctx.db.get("circle").col("entity_id").delete(.{ .entity_id = circle_val.entity_id, });
// }
}
//#[spacetimedb::table(name = move_all_players_timer, scheduled(move_all_players))]
pub const move_all_players_timer: spacetime.Table = .{
.schema = MoveAllPlayersTimer,
.primary_key = "scheduled_id",
.schedule_reducer = &move_all_players
};
pub const MoveAllPlayersTimer = struct {
//#[primary_key]
//#[auto_inc]
scheduled_id: u64,
scheduled_at: spacetime.ScheduleAt,
};
pub const move_all_players = spacetime.Reducer{
.func_type = @TypeOf(move_all_players_reducer),
.func = @ptrCast(&move_all_players_reducer),
.params = &.{ "_timer" }
.params = &.{ "timer" }
};
pub fn move_all_players_reducer(ctx: *spacetime.ReducerContext, _timer: MoveAllPlayersTimer) !void {
pub fn move_all_players_reducer(ctx: *spacetime.ReducerContext, timer: MoveAllPlayersTimer) !void {
_ = ctx;
_ = _timer;
//std.log.info("Move Players!", .{});
std.log.info("(id: {}) Move Players!", .{timer.scheduled_id});
return;
}
pub const say_hello = spacetime.Reducer{ .func_type = @TypeOf(say_hello_reducer), .func = @ptrCast(&say_hello_reducer)};
// pub const say_hello = spacetime.Reducer{ .func_type = @TypeOf(say_hello_reducer), .func = @ptrCast(&say_hello_reducer)};
pub fn say_hello_reducer(ctx: *spacetime.ReducerContext) !void {
_ = ctx;
std.log.info("Hello!", .{});
return;
}
// pub fn say_hello_reducer(ctx: *spacetime.ReducerContext) !void {
// _ = ctx;
// std.log.info("Hello!", .{});
// return;
// }

View file

@ -244,7 +244,6 @@ pub fn readArg(allocator: std.mem.Allocator, args: BytesSource, comptime t: type
inline else => |tag_field| {
const field = std.meta.fields(t)[@intFromEnum(tag_field)];
@field(temp, field.name) = (try readArg(allocator, args, field.type));
}
}
//@field(temp, field.name) = try readArg(allocator, args, @TypeOf(field));
@ -320,8 +319,8 @@ const StructImpl = struct {
fields: []const StructFieldImpl,
};
pub fn addStructImpl(structImpls: *[]const StructImpl, layout: anytype) u32 {
const name = blk: {
pub fn addStructImpl(structImpls: *[]const StructImpl, layout: anytype, name_override: ?[]const u8) u32 {
const name = name_override orelse blk: {
var temp: []const u8 = @typeName(layout);
if(std.mem.lastIndexOf(u8, temp, ".")) |idx|
temp = temp[idx+1..];
@ -344,7 +343,7 @@ pub fn addStructImpl(structImpls: *[]const StructImpl, layout: anytype) u32 {
.name = field.name,
.type = .{
.Ref = .{
.inner = addStructImpl(structImpls, field.type),
.inner = addStructImpl(structImpls, field.type, null),
}
}
}
@ -429,7 +428,7 @@ pub fn compile(comptime moduleTables : []const Table, comptime moduleReducers :
const table_type: TableType = table.type;
const table_access: TableAccess = table.access;
const product_type_ref: AlgebraicTypeRef = AlgebraicTypeRef{
.inner = addStructImpl(&structDecls, table.schema),
.inner = addStructImpl(&structDecls, table.schema, table.schema_name),
};
const primary_key: []const u16 = blk: {
if(table.primary_key) |key| {
@ -601,8 +600,7 @@ pub fn callReducer(comptime mdef: []const Reducer, id: usize, args: anytype) Red
}
pub fn PrintModule(data: anytype) void {
var buf: [64]u8 = undefined;
std.log.debug(std.fmt.bufPrint(&buf, "\"{s}\": {{", .{@typeName(@TypeOf(data))}) catch "<Error>");
std.log.debug("\"{s}\": {{", .{@typeName(@TypeOf(data))});
switch(@TypeOf(data)) {
RawModuleDefV9 => {
PrintModule(data.typespace);
@ -658,16 +656,16 @@ pub fn PrintModule(data: anytype) void {
}
},
[]const u8 => {
std.log.debug(std.fmt.bufPrint(&buf, "\"{s}\"", .{data}) catch "<Error>");
std.log.debug("\"{s}\"", .{data});
},
u32 => {
std.log.debug(std.fmt.bufPrint(&buf, "{}", .{data}) catch "<Error>");
std.log.debug("{}", .{data});
},
else => {
std.log.debug("\"...\"");
std.log.debug("\"...\"", .{});
},
}
std.log.debug("},");
std.log.debug("}},", .{});
}
pub const Param = struct {
@ -691,6 +689,7 @@ pub const Index = struct {
pub const Table = struct {
name: ?[]const u8 = null,
schema: type,
schema_name: []const u8,
type: TableType = .User,
access: TableAccess = .Private,
primary_key: ?[]const u8 = null,
@ -731,6 +730,7 @@ pub const tables: []const Table = blk: {
.type = field.type,
.access = field.access,
.schema = field.schema,
.schema_name = field.schema_name,
.name = field.name orelse decl.name,
.primary_key = field.primary_key,
.schedule_reducer = field.schedule_reducer,
@ -759,7 +759,7 @@ pub export fn __describe_module__(description: BytesSink) void {
@compileError(fmterr);
};
//PrintModule(compiledModule);
PrintModule(compiledModule);
serialize_module(&moduleDefBytes, compiledModule) catch {
std.log.err("Allocator Error: Cannot continue!", .{});