From 31de354ce4a800e2787a712f9b0d8d045056994a Mon Sep 17 00:00:00 2001 From: ookami125 Date: Wed, 12 Mar 2025 10:57:00 -0400 Subject: [PATCH] parameter names current impl --- src/main.zig | 46 ++++++++++--- src/spacetime.zig | 121 +++++++++++++++++++++++++---------- src/spacetime/serializer.zig | 10 +-- src/spacetime/types.zig | 22 ++++++- 4 files changed, 149 insertions(+), 50 deletions(-) diff --git a/src/main.zig b/src/main.zig index b94327f..47f7e6a 100644 --- a/src/main.zig +++ b/src/main.zig @@ -5,12 +5,15 @@ pub fn print(fmt: []const u8) void { spacetime.console_log(2, null, 0, null, 0, 0, fmt.ptr, fmt.len); } -const moduleDef = .{ +const moduleTablesDef = .{ .Person = spacetime.Table(Person){ .name = "person" }, +}; + +const moduleReducersDef = .{ .Init = spacetime.Reducer(Init){ .lifecycle = .Init }, .OnConnect = spacetime.Reducer(OnConnect){ .lifecycle = .OnConnect }, .OnDisconnect = spacetime.Reducer(OnDisconnect){ .lifecycle = .OnDisconnect }, - .add = spacetime.Reducer(add){}, + .add = spacetime.Reducer(add){ .param_names = &[_][]const u8{ "name" }}, .say_hello = spacetime.Reducer(say_hello){}, }; @@ -41,7 +44,13 @@ export fn __describe_module__(description: spacetime.BytesSink) void { var moduleDefBytes = std.ArrayList(u8).init(allocator); defer moduleDefBytes.deinit(); - spacetime.serialize_module(&moduleDefBytes, comptime spacetime.compile(moduleDef)) catch { + spacetime.serialize_module(&moduleDefBytes, comptime spacetime.compile(moduleTablesDef, moduleReducersDef) catch |err| { + var buf: [1024]u8 = undefined; + const fmterr = std.fmt.bufPrint(&buf, "Error: {}", .{err}) catch { + @compileError("ERROR2: No Space Left! Expand error buffer size!"); + }; + @compileError(fmterr); + }) catch { print("Allocator Error: Cannot continue!"); @panic("Allocator Error: Cannot continue!"); }; @@ -49,6 +58,14 @@ export fn __describe_module__(description: spacetime.BytesSink) void { spacetime.write_to_sink(description, moduleDefBytes.items); } +fn readStringArg(allocator: std.mem.Allocator, args: spacetime.BytesSource) ![]const u8 { + var maxbuf: [4]u8 = undefined; + const len_buf = try spacetime.read_bytes_source(args, &maxbuf); + const len: usize = std.mem.bytesToValue(u32, len_buf); + const string_buf = try allocator.alloc(u8, len); + return try spacetime.read_bytes_source(args, string_buf); +} + export fn __call_reducer__( id: usize, sender_0: u64, @@ -61,22 +78,30 @@ export fn __call_reducer__( args: spacetime.BytesSource, err: spacetime.BytesSink, ) i16 { - //const allocator = std.heap.wasm_allocator; - _ = args; + const allocator = std.heap.wasm_allocator; _ = err; + //_ = args; var ctx: spacetime.ReducerContext = .{ .indentity = std.mem.bytesAsValue(u256, std.mem.sliceAsBytes(&[_]u64{ sender_0, sender_1, sender_2, sender_3})).*, .timestamp = timestamp, .connection_id = std.mem.bytesAsValue(u128, std.mem.sliceAsBytes(&[_]u64{ conn_id_0, conn_id_1})).*, + .db = undefined, }; switch(id) { 0...2, 4 => { - callReducer(moduleDef, id, .{ &ctx }); + callReducer(moduleReducersDef, id, .{ &ctx }); }, 3 => { - callReducer(moduleDef, id, .{ &ctx, "blah" }); + //var maxbuf: [1024]u8 = undefined; + //const buf = spacetime.read_bytes_source(args, &maxbuf) catch unreachable; + //const fmtbuf = std.fmt.allocPrint(allocator, "{any}", .{buf}) catch unreachable; + //defer allocator.free(fmtbuf); + //print(fmtbuf); + //manually parse args + const name: []const u8 = readStringArg(allocator, args) catch unreachable; + callReducer(moduleReducersDef, id, .{ &ctx, name }); }, else => unreachable, } @@ -107,9 +132,10 @@ pub fn OnDisconnect(_ctx: *spacetime.ReducerContext) void { print("Hello, OnDisconnect!"); } -pub fn add(_ctx: *spacetime.ReducerContext, name: []const u8) void { - _ = _ctx; - //ctx.db.person().insert(Person { name }); +pub fn add(ctx: *spacetime.ReducerContext, name: []const u8) void { + //@compileLog(.{@typeInfo(@TypeOf(ctx.db))});// .person().insert(Person { name }); + _ = ctx.db.get(moduleTablesDef.Person); + //ctx.db.person().insert(Person{ .name = name }); var buf: [128]u8 = undefined; print(std.fmt.bufPrint(&buf, "Hello, add({s})!", .{ name }) catch "[add] Error: name to long"); } diff --git a/src/spacetime.zig b/src/spacetime.zig index aa53503..4a97c2d 100644 --- a/src/spacetime.zig +++ b/src/spacetime.zig @@ -50,10 +50,26 @@ pub const BytesSink = extern struct { inner: u32 }; pub const BytesSource = extern struct { inner: u32 }; pub extern "spacetime_10.0" fn bytes_sink_write(sink: BytesSink, buffer_ptr: [*c]const u8, buffer_len_ptr: *usize) u16; +pub extern "spacetime_10.0" fn bytes_source_read(source: BytesSource, buffer_ptr: [*c]u8, buffer_len_ptr: *usize) i16; const NO_SUCH_BYTES = 8; const NO_SPACE = 9; +/// Read `source` from the host fully into `buf`. +pub fn read_bytes_source(source: BytesSource, buf: []u8) ![]u8 { + const INVALID: i16 = NO_SUCH_BYTES; + + var buf_len = buf.len; + const ret = bytes_source_read(source, @ptrCast(buf), &buf_len); + switch(ret) { + -1, 0 => {}, + INVALID => @panic("invalid source passed"), + else => unreachable, + } + + return buf[0..buf_len]; +} + pub fn write_to_sink(sink: BytesSink, _buf: []const u8) void { var buf: []const u8 = _buf; while(true) { @@ -73,46 +89,54 @@ pub fn write_to_sink(sink: BytesSink, _buf: []const u8) void { } } -pub fn parse_reducers(root: type) []const RawReducerDefV9 { - const decls = std.meta.declarations(root); - //@compileLog(.{ decls }); +// pub fn parse_reducers(root: type) []const RawReducerDefV9 { +// const decls = std.meta.declarations(root); +// //@compileLog(.{ decls }); - var reducers : []const RawReducerDefV9 = &[_]RawReducerDefV9{}; - _ = &reducers; +// var reducers : []const RawReducerDefV9 = &[_]RawReducerDefV9{}; +// _ = &reducers; - inline for(decls) |decl| { +// inline for(decls) |decl| { - const temp = @field(root, decl.name); - const temp_type = @typeInfo(@TypeOf(temp)); - if(temp_type != .@"fn") continue; - if(temp_type.@"fn".params[0].type.? != *ReducerContext) continue; +// const temp = @field(root, decl.name); +// const temp_type = @typeInfo(@TypeOf(temp)); +// if(temp_type != .@"fn") continue; +// if(temp_type.@"fn".params[0].type.? != *ReducerContext) continue; - const lifecycle: ?Lifecycle = blk: { - if(std.mem.eql(u8, decl.name, "Init")) break :blk .Init; - if(std.mem.eql(u8, decl.name, "OnConnect")) break :blk .OnConnect; - if(std.mem.eql(u8, decl.name, "OnDisconnect")) break :blk .OnDisconnect; - break :blk null; - }; +// const lifecycle: ?Lifecycle = blk: { +// if(std.mem.eql(u8, decl.name, "Init")) break :blk .Init; +// if(std.mem.eql(u8, decl.name, "OnConnect")) break :blk .OnConnect; +// if(std.mem.eql(u8, decl.name, "OnDisconnect")) break :blk .OnDisconnect; +// break :blk null; +// }; - reducers = reducers ++ &[_]RawReducerDefV9{ - .{ - .name = decl.name, - .params = .{ .elements = &[_]ProductTypeElement{} }, - .lifecycle = lifecycle, - }, - }; +// reducers = reducers ++ &[_]RawReducerDefV9{ +// .{ +// .name = decl.name, +// .params = .{ .elements = &[_]ProductTypeElement{} }, +// .lifecycle = lifecycle, +// }, +// }; - } +// } - return reducers; -} +// return reducers; +// } + +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 []const u8 = &[_][]const u8{}, }; + + //@compileLog(.{@TypeOf(func)}); + return @"spacetime_10.0__reducer_"; } @@ -126,7 +150,15 @@ pub fn Table(comptime table: anytype) type { return @"spacetime_10.0__table_"; } -pub fn compile(comptime module : anytype) RawModuleDefV9 { +fn zigTypeToSpacetimeType(comptime param: ?type) !AlgebraicType { + if(param == null) @compileError("Null parameter type passed to zigParamsToSpacetimeParams"); + return switch(param.?) { + []const u8 => .{ .String = {} }, + else => error.ZigTypeNotSupported, + }; +} + +pub fn compile(comptime moduleTables : anytype, comptime moduleReducers : anytype) !RawModuleDefV9 { var def : RawModuleDefV9 = undefined; _ = &def; @@ -134,11 +166,12 @@ pub fn compile(comptime module : anytype) RawModuleDefV9 { var tables: []const RawTableDefV9 = &[_]RawTableDefV9{}; var reducers: []const RawReducerDefV9 = &[_]RawReducerDefV9{}; - inline for(std.meta.fields(@TypeOf(module))) |field| { - const name: []const u8 = @as(*const field.type, @alignCast(@ptrCast(field.default_value.?))).*.name orelse field.name; + inline for(std.meta.fields(@TypeOf(moduleTables))) |field| { + const default_values = @as(*const field.type, @alignCast(@ptrCast(field.default_value.?))).*; + const name: []const u8 = default_values.name orelse field.name; if( std.mem.endsWith(u8, @typeName(field.type), "spacetime_10.0__table_")) { - const table_type: TableType = @as(*const field.type, @alignCast(@ptrCast(field.default_value.?))).*.table_type; - const table_access: TableAccess = @as(*const field.type, @alignCast(@ptrCast(field.default_value.?))).*.table_access; + const table_type: TableType = default_values.table_type; + const table_access: TableAccess = default_values.table_access; tables = tables ++ &[_]RawTableDefV9{ .{ .name = name, @@ -154,12 +187,34 @@ pub fn compile(comptime module : anytype) RawModuleDefV9 { }; continue; } + @compileLog(.{ field }); + } + + inline for(std.meta.fields(@TypeOf(moduleReducers))) |field| { + const default_values = @as(*const field.type, @alignCast(@ptrCast(field.default_value.?))).*; + const name: []const u8 = default_values.name orelse field.name; if( std.mem.endsWith(u8, @typeName(field.type), "spacetime_10.0__reducer_")) { - const lifecycle: ?Lifecycle = @as(*const field.type, @alignCast(@ptrCast(field.default_value.?))).*.lifecycle; + const lifecycle: ?Lifecycle = default_values.lifecycle; + + //parse the arguments + var params: []const ProductTypeElement = &[_]ProductTypeElement{}; + const param_names = default_values.param_names; + + //@compileLog(.{@typeInfo(@TypeOf(default_values.func)).@"fn"}); + for(@typeInfo(@TypeOf(default_values.func)).@"fn".params[1..], param_names) |param, param_name| { + //@compileLog(.{ name, param }); + params = params ++ &[_]ProductTypeElement{ + .{ + .name = param_name, + .algebraic_type = try zigTypeToSpacetimeType(param.type), + } + }; + } + reducers = reducers ++ &[_]RawReducerDefV9{ .{ .name = name, - .params = .{ .elements = &[_]ProductTypeElement{} }, + .params = .{ .elements = params }, .lifecycle = lifecycle, }, }; diff --git a/src/spacetime/serializer.zig b/src/spacetime/serializer.zig index 9616e46..5f4697d 100644 --- a/src/spacetime/serializer.zig +++ b/src/spacetime/serializer.zig @@ -147,11 +147,11 @@ fn serialize_table_access(array: *std.ArrayList(u8), val: TableAccess) !void { } fn serialize_product_type_element(array: *std.ArrayList(u8), val: ProductTypeElement) !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 array.appendSlice(&[_]u8{ 0 }); + //if(val.name) |name| { + try array.appendSlice(&std.mem.toBytes(@as(u32, @intCast(val.name.len)))); + try array.appendSlice(val.name); + //} try serialize_algebraic_type(array, val.algebraic_type); } diff --git a/src/spacetime/types.zig b/src/spacetime/types.zig index 0d8636e..eaea723 100644 --- a/src/spacetime/types.zig +++ b/src/spacetime/types.zig @@ -1,3 +1,5 @@ +const std = @import("std"); + pub const Str = []const u8; pub const SumTypeVariant = struct { @@ -110,7 +112,7 @@ pub const RawTableDefV9 = struct { }; pub const ProductTypeElement = struct { - name: ?Str, + name: Str, algebraic_type: AlgebraicType, }; @@ -124,11 +126,27 @@ pub const Lifecycle = enum { OnDisconnect, }; +pub fn Table2Struct(comptime table_type: type) type { + _ = table_type; + return struct { + + }; +} + +pub const Local = struct { + pub fn get(self: @This(), table: anytype) Table2Struct(@TypeOf(table)) { + _ = self; + return .{ + //.name = "blahsss", + }; + } +}; + pub const ReducerContext = struct { indentity: u256, timestamp: u64, connection_id: u128, - + db: Local, }; pub const ReducerFn = fn(*ReducerContext) void;