Changing syntax and union support
This commit is contained in:
parent
2331a29358
commit
acadefcaa5
4 changed files with 408 additions and 303 deletions
81
src/main.zig
81
src/main.zig
|
|
@ -6,69 +6,64 @@ pub export fn spacetime_includes() void {
|
||||||
_ = &spacetime.__call_reducer__;
|
_ = &spacetime.__call_reducer__;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const moduleTablesDef = .{
|
pub const DbVector2 = struct {
|
||||||
.person = spacetime.Table(.{.name = "person", .layout = Person}),
|
x: f32,
|
||||||
.person2 = spacetime.Table(.{.name = "person2", .layout = Person}),
|
y: f32,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const moduleReducersDef = .{
|
pub const person: spacetime.Table = .{ .schema = Person, };
|
||||||
.Init = spacetime.Reducer(Init){ .lifecycle = .Init },
|
pub const Person = struct{
|
||||||
.OnConnect = spacetime.Reducer(OnConnect){ .lifecycle = .OnConnect },
|
name: []const u8,
|
||||||
.OnDisconnect = spacetime.Reducer(OnDisconnect){ .lifecycle = .OnDisconnect },
|
pos: DbVector2,
|
||||||
.add = spacetime.Reducer(add){ .param_names = &[_][:0]const u8{ "name" }},
|
schedule: spacetime.ScheduleAt,
|
||||||
.say_hello = spacetime.Reducer(say_hello){},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const DbVector2 = spacetime.Struct(.{
|
pub const Init: spacetime.Reducer = .{
|
||||||
.name = "DbVector2",
|
.func_type = @TypeOf(InitReducer),
|
||||||
.fields = &[_]spacetime.StructFieldDecl{
|
.func = @ptrCast(&InitReducer),
|
||||||
.{ .name = "x", .type = f32, },
|
.lifecycle = .Init,
|
||||||
.{ .name = "y", .type = f32 },
|
};
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
pub const Person = spacetime.Struct(.{
|
pub fn InitReducer(_: *spacetime.ReducerContext) void {
|
||||||
.name = "person",
|
|
||||||
.fields = &[_]spacetime.StructFieldDecl{
|
|
||||||
.{ .name = "name", .type = []const u8, },
|
|
||||||
.{ .name = "pos", .type = DbVector2, },
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
pub fn Init(ctx: *spacetime.ReducerContext) void {
|
|
||||||
// Called when the module is initially published
|
// Called when the module is initially published
|
||||||
_ = ctx;
|
|
||||||
spacetime.print("[Init]");
|
spacetime.print("[Init]");
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn OnConnect(ctx: *spacetime.ReducerContext) void {
|
pub const OnConnect = spacetime.Reducer{ .func_type = @TypeOf(OnConnectReducer), .func = @ptrCast(&OnConnectReducer), .lifecycle = .OnConnect, };
|
||||||
|
pub fn OnConnectReducer(_: *spacetime.ReducerContext) void {
|
||||||
// Called everytime a new client connects
|
// Called everytime a new client connects
|
||||||
_ = ctx;
|
|
||||||
spacetime.print("[OnConnect]");
|
spacetime.print("[OnConnect]");
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn OnDisconnect(ctx: *spacetime.ReducerContext) void {
|
pub const OnDisconnect = spacetime.Reducer{ .func_type = @TypeOf(OnDisconnectReducer), .func = @ptrCast(&OnDisconnectReducer), .lifecycle = .OnDisconnect, };
|
||||||
|
pub fn OnDisconnectReducer(_: *spacetime.ReducerContext) void {
|
||||||
// Called everytime a client disconnects
|
// Called everytime a client disconnects
|
||||||
_ = ctx;
|
|
||||||
spacetime.print("[OnDisconnect]");
|
spacetime.print("[OnDisconnect]");
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add(ctx: *spacetime.ReducerContext, name: []const u8) void {
|
pub const add = spacetime.Reducer{ .func_type = @TypeOf(addReducer), .func = @ptrCast(&addReducer), .params = &.{ "name", "time" }};
|
||||||
const personTable = ctx.*.db.get(moduleTablesDef.person);
|
pub fn addReducer(ctx: *spacetime.ReducerContext, name: []const u8, time: i64) void {
|
||||||
personTable.insert(Person{ .name = name, .pos = DbVector2{ .x = 10.4, .y = 20.6 } });
|
const personTable = ctx.*.db.get("person");
|
||||||
|
personTable.insert(Person{
|
||||||
|
.name = name,
|
||||||
|
.pos = DbVector2{ .x = 10.4, .y = 20.6 },
|
||||||
|
.schedule = .{ .Interval = .{ .__time_duration_micros__ = time, }, },
|
||||||
|
});
|
||||||
|
|
||||||
var buf: [128]u8 = undefined;
|
var buf: [128]u8 = undefined;
|
||||||
spacetime.print(std.fmt.bufPrint(&buf, "[add] {{{s}}}!", .{ name }) catch "[add] Error: name to long");
|
spacetime.print(std.fmt.bufPrint(&buf, "[add] {{{s}}}!", .{ name }) catch "[add] Error: name to long");
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn say_hello(ctx: *spacetime.ReducerContext) void {
|
pub const say_hello = spacetime.Reducer{ .func_type = @TypeOf(say_helloReducer), .func = @ptrCast(&say_helloReducer), };
|
||||||
var personIter = ctx.*.db.get(moduleTablesDef.person).iter();
|
pub fn say_helloReducer(ctx: *spacetime.ReducerContext) void {
|
||||||
while(personIter.next() catch {
|
//_ = ctx;
|
||||||
@panic("person Iter errored!");
|
var personIter = ctx.*.db.get("person").iter();
|
||||||
}) |person| {
|
while(personIter.next() catch {
|
||||||
var buffer: [512]u8 = undefined;
|
@panic("person Iter errored!");
|
||||||
const msg = std.fmt.bufPrint(&buffer, "Hello, {s} (pos: {{{d}, {d}}})!", .{ person.name, person.pos.x, person.pos.y }) catch "<Unknown>";
|
}) |item| {
|
||||||
spacetime.print(msg);
|
var buffer: [512]u8 = undefined;
|
||||||
}
|
const msg = std.fmt.bufPrint(&buffer, "Hello, {s} (pos: {{{d}, {d}}}) (time: {})!", .{ item.name, item.pos.x, item.pos.y, item.schedule.Interval.__time_duration_micros__ }) catch "<Unknown>";
|
||||||
spacetime.print("Hello, World!");
|
spacetime.print(msg);
|
||||||
|
}
|
||||||
|
spacetime.print("Hello, World!");
|
||||||
}
|
}
|
||||||
|
|
@ -51,6 +51,15 @@ pub fn print(fmt: []const u8) void {
|
||||||
console_log(2, null, 0, null, 0, 0, fmt.ptr, fmt.len);
|
console_log(2, null, 0, null, 0, 0, fmt.ptr, fmt.len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn debug_print(comptime fmt: []const u8, args: anytype) void {
|
||||||
|
var buf: [512]u8 = undefined;
|
||||||
|
var fbs = std.io.fixedBufferStream(&buf);
|
||||||
|
std.fmt.format(fbs.writer().any(), fmt, args) catch {
|
||||||
|
return print("Expand the buf in debug_print!");
|
||||||
|
};
|
||||||
|
return print(fbs.getWritten());
|
||||||
|
}
|
||||||
|
|
||||||
pub const BytesSink = extern struct { inner: u32 };
|
pub const BytesSink = extern struct { inner: u32 };
|
||||||
pub const BytesSource = extern struct { inner: u32 };
|
pub const BytesSource = extern struct { inner: u32 };
|
||||||
|
|
||||||
|
|
@ -65,12 +74,10 @@ pub const RowIter = extern struct { _inner: u32, pub const INVALID = RowIter{ ._
|
||||||
pub extern "spacetime_10.0" fn row_iter_bsatn_advance(iter: RowIter, buffer_ptr: [*c]u8, buffer_len_ptr: *usize) i16;
|
pub extern "spacetime_10.0" fn row_iter_bsatn_advance(iter: RowIter, buffer_ptr: [*c]u8, buffer_len_ptr: *usize) i16;
|
||||||
pub extern "spacetime_10.0" fn datastore_table_scan_bsatn(table_id: TableId, out: [*c]RowIter) u16;
|
pub extern "spacetime_10.0" fn datastore_table_scan_bsatn(table_id: TableId, out: [*c]RowIter) u16;
|
||||||
|
|
||||||
// pub const Identity = struct {
|
pub const ScheduleAt = union(enum){
|
||||||
// __identity__: u256,
|
Interval: struct{ __time_duration_micros__: i64 },
|
||||||
// };
|
Time: struct{ __timestamp_micros_since_unix_epoch__: i64 },
|
||||||
|
};
|
||||||
pub const MagicStruct = "spacetime_10.0__struct_";
|
|
||||||
pub const MagicTable = "spacetime_10.0__table_";
|
|
||||||
|
|
||||||
pub const EXHAUSTED = -1;
|
pub const EXHAUSTED = -1;
|
||||||
pub const OK = 0;
|
pub const OK = 0;
|
||||||
|
|
@ -111,21 +118,6 @@ pub fn write_to_sink(sink: BytesSink, _buf: []const u8) void {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const Param = struct {
|
|
||||||
name: []const u8,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub fn Reducer(comptime func: anytype) type {
|
|
||||||
const @"spacetime_10.0__reducer_" = struct {
|
|
||||||
name: ?[]const u8 = null,
|
|
||||||
func: @TypeOf(func) = func,
|
|
||||||
lifecycle: ?Lifecycle = null,
|
|
||||||
param_names: []const [:0]const u8 = &[_][:0]const u8{},
|
|
||||||
};
|
|
||||||
|
|
||||||
return @"spacetime_10.0__reducer_";
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const StructFieldDecl = struct {
|
pub const StructFieldDecl = struct {
|
||||||
name: [:0]const u8,
|
name: [:0]const u8,
|
||||||
type: type,
|
type: type,
|
||||||
|
|
@ -143,6 +135,8 @@ fn spacetimeType2ZigType(t: AlgebraicType) type {
|
||||||
.String => []const u8,
|
.String => []const u8,
|
||||||
.U32 => u32,
|
.U32 => u32,
|
||||||
.U64 => u64,
|
.U64 => u64,
|
||||||
|
.I32 => i32,
|
||||||
|
.I64 => i64,
|
||||||
else => unreachable,
|
else => unreachable,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -152,59 +146,6 @@ const StructFieldImpl = struct {
|
||||||
type: AlgebraicType,
|
type: AlgebraicType,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn Struct(comptime decl: StructDecl) type {
|
|
||||||
const @"spacetime_10.0__struct_" = struct {
|
|
||||||
name: []const u8 = decl.name,
|
|
||||||
};
|
|
||||||
|
|
||||||
var zigStructMembers: []const std.builtin.Type.StructField = &[_]std.builtin.Type.StructField{
|
|
||||||
std.builtin.Type.StructField{
|
|
||||||
.name = MagicStruct,
|
|
||||||
.type = @"spacetime_10.0__struct_",
|
|
||||||
.default_value = @as(?*const anyopaque, &@"spacetime_10.0__struct_"{}),
|
|
||||||
.is_comptime = false,
|
|
||||||
.alignment = 0,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
inline for(decl.fields) |field| {
|
|
||||||
zigStructMembers = zigStructMembers ++ &[_]std.builtin.Type.StructField{
|
|
||||||
std.builtin.Type.StructField{
|
|
||||||
.name = field.name,
|
|
||||||
.type = field.type,
|
|
||||||
.default_value = null,
|
|
||||||
.is_comptime = false,
|
|
||||||
.alignment = 0,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return @Type(.{
|
|
||||||
.@"struct" = std.builtin.Type.Struct{
|
|
||||||
.decls = &[_]std.builtin.Type.Declaration{},
|
|
||||||
.fields = zigStructMembers,
|
|
||||||
.is_tuple = false,
|
|
||||||
.layout = .@"auto",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const TableDecl = struct {
|
|
||||||
name: []const u8,
|
|
||||||
layout: type,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub fn Table(comptime decl: TableDecl) type {
|
|
||||||
const @"spacetime_10.0__table_" = struct {
|
|
||||||
name: []const u8 = decl.name,
|
|
||||||
table_type: TableType = .User,
|
|
||||||
table_access: TableAccess = .Private,
|
|
||||||
layout: @TypeOf(decl.layout) = decl.layout,
|
|
||||||
};
|
|
||||||
|
|
||||||
return @"spacetime_10.0__table_";
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn readArg(allocator: std.mem.Allocator, args: BytesSource, comptime t: AlgebraicType) !spacetimeType2ZigType(t) {
|
pub fn readArg(allocator: std.mem.Allocator, args: BytesSource, comptime t: AlgebraicType) !spacetimeType2ZigType(t) {
|
||||||
switch(t) {
|
switch(t) {
|
||||||
.String => {
|
.String => {
|
||||||
|
|
@ -214,16 +155,11 @@ pub fn readArg(allocator: std.mem.Allocator, args: BytesSource, comptime t: Alge
|
||||||
const string_buf = try allocator.alloc(u8, len);
|
const string_buf = try allocator.alloc(u8, len);
|
||||||
return try read_bytes_source(args, string_buf);
|
return try read_bytes_source(args, string_buf);
|
||||||
},
|
},
|
||||||
.U32 => {
|
.U32, .U64, .I32, .I64 => {
|
||||||
var maxbuf: [4]u8 = undefined;
|
const read_type = spacetimeType2ZigType(t);
|
||||||
|
var maxbuf: [@sizeOf(read_type)]u8 = undefined;
|
||||||
const len_buf = try read_bytes_source(args, &maxbuf);
|
const len_buf = try read_bytes_source(args, &maxbuf);
|
||||||
const len: u32 = std.mem.bytesToValue(u32, len_buf);
|
const len: read_type = std.mem.bytesToValue(read_type, len_buf);
|
||||||
return len;
|
|
||||||
},
|
|
||||||
.U64 => {
|
|
||||||
var maxbuf: [8]u8 = undefined;
|
|
||||||
const len_buf = try read_bytes_source(args, &maxbuf);
|
|
||||||
const len: u64 = std.mem.bytesToValue(u64, len_buf);
|
|
||||||
return len;
|
return len;
|
||||||
},
|
},
|
||||||
else => @compileError("unsupported type in readArg!"),
|
else => @compileError("unsupported type in readArg!"),
|
||||||
|
|
@ -234,11 +170,31 @@ pub fn zigTypeToSpacetimeType(comptime param: ?type) AlgebraicType {
|
||||||
if(param == null) @compileError("Null parameter type passed to zigParamsToSpacetimeParams");
|
if(param == null) @compileError("Null parameter type passed to zigParamsToSpacetimeParams");
|
||||||
return switch(param.?) {
|
return switch(param.?) {
|
||||||
[]const u8 => .{ .String = {} },
|
[]const u8 => .{ .String = {} },
|
||||||
|
i32 => .{ .I32 = {}, },
|
||||||
|
i64 => .{ .I64 = {}, },
|
||||||
u32 => .{ .U32 = {}, },
|
u32 => .{ .U32 = {}, },
|
||||||
u64 => .{ .U64 = {}, },
|
u64 => .{ .U64 = {}, },
|
||||||
f32 => .{ .F32 = {}, },
|
f32 => .{ .F32 = {}, },
|
||||||
//Identity => .{ .U256 = {}, },
|
//Identity => .{ .U256 = {}, },
|
||||||
else => {
|
else => blk: {
|
||||||
|
if(@typeInfo(param.?) == .@"struct") {
|
||||||
|
var elements: []const ProductTypeElement = &.{};
|
||||||
|
const fields = std.meta.fields(param.?);
|
||||||
|
for(fields) |field| {
|
||||||
|
elements = elements ++ &[_]ProductTypeElement{
|
||||||
|
ProductTypeElement{
|
||||||
|
.name = field.name,
|
||||||
|
.algebraic_type = zigTypeToSpacetimeType(field.type),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
break :blk .{
|
||||||
|
.Product = ProductType{
|
||||||
|
.elements = elements
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
@compileLog(param.?);
|
@compileLog(param.?);
|
||||||
@compileError("Unmatched type passed to zigTypeToSpacetimeType!");
|
@compileError("Unmatched type passed to zigTypeToSpacetimeType!");
|
||||||
},
|
},
|
||||||
|
|
@ -251,10 +207,12 @@ const StructImpl = struct {
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn addStructImpl(structImpls: *[]const StructImpl, layout: anytype) u32 {
|
pub fn addStructImpl(structImpls: *[]const StructImpl, layout: anytype) u32 {
|
||||||
var members: []const StructFieldImpl = &[_]StructFieldImpl{};
|
const name = blk: {
|
||||||
|
var temp: []const u8 = @typeName(layout);
|
||||||
const fields = std.meta.fields(layout);
|
if(std.mem.lastIndexOf(u8, temp, ".")) |idx|
|
||||||
const name = utils.getMemberDefaultValue(fields[0].type, "name");
|
temp = temp[idx+1..];
|
||||||
|
break :blk temp;
|
||||||
|
};
|
||||||
|
|
||||||
//FIXME: Search for existing structImpl of provided layout. I think the current might work, but I don't trust it.
|
//FIXME: Search for existing structImpl of provided layout. I think the current might work, but I don't trust it.
|
||||||
inline for(structImpls.*, 0..) |structImpl, i| {
|
inline for(structImpls.*, 0..) |structImpl, i| {
|
||||||
|
|
@ -263,7 +221,9 @@ pub fn addStructImpl(structImpls: *[]const StructImpl, layout: anytype) u32 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline for(fields[1..]) |field| {
|
const fields = std.meta.fields(layout);
|
||||||
|
var members: []const StructFieldImpl = &[_]StructFieldImpl{};
|
||||||
|
inline for(fields) |field| {
|
||||||
if(@typeInfo(field.type) == .@"struct") {
|
if(@typeInfo(field.type) == .@"struct") {
|
||||||
members = members ++ &[_]StructFieldImpl{
|
members = members ++ &[_]StructFieldImpl{
|
||||||
.{
|
.{
|
||||||
|
|
@ -275,6 +235,29 @@ pub fn addStructImpl(structImpls: *[]const StructImpl, layout: anytype) u32 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
} else if(@typeInfo(field.type) == .@"union") {
|
||||||
|
var variants: []const SumTypeVariant = &[_]SumTypeVariant{};
|
||||||
|
_ = &variants;
|
||||||
|
|
||||||
|
const unionFields = std.meta.fields(field.type);
|
||||||
|
inline for(unionFields) |unionField| {
|
||||||
|
variants = variants ++ &[_]SumTypeVariant{
|
||||||
|
SumTypeVariant{
|
||||||
|
.name = unionField.name,
|
||||||
|
.algebraic_type = zigTypeToSpacetimeType(unionField.type),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
members = members ++ &[_]StructFieldImpl{
|
||||||
|
.{
|
||||||
|
.name = field.name,
|
||||||
|
.type = .{
|
||||||
|
.Sum = .{
|
||||||
|
.variants = variants,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
} else {
|
} else {
|
||||||
members = members ++ &[_]StructFieldImpl{
|
members = members ++ &[_]StructFieldImpl{
|
||||||
.{
|
.{
|
||||||
|
|
@ -294,27 +277,27 @@ pub fn addStructImpl(structImpls: *[]const StructImpl, layout: anytype) u32 {
|
||||||
return structImpls.len - 1;
|
return structImpls.len - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn compile(comptime moduleTables : anytype, comptime moduleReducers : anytype) !RawModuleDefV9 {
|
pub fn compile(comptime moduleTables : []const Table, comptime moduleReducers : []const Reducer) !RawModuleDefV9 {
|
||||||
var def : RawModuleDefV9 = undefined;
|
var def : RawModuleDefV9 = undefined;
|
||||||
_ = &def;
|
_ = &def;
|
||||||
|
|
||||||
var tables: []const RawTableDefV9 = &[_]RawTableDefV9{};
|
var tableDefs: []const RawTableDefV9 = &[_]RawTableDefV9{};
|
||||||
var reducers: []const RawReducerDefV9 = &[_]RawReducerDefV9{};
|
var reducerDefs: []const RawReducerDefV9 = &[_]RawReducerDefV9{};
|
||||||
|
|
||||||
var raw_types: []const AlgebraicType = &[_]AlgebraicType{};
|
var raw_types: []const AlgebraicType = &[_]AlgebraicType{};
|
||||||
var types: []const RawTypeDefV9 = &[_]RawTypeDefV9{};
|
var types: []const RawTypeDefV9 = &[_]RawTypeDefV9{};
|
||||||
|
|
||||||
var structDecls: []const StructImpl = &[_]StructImpl{};
|
var structDecls: []const StructImpl = &[_]StructImpl{};
|
||||||
|
|
||||||
inline for(std.meta.fields(@TypeOf(moduleTables))) |field| {
|
inline for(moduleTables) |table| {
|
||||||
const table: @as(*const field.type, @alignCast(@ptrCast(field.default_value))).* = .{};
|
//const table: @as(*const field.type, @alignCast(@ptrCast(field.default_value))).* = .{};
|
||||||
const name: []const u8 = table.name;
|
const name: []const u8 = table.name.?;
|
||||||
const table_type: TableType = table.table_type;
|
const table_type: TableType = table.type;
|
||||||
const table_access: TableAccess = table.table_access;
|
const table_access: TableAccess = table.access;
|
||||||
const product_type_ref: AlgebraicTypeRef = AlgebraicTypeRef{
|
const product_type_ref: AlgebraicTypeRef = AlgebraicTypeRef{
|
||||||
.inner = addStructImpl(&structDecls, table.layout),
|
.inner = addStructImpl(&structDecls, table.schema),
|
||||||
};
|
};
|
||||||
tables = tables ++ &[_]RawTableDefV9{
|
tableDefs = tableDefs ++ &[_]RawTableDefV9{
|
||||||
.{
|
.{
|
||||||
.name = name,
|
.name = name,
|
||||||
.product_type_ref = product_type_ref,
|
.product_type_ref = product_type_ref,
|
||||||
|
|
@ -362,64 +345,56 @@ pub fn compile(comptime moduleTables : anytype, comptime moduleReducers : anytyp
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
inline for(std.meta.fields(@TypeOf(moduleReducers))) |field| {
|
inline for(moduleReducers) |reducer| {
|
||||||
const default_values = @as(*const field.type, @alignCast(@ptrCast(field.default_value.?))).*;
|
const name: []const u8 = reducer.name.?;
|
||||||
const name: []const u8 = default_values.name orelse field.name;
|
const lifecycle: Lifecycle = reducer.lifecycle;
|
||||||
if( std.mem.endsWith(u8, @typeName(field.type), "spacetime_10.0__reducer_")) {
|
|
||||||
const lifecycle: ?Lifecycle = default_values.lifecycle;
|
|
||||||
|
|
||||||
var params: []const ProductTypeElement = &[_]ProductTypeElement{};
|
var params: []const ProductTypeElement = &[_]ProductTypeElement{};
|
||||||
const param_names = default_values.param_names;
|
const param_names = reducer.params;
|
||||||
|
|
||||||
for(@typeInfo(@TypeOf(default_values.func)).@"fn".params[1..], param_names) |param, param_name| {
|
for(@typeInfo(reducer.func_type).@"fn".params[1..], param_names) |param, param_name| {
|
||||||
params = params ++ &[_]ProductTypeElement{
|
params = params ++ &[_]ProductTypeElement{
|
||||||
.{
|
|
||||||
.name = param_name,
|
|
||||||
.algebraic_type = zigTypeToSpacetimeType(param.type),
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
reducers = reducers ++ &[_]RawReducerDefV9{
|
|
||||||
.{
|
.{
|
||||||
.name = name,
|
.name = param_name,
|
||||||
.params = .{ .elements = params },
|
.algebraic_type = zigTypeToSpacetimeType(param.type),
|
||||||
.lifecycle = lifecycle,
|
}
|
||||||
},
|
|
||||||
};
|
};
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
@compileLog(.{ field });
|
|
||||||
|
reducerDefs = reducerDefs ++ &[_]RawReducerDefV9{
|
||||||
|
.{
|
||||||
|
.name = name,
|
||||||
|
.params = .{ .elements = params },
|
||||||
|
.lifecycle = lifecycle,
|
||||||
|
},
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return .{
|
return .{
|
||||||
.typespace = .{
|
.typespace = .{
|
||||||
.types = raw_types,
|
.types = raw_types,
|
||||||
},
|
},
|
||||||
.tables = tables,
|
.tables = tableDefs,
|
||||||
.reducers = reducers,
|
.reducers = reducerDefs,
|
||||||
.types = types,
|
.types = types,
|
||||||
.misc_exports = &[_]RawMiscModuleExportV9{},
|
.misc_exports = &[_]RawMiscModuleExportV9{},
|
||||||
.row_level_security = &[_]RawRowLevelSecurityDefV9{},
|
.row_level_security = &[_]RawRowLevelSecurityDefV9{},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn callReducer(comptime mdef: anytype, id: usize, args: anytype) void {
|
pub fn callReducer(comptime mdef: []const Reducer, id: usize, args: anytype) void {
|
||||||
comptime var i = 0;
|
inline for(mdef, 0..) |field, i| {
|
||||||
inline for(std.meta.fields(@TypeOf(mdef))) |field| {
|
if(id == i) {
|
||||||
if( comptime std.mem.endsWith(u8, @typeName(field.type), "spacetime_10.0__reducer_")) {
|
const func = field.func_type;
|
||||||
if(id == i) {
|
if(std.meta.fields(@TypeOf(args)).len == @typeInfo(func).@"fn".params.len) {
|
||||||
const func = @as(*const field.type, @alignCast(@ptrCast(field.default_value.?))).*.func;
|
const func_val: func = @as(*const func, @ptrCast(field.func)).*;
|
||||||
if(std.meta.fields(@TypeOf(args)).len == @typeInfo(@TypeOf(func)).@"fn".params.len) {
|
return @call(.auto, func_val, args);
|
||||||
return @call(.auto, func, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
const name: []const u8 = @as(*const field.type, @alignCast(@ptrCast(field.default_value.?))).*.name orelse field.name;
|
|
||||||
var buf: [128]u8 = undefined;
|
|
||||||
print(std.fmt.bufPrint(&buf, "invalid number of args passed to {s}, expected {} got {}", .{name, @typeInfo(@TypeOf(func)).@"fn".params.len, std.meta.fields(@TypeOf(args)).len}) catch "!!!Error while printing last error!!!");
|
|
||||||
@panic("invalid number of args passed to func");
|
|
||||||
}
|
}
|
||||||
i += 1;
|
|
||||||
|
const name: []const u8 = field.name.?;
|
||||||
|
var buf: [128]u8 = undefined;
|
||||||
|
print(std.fmt.bufPrint(&buf, "invalid number of args passed to {s}, expected {} got {}", .{name, @typeInfo(func).@"fn".params.len, std.meta.fields(@TypeOf(args)).len}) catch "!!!Error while printing last error!!!");
|
||||||
|
@panic("invalid number of args passed to func");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -494,8 +469,64 @@ pub fn PrintModule(data: anytype) void {
|
||||||
print("},");
|
print("},");
|
||||||
}
|
}
|
||||||
|
|
||||||
const moduleTablesDef = @import("root").moduleTablesDef;
|
pub const Param = struct {
|
||||||
const moduleReducersDef = @import("root").moduleReducersDef;
|
name: []const u8,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const Reducer = struct {
|
||||||
|
name: ?[]const u8 = null,
|
||||||
|
lifecycle: Lifecycle = .None,
|
||||||
|
params: []const [:0]const u8 = &.{},
|
||||||
|
param_types: ?[]type = null,
|
||||||
|
func_type: type,
|
||||||
|
func: *const fn()void,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const Table = struct {
|
||||||
|
name: ?[]const u8 = null,
|
||||||
|
schema: type,
|
||||||
|
type: TableType = .User,
|
||||||
|
access: TableAccess = .Private,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const reducers: []const Reducer = blk: {
|
||||||
|
var temp: []const Reducer = &.{};
|
||||||
|
const root = @import("root");
|
||||||
|
for(@typeInfo(root).@"struct".decls) |decl| {
|
||||||
|
const field = @field(root, decl.name);
|
||||||
|
if(@TypeOf(@field(root, decl.name)) == Reducer) {
|
||||||
|
temp = temp ++ &[_]Reducer{
|
||||||
|
Reducer{
|
||||||
|
.name = field.name orelse decl.name,
|
||||||
|
.lifecycle = field.lifecycle,
|
||||||
|
.params = field.params,
|
||||||
|
.func = field.func,
|
||||||
|
.func_type = field.func_type,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break :blk temp;
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const tables: []const Table = blk: {
|
||||||
|
var temp: []const Table = &.{};
|
||||||
|
const root = @import("root");
|
||||||
|
for(@typeInfo(root).@"struct".decls) |decl| {
|
||||||
|
const field = @field(root, decl.name);
|
||||||
|
if(@TypeOf(@field(root, decl.name)) == Table) {
|
||||||
|
temp = temp ++ &[_]Table{
|
||||||
|
Table{
|
||||||
|
.type = field.type,
|
||||||
|
.access = field.access,
|
||||||
|
.schema = field.schema,
|
||||||
|
.name = field.name orelse decl.name,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break :blk temp;
|
||||||
|
};
|
||||||
|
|
||||||
pub export fn __describe_module__(description: BytesSink) void {
|
pub export fn __describe_module__(description: BytesSink) void {
|
||||||
const allocator = std.heap.wasm_allocator;
|
const allocator = std.heap.wasm_allocator;
|
||||||
|
|
@ -504,7 +535,7 @@ pub export fn __describe_module__(description: BytesSink) void {
|
||||||
var moduleDefBytes = std.ArrayList(u8).init(allocator);
|
var moduleDefBytes = std.ArrayList(u8).init(allocator);
|
||||||
defer moduleDefBytes.deinit();
|
defer moduleDefBytes.deinit();
|
||||||
|
|
||||||
const compiledModule = comptime compile(moduleTablesDef, moduleReducersDef) catch |err| {
|
const compiledModule = comptime compile(tables, reducers) catch |err| {
|
||||||
var buf: [1024]u8 = undefined;
|
var buf: [1024]u8 = undefined;
|
||||||
const fmterr = std.fmt.bufPrint(&buf, "Error: {}", .{err}) catch {
|
const fmterr = std.fmt.bufPrint(&buf, "Error: {}", .{err}) catch {
|
||||||
@compileError("ERROR2: No Space Left! Expand error buffer size!");
|
@compileError("ERROR2: No Space Left! Expand error buffer size!");
|
||||||
|
|
@ -512,16 +543,11 @@ pub export fn __describe_module__(description: BytesSink) void {
|
||||||
@compileError(fmterr);
|
@compileError(fmterr);
|
||||||
};
|
};
|
||||||
|
|
||||||
//PrintModule(compiledModule);
|
|
||||||
|
|
||||||
serialize_module(&moduleDefBytes, compiledModule) catch {
|
serialize_module(&moduleDefBytes, compiledModule) catch {
|
||||||
print("Allocator Error: Cannot continue!");
|
print("Allocator Error: Cannot continue!");
|
||||||
@panic("Allocator Error: Cannot continue!");
|
@panic("Allocator Error: Cannot continue!");
|
||||||
};
|
};
|
||||||
|
|
||||||
//var buffer: [8196]u8 = undefined;
|
|
||||||
//print(std.fmt.bufPrint(&buffer, "{any}", .{moduleDefBytes.items}) catch "Expand buffer");
|
|
||||||
|
|
||||||
write_to_sink(description, moduleDefBytes.items);
|
write_to_sink(description, moduleDefBytes.items);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -550,66 +576,62 @@ pub export fn __call_reducer__(
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
var i: usize = 0;
|
inline for(reducers, 0..) |reducer, i| {
|
||||||
inline for(std.meta.fields(@TypeOf(moduleReducersDef))) |field| {
|
if(id == i) {
|
||||||
if( comptime std.mem.endsWith(u8, @typeName(field.type), "spacetime_10.0__reducer_")) {
|
const func = reducer.func_type;
|
||||||
defer i += 1;
|
const params = @typeInfo(func).@"fn".params;
|
||||||
if(id == i) {
|
const param_names = reducer.params;
|
||||||
const func = utils.getMemberDefaultType(field.type, "func");
|
comptime var argCount = 1;
|
||||||
const params = @typeInfo(func).@"fn".params;
|
comptime var argList: []const std.builtin.Type.StructField = &[_]std.builtin.Type.StructField{
|
||||||
const param_names = @field(moduleReducersDef, field.name).param_names;
|
std.builtin.Type.StructField{
|
||||||
comptime var argCount = 1;
|
.alignment = 0,
|
||||||
comptime var argList: []const std.builtin.Type.StructField = &[_]std.builtin.Type.StructField{
|
.default_value = null,
|
||||||
|
.is_comptime = false,
|
||||||
|
.name = "0",
|
||||||
|
.type = *ReducerContext,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
inline for(params[1..], param_names) |param, name| {
|
||||||
|
_ = name;
|
||||||
|
argList = argList ++ &[_]std.builtin.Type.StructField{
|
||||||
std.builtin.Type.StructField{
|
std.builtin.Type.StructField{
|
||||||
.alignment = 0,
|
.alignment = 0,
|
||||||
.default_value = null,
|
.default_value = null,
|
||||||
.is_comptime = false,
|
.is_comptime = false,
|
||||||
.name = "0",
|
.name = comptime utils.itoa(argCount),
|
||||||
.type = *ReducerContext,
|
.type = param.type.?,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
argCount += 1;
|
||||||
inline for(params[1..], param_names) |param, name| {
|
|
||||||
_ = name;
|
|
||||||
argList = argList ++ &[_]std.builtin.Type.StructField{
|
|
||||||
std.builtin.Type.StructField{
|
|
||||||
.alignment = 0,
|
|
||||||
.default_value = null,
|
|
||||||
.is_comptime = false,
|
|
||||||
.name = comptime utils.itoa(argCount),
|
|
||||||
.type = param.type.?,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
argCount += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
const argsStruct = @Type(.{
|
|
||||||
.@"struct" = std.builtin.Type.Struct{
|
|
||||||
.backing_integer = null,
|
|
||||||
.decls = &[_]std.builtin.Type.Declaration{},
|
|
||||||
.fields = argList,
|
|
||||||
.is_tuple = true,
|
|
||||||
.layout = .auto,
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
var constructedArg: argsStruct = undefined;
|
|
||||||
|
|
||||||
@field(constructedArg, "0") = &ctx;
|
|
||||||
|
|
||||||
if(args.inner != 0) {
|
|
||||||
inline for(params, 0..) |param, name| {
|
|
||||||
comptime if(name == 0) continue;
|
|
||||||
@field(constructedArg, utils.itoa(name)) = readArg(allocator, args, zigTypeToSpacetimeType(param.type.?)) catch |err2| {
|
|
||||||
var buf: [512]u8 = undefined;
|
|
||||||
print(std.fmt.bufPrint(&buf, "Error: {}", .{err2}) catch "Expand Error Buffer!");
|
|
||||||
@panic("blah");
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
callReducer(moduleReducersDef, i, constructedArg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const argsStruct = @Type(.{
|
||||||
|
.@"struct" = std.builtin.Type.Struct{
|
||||||
|
.backing_integer = null,
|
||||||
|
.decls = &[_]std.builtin.Type.Declaration{},
|
||||||
|
.fields = argList,
|
||||||
|
.is_tuple = true,
|
||||||
|
.layout = .auto,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var constructedArg: argsStruct = undefined;
|
||||||
|
|
||||||
|
@field(constructedArg, "0") = &ctx;
|
||||||
|
|
||||||
|
if(args.inner != 0) {
|
||||||
|
inline for(params, 0..) |param, name| {
|
||||||
|
comptime if(name == 0) continue;
|
||||||
|
@field(constructedArg, utils.itoa(name)) = readArg(allocator, args, zigTypeToSpacetimeType(param.type.?)) catch |err2| {
|
||||||
|
var buf: [512]u8 = undefined;
|
||||||
|
print(std.fmt.bufPrint(&buf, "Error: {}", .{err2}) catch "Expand Error Buffer!");
|
||||||
|
@panic("blah");
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
callReducer(reducers, i, constructedArg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -65,9 +65,9 @@ fn serialize_raw_reducer_def_v9(array: *std.ArrayList(u8), val: RawReducerDefV9)
|
||||||
for(val.params.elements) |element| {
|
for(val.params.elements) |element| {
|
||||||
try serialize_product_type_element(array, element);
|
try serialize_product_type_element(array, element);
|
||||||
}
|
}
|
||||||
try array.appendSlice(&[_]u8{ @intFromBool(val.lifecycle == null) });
|
try array.appendSlice(&[_]u8{ @intFromBool(val.lifecycle == .None) });
|
||||||
if(val.lifecycle) |lifecycle| {
|
if(val.lifecycle != .None) {
|
||||||
try serialize_lifecycle(array, lifecycle);
|
try serialize_lifecycle(array, val.lifecycle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -146,6 +146,22 @@ fn serialize_table_access(array: *std.ArrayList(u8), val: TableAccess) !void {
|
||||||
try array.appendSlice(&[_]u8{@intFromEnum(val)});
|
try array.appendSlice(&[_]u8{@intFromEnum(val)});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn serialize_sum_type_variant(array: *std.ArrayList(u8), val: SumTypeVariant) !void {
|
||||||
|
try array.appendSlice(&[_]u8{ @intFromBool(val.name == null) });
|
||||||
|
if(val.name) |name| {
|
||||||
|
try array.appendSlice(&std.mem.toBytes(@as(u32, @intCast(name.len))));
|
||||||
|
try array.appendSlice(name);
|
||||||
|
}
|
||||||
|
try serialize_algebraic_type(array, val.algebraic_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn serialize_sum_type(array: *std.ArrayList(u8), val: SumType) std.mem.Allocator.Error!void {
|
||||||
|
try array.appendSlice(&std.mem.toBytes(@as(u32, @intCast(val.variants.len))));
|
||||||
|
for(val.variants) |variant| {
|
||||||
|
try serialize_sum_type_variant(array, variant);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn serialize_product_type_element(array: *std.ArrayList(u8), val: ProductTypeElement) !void {
|
fn serialize_product_type_element(array: *std.ArrayList(u8), val: ProductTypeElement) !void {
|
||||||
try array.appendSlice(&[_]u8{ 0 });
|
try array.appendSlice(&[_]u8{ 0 });
|
||||||
try array.appendSlice(&std.mem.toBytes(@as(u32, @intCast(val.name.len))));
|
try array.appendSlice(&std.mem.toBytes(@as(u32, @intCast(val.name.len))));
|
||||||
|
|
@ -170,6 +186,10 @@ fn serialize_algebraic_type(array: *std.ArrayList(u8), val: AlgebraicType) !void
|
||||||
try array.appendSlice(&[_]u8{@intFromEnum(val)});
|
try array.appendSlice(&[_]u8{@intFromEnum(val)});
|
||||||
try array.appendSlice(&std.mem.toBytes(ref.inner));
|
try array.appendSlice(&std.mem.toBytes(ref.inner));
|
||||||
},
|
},
|
||||||
|
AlgebraicType.Sum => |sum| {
|
||||||
|
try array.appendSlice(&[_]u8{@intFromEnum(val)});
|
||||||
|
try serialize_sum_type(array, sum);
|
||||||
|
},
|
||||||
else => try array.appendSlice(&[_]u8{@intFromEnum(val)}),
|
else => try array.appendSlice(&[_]u8{@intFromEnum(val)}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -127,13 +127,42 @@ pub const Lifecycle = enum {
|
||||||
Init,
|
Init,
|
||||||
OnConnect,
|
OnConnect,
|
||||||
OnDisconnect,
|
OnDisconnect,
|
||||||
|
None,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
fn getUnionSize(data: anytype) usize {
|
||||||
|
//const fields = std.meta.fields(@TypeOf(data));
|
||||||
|
var size: usize = 0;
|
||||||
|
|
||||||
|
switch(data) {
|
||||||
|
inline else => |field| {
|
||||||
|
switch(@TypeOf(field)) {
|
||||||
|
[]const u8 => {
|
||||||
|
const val = @field(data, field.name);
|
||||||
|
size = @max(size, 4 + val.len);
|
||||||
|
},
|
||||||
|
i64, u32, u64, f32 => {
|
||||||
|
size = @max(size, @sizeOf(field.type));
|
||||||
|
},
|
||||||
|
else => {
|
||||||
|
switch(@typeInfo(@TypeOf(field))) {
|
||||||
|
.@"struct" => {
|
||||||
|
size = @max(size, getStructSize(field));
|
||||||
|
},
|
||||||
|
.@"union" => {
|
||||||
|
size = @max(size, 1 + getUnionSize(field));
|
||||||
|
},
|
||||||
|
else => @compileError("Unsupported type in getUnionSize"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
fn getStructSize(data: anytype) usize {
|
fn getStructSize(data: anytype) usize {
|
||||||
const struct_type = @TypeOf(data);
|
|
||||||
|
|
||||||
const @"spacetime_10.0__table_" = utils.getMemberDefaultType(struct_type, spacetime.MagicStruct);
|
|
||||||
|
|
||||||
const fields = std.meta.fields(@TypeOf(data));
|
const fields = std.meta.fields(@TypeOf(data));
|
||||||
var size: usize = 0;
|
var size: usize = 0;
|
||||||
inline for(fields) |field| {
|
inline for(fields) |field| {
|
||||||
|
|
@ -142,23 +171,18 @@ fn getStructSize(data: anytype) usize {
|
||||||
const val = @field(data, field.name);
|
const val = @field(data, field.name);
|
||||||
size += 4 + val.len;
|
size += 4 + val.len;
|
||||||
},
|
},
|
||||||
u32 => {
|
i64, u32, u64, f32 => {
|
||||||
size += 4;
|
size += @sizeOf(field.type);
|
||||||
},
|
},
|
||||||
u64 => {
|
|
||||||
size += 8;
|
|
||||||
},
|
|
||||||
f32 => {
|
|
||||||
size += 4;
|
|
||||||
},
|
|
||||||
@"spacetime_10.0__table_" => {},
|
|
||||||
else => blk: {
|
else => blk: {
|
||||||
if(@typeInfo(field.type) == .@"struct" and std.meta.fieldIndex(field.type, spacetime.MagicStruct) != null) {
|
if(@typeInfo(field.type) == .@"struct") {
|
||||||
size += getStructSize(@field(data, field.name));
|
size += getStructSize(@field(data, field.name));
|
||||||
break :blk;
|
break :blk;
|
||||||
|
} else if(@typeInfo(field.type) == .@"union") {
|
||||||
|
size += 1 + getUnionSize(@field(data, field.name));
|
||||||
|
break :blk;
|
||||||
}
|
}
|
||||||
@compileLog(field.type);
|
@compileError("Unsupported type in getStructSize");
|
||||||
@compileError("Unsupported type in StructSerializer");
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -166,10 +190,19 @@ fn getStructSize(data: anytype) usize {
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn getStructData(data: anytype, mem: []u8) []u8 {
|
fn getUnionData(data: anytype, mem: []u8) []u8 {
|
||||||
const struct_type = @TypeOf(data);
|
var offset_mem = mem;
|
||||||
const @"spacetime_10.0__table_" = utils.getMemberDefaultType(struct_type, spacetime.MagicStruct);
|
switch(data) {
|
||||||
|
inline else => |field| {
|
||||||
|
std.mem.bytesAsValue(u8, offset_mem[0..@sizeOf(u8)]).* = @intFromEnum(data);
|
||||||
|
offset_mem = offset_mem[@sizeOf(u8)..];
|
||||||
|
offset_mem = getStructData(field, offset_mem);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return offset_mem;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn getStructData(data: anytype, mem: []u8) []u8 {
|
||||||
const fields = std.meta.fields(@TypeOf(data));
|
const fields = std.meta.fields(@TypeOf(data));
|
||||||
var offset_mem = mem;
|
var offset_mem = mem;
|
||||||
inline for(fields) |field| {
|
inline for(fields) |field| {
|
||||||
|
|
@ -180,26 +213,18 @@ fn getStructData(data: anytype, mem: []u8) []u8 {
|
||||||
std.mem.copyForwards(u8, offset_mem[4..], val);
|
std.mem.copyForwards(u8, offset_mem[4..], val);
|
||||||
offset_mem = offset_mem[4 + val.len ..];
|
offset_mem = offset_mem[4 + val.len ..];
|
||||||
},
|
},
|
||||||
u32 => {
|
i32, i64, u32, u64, f32 => {
|
||||||
const val = @field(data, field.name);
|
const val = @field(data, field.name);
|
||||||
std.mem.bytesAsValue(u32, offset_mem[0..4]).* = val;
|
std.mem.bytesAsValue(field.type, offset_mem[0..@sizeOf(field.type)]).* = val;
|
||||||
offset_mem = offset_mem[4..];
|
offset_mem = offset_mem[@sizeOf(field.type)..];
|
||||||
},
|
},
|
||||||
u64 => {
|
|
||||||
const val = @field(data, field.name);
|
|
||||||
std.mem.bytesAsValue(u64, offset_mem[0..4]).* = val;
|
|
||||||
offset_mem = offset_mem[8..];
|
|
||||||
},
|
|
||||||
f32 => {
|
|
||||||
const val = @field(data, field.name);
|
|
||||||
std.mem.bytesAsValue(f32, offset_mem[0..4]).* = val;
|
|
||||||
offset_mem = offset_mem[4..];
|
|
||||||
},
|
|
||||||
@"spacetime_10.0__table_" => {},
|
|
||||||
else => blk: {
|
else => blk: {
|
||||||
if(@typeInfo(field.type) == .@"struct" and std.meta.fieldIndex(field.type, spacetime.MagicStruct) != null) {
|
if(@typeInfo(field.type) == .@"struct") {
|
||||||
offset_mem = getStructData(@field(data, field.name), offset_mem);
|
offset_mem = getStructData(@field(data, field.name), offset_mem);
|
||||||
break :blk;
|
break :blk;
|
||||||
|
} else if(@typeInfo(field.type) == .@"union") {
|
||||||
|
offset_mem = getUnionData(@field(data, field.name), offset_mem);
|
||||||
|
break :blk;
|
||||||
}
|
}
|
||||||
@compileLog(field.type);
|
@compileLog(field.type);
|
||||||
@compileError("Unsupported type in StructSerializer");
|
@compileError("Unsupported type in StructSerializer");
|
||||||
|
|
@ -220,9 +245,52 @@ pub fn StructSerializer(struct_type: type) fn(std.mem.Allocator, struct_type) st
|
||||||
}.serialize;
|
}.serialize;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn StructDeserializer(struct_type: type) fn(allocator: std.mem.Allocator, *[]const u8) std.mem.Allocator.Error!*struct_type {
|
pub fn UnionDeserializer(union_type: type) fn(allocator: std.mem.Allocator, *[]const u8) std.mem.Allocator.Error!*union_type {
|
||||||
const @"spacetime_10.0__table_" = utils.getMemberDefaultType(struct_type, spacetime.MagicStruct);
|
return struct {
|
||||||
|
pub fn deserialize(allocator: std.mem.Allocator, data: *[]const u8) std.mem.Allocator.Error!*union_type {
|
||||||
|
const ret = try allocator.create(union_type);
|
||||||
|
var offset_mem = data.*;
|
||||||
|
|
||||||
|
const tagType = u8;
|
||||||
|
|
||||||
|
const tag: std.meta.Tag(union_type) = @enumFromInt(std.mem.bytesAsValue(tagType, offset_mem[0..@sizeOf(tagType)]).*);
|
||||||
|
offset_mem = offset_mem[@sizeOf(tagType)..];
|
||||||
|
switch(tag) {
|
||||||
|
inline else => |union_field| {
|
||||||
|
const field = std.meta.fields(union_type)[@intFromEnum(union_field)];
|
||||||
|
switch(field.type) {
|
||||||
|
[]const u8 => {
|
||||||
|
const len = std.mem.bytesAsValue(u32, offset_mem[0..4]).*;
|
||||||
|
const str = try allocator.dupe(u8, offset_mem[4..(4+len)]);
|
||||||
|
@field(ret.*, field.name) = str;
|
||||||
|
offset_mem = offset_mem[4+len ..];
|
||||||
|
},
|
||||||
|
u32, u64, i32, i64, f32 => {
|
||||||
|
@field(ret.*, field.name) = std.mem.bytesAsValue(field.type, offset_mem[0..@sizeOf(field.type)]).*;
|
||||||
|
offset_mem = offset_mem[@sizeOf(field.type)..];
|
||||||
|
},
|
||||||
|
else => blk: {
|
||||||
|
if(@typeInfo(field.type) == .@"struct") {
|
||||||
|
@field(ret.*, field.name) = (try StructDeserializer(field.type)(allocator, &offset_mem)).*;
|
||||||
|
break :blk;
|
||||||
|
} else if(@typeInfo(field.type) == .@"union") {
|
||||||
|
@field(ret.*, field.name) = (try UnionDeserializer(field.type)(allocator, &offset_mem)).*;
|
||||||
|
break :blk;
|
||||||
|
}
|
||||||
|
@compileLog(field.type);
|
||||||
|
@compileError("Unsupported type in StructDeserializer");
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data.* = offset_mem;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}.deserialize;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn StructDeserializer(struct_type: type) fn(allocator: std.mem.Allocator, *[]const u8) std.mem.Allocator.Error!*struct_type {
|
||||||
return struct {
|
return struct {
|
||||||
pub fn deserialize(allocator: std.mem.Allocator, data: *[]const u8) std.mem.Allocator.Error!*struct_type {
|
pub fn deserialize(allocator: std.mem.Allocator, data: *[]const u8) std.mem.Allocator.Error!*struct_type {
|
||||||
const ret = try allocator.create(struct_type);
|
const ret = try allocator.create(struct_type);
|
||||||
|
|
@ -236,23 +304,17 @@ pub fn StructDeserializer(struct_type: type) fn(allocator: std.mem.Allocator, *[
|
||||||
@field(ret.*, field.name) = str;
|
@field(ret.*, field.name) = str;
|
||||||
offset_mem = offset_mem[4+len ..];
|
offset_mem = offset_mem[4+len ..];
|
||||||
},
|
},
|
||||||
u32 => {
|
u32, u64, i32, i64, f32 => {
|
||||||
@field(ret.*, field.name) = std.mem.bytesAsValue(u32, offset_mem[0..4]).*;
|
@field(ret.*, field.name) = std.mem.bytesAsValue(field.type, offset_mem[0..@sizeOf(field.type)]).*;
|
||||||
offset_mem = offset_mem[4..];
|
offset_mem = offset_mem[@sizeOf(field.type)..];
|
||||||
},
|
},
|
||||||
u64 => {
|
|
||||||
@field(ret.*, field.name) = std.mem.bytesAsValue(u64, offset_mem[0..4]).*;
|
|
||||||
offset_mem = offset_mem[8..];
|
|
||||||
},
|
|
||||||
f32 => {
|
|
||||||
@field(ret.*, field.name) = std.mem.bytesAsValue(f32, offset_mem[0..4]).*;
|
|
||||||
offset_mem = offset_mem[4..];
|
|
||||||
},
|
|
||||||
@"spacetime_10.0__table_" => {},
|
|
||||||
else => blk: {
|
else => blk: {
|
||||||
if(@typeInfo(field.type) == .@"struct" and std.meta.fieldIndex(field.type, spacetime.MagicStruct) != null) {
|
if(@typeInfo(field.type) == .@"struct") {
|
||||||
@field(ret.*, field.name) = (try StructDeserializer(field.type)(allocator, &offset_mem)).*;
|
@field(ret.*, field.name) = (try StructDeserializer(field.type)(allocator, &offset_mem)).*;
|
||||||
break :blk;
|
break :blk;
|
||||||
|
} else if(@typeInfo(field.type) == .@"union") {
|
||||||
|
@field(ret.*, field.name) = (try UnionDeserializer(field.type)(allocator, &offset_mem)).*;
|
||||||
|
break :blk;
|
||||||
}
|
}
|
||||||
@compileLog(field.type);
|
@compileLog(field.type);
|
||||||
@compileError("Unsupported type in StructDeserializer");
|
@compileError("Unsupported type in StructDeserializer");
|
||||||
|
|
@ -265,9 +327,15 @@ pub fn StructDeserializer(struct_type: type) fn(allocator: std.mem.Allocator, *[
|
||||||
}.deserialize;
|
}.deserialize;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn Table2ORM(comptime table_type: type) type {
|
pub fn Table2ORM(comptime table_name: []const u8) type {
|
||||||
const table_name = utils.getMemberDefaultValue(table_type, "name");
|
const table = blk: {
|
||||||
const struct_type = utils.getMemberDefaultValue(table_type, "layout");
|
for(spacetime.tables) |table| {
|
||||||
|
if(std.mem.eql(u8, table_name, table.name.?)) {
|
||||||
|
break :blk table;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const struct_type = table.schema;
|
||||||
|
|
||||||
return struct {
|
return struct {
|
||||||
allocator: std.mem.Allocator,
|
allocator: std.mem.Allocator,
|
||||||
|
|
@ -343,7 +411,7 @@ pub fn Table2ORM(comptime table_type: type) type {
|
||||||
pub const Local = struct {
|
pub const Local = struct {
|
||||||
allocator: std.mem.Allocator,
|
allocator: std.mem.Allocator,
|
||||||
|
|
||||||
pub fn get(self: @This(), table: anytype) Table2ORM(table) {
|
pub fn get(self: @This(), comptime table: []const u8) Table2ORM(table) {
|
||||||
return .{
|
return .{
|
||||||
.allocator = self.allocator,
|
.allocator = self.allocator,
|
||||||
};
|
};
|
||||||
|
|
@ -362,7 +430,7 @@ pub const ReducerFn = fn(*ReducerContext) void;
|
||||||
pub const RawReducerDefV9 = struct {
|
pub const RawReducerDefV9 = struct {
|
||||||
name: RawIdentifier,
|
name: RawIdentifier,
|
||||||
params: ProductType,
|
params: ProductType,
|
||||||
lifecycle: ?Lifecycle,
|
lifecycle: Lifecycle,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const RawScopedTypeNameV9 = struct {
|
pub const RawScopedTypeNameV9 = struct {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue