First "usable" version zig on spacetimedb
This commit is contained in:
parent
31de354ce4
commit
ba5cadfb1b
5 changed files with 568 additions and 254 deletions
|
|
@ -1,4 +1,7 @@
|
|||
const std = @import("std");
|
||||
const spacetime = @import("../spacetime.zig");
|
||||
const console_log = spacetime.console_log;
|
||||
const TableId = spacetime.TableId;
|
||||
|
||||
pub const Str = []const u8;
|
||||
|
||||
|
|
@ -12,7 +15,6 @@ pub const SumType = struct {
|
|||
};
|
||||
|
||||
pub const ArrayType = struct {
|
||||
/// The base type every element of the array has.
|
||||
elem_ty: []const AlgebraicType,
|
||||
};
|
||||
|
||||
|
|
@ -126,18 +128,181 @@ pub const Lifecycle = enum {
|
|||
OnDisconnect,
|
||||
};
|
||||
|
||||
pub fn Table2Struct(comptime table_type: type) type {
|
||||
_ = table_type;
|
||||
return struct {
|
||||
pub fn StructSerializer(struct_type: type) fn(std.mem.Allocator, struct_type) std.mem.Allocator.Error![]u8 {
|
||||
|
||||
const @"spacetime_10.0__table_" = std.meta.fields(struct_type)[std.meta.fieldIndex(struct_type, "spacetime_10.0__table_").?].type;
|
||||
|
||||
return struct {
|
||||
pub fn serialize(allocator: std.mem.Allocator, data: struct_type) ![]u8 {
|
||||
const fields = std.meta.fields(@TypeOf(data));
|
||||
var size: usize = 0;
|
||||
inline for(fields) |field| {
|
||||
switch(field.type) {
|
||||
[]const u8 => {
|
||||
const val = @field(data, field.name);
|
||||
size += 4 + val.len;
|
||||
},
|
||||
u32 => {
|
||||
size += 4;
|
||||
},
|
||||
u64 => {
|
||||
size += 8;
|
||||
},
|
||||
@"spacetime_10.0__table_" => {},
|
||||
else => {
|
||||
@compileLog(field.type);
|
||||
@compileError("Unsupported type in StructSerializer");
|
||||
},
|
||||
}
|
||||
}
|
||||
const mem = try allocator.alloc(u8, size);
|
||||
var offset_mem = mem;
|
||||
inline for(fields) |field| {
|
||||
switch(field.type) {
|
||||
[]const u8 => {
|
||||
const val = @field(data, field.name);
|
||||
std.mem.bytesAsValue(u32, offset_mem[0..4]).* = val.len;
|
||||
std.mem.copyForwards(u8, offset_mem[4..], val);
|
||||
offset_mem = offset_mem[4 + val.len ..];
|
||||
},
|
||||
u32 => {
|
||||
const val = @field(data, field.name);
|
||||
std.mem.bytesAsValue(u32, offset_mem[0..4]).* = val;
|
||||
offset_mem = offset_mem[4..];
|
||||
},
|
||||
u64 => {
|
||||
const val = @field(data, field.name);
|
||||
std.mem.bytesAsValue(u64, offset_mem[0..4]).* = val;
|
||||
offset_mem = offset_mem[8..];
|
||||
},
|
||||
@"spacetime_10.0__table_" => {},
|
||||
else => @compileError("Unsupported type in StructSerializer"),
|
||||
}
|
||||
}
|
||||
return mem;
|
||||
}
|
||||
}.serialize;
|
||||
}
|
||||
|
||||
pub fn StructDeserializer(struct_type: type) fn(allocator: std.mem.Allocator, *[]const u8) std.mem.Allocator.Error!*struct_type {
|
||||
|
||||
const @"spacetime_10.0__table_" = std.meta.fields(struct_type)[std.meta.fieldIndex(struct_type, "spacetime_10.0__table_").?].type;
|
||||
|
||||
return struct {
|
||||
pub fn deserialize(allocator: std.mem.Allocator, data: *[]const u8) std.mem.Allocator.Error!*struct_type {
|
||||
const ret = try allocator.create(struct_type);
|
||||
var offset_mem = data.*;
|
||||
const fields = std.meta.fields(struct_type);
|
||||
inline for(fields) |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 => {
|
||||
@field(ret.*, field.name) = std.mem.bytesAsValue(u32, offset_mem[0..4]).*;
|
||||
offset_mem = offset_mem[4..];
|
||||
},
|
||||
u64 => {
|
||||
@field(ret.*, field.name) = std.mem.bytesAsValue(u64, offset_mem[0..4]).*;
|
||||
offset_mem = offset_mem[8..];
|
||||
},
|
||||
@"spacetime_10.0__table_" => {},
|
||||
else => @compileError("Unsupported type in StructDeserializer"),
|
||||
}
|
||||
}
|
||||
data.* = offset_mem;
|
||||
return ret;
|
||||
}
|
||||
}.deserialize;
|
||||
}
|
||||
|
||||
pub fn Table2Struct(comptime table_type: type) type {
|
||||
|
||||
const fields = std.meta.fields(table_type);
|
||||
const field = fields[std.meta.fieldIndex(table_type, "spacetime_10.0__table_").?];
|
||||
const struct_type = @as(*const field.type, @alignCast(@ptrCast(field.default_value.?))).*;
|
||||
const table_name: []const u8 = struct_type.name.?;
|
||||
|
||||
return struct {
|
||||
allocator: std.mem.Allocator,
|
||||
|
||||
pub const Iter = struct {
|
||||
allocator: std.mem.Allocator,
|
||||
handle: spacetime.RowIter,
|
||||
buffer: [0x20_000]u8 = undefined,
|
||||
contents: []u8 = undefined,
|
||||
last_ret: i16 = spacetime.OK,
|
||||
|
||||
pub fn next(self: *@This()) !?*table_type {
|
||||
var buffer_len: usize = undefined;
|
||||
while(true)
|
||||
{
|
||||
var ret = self.last_ret;
|
||||
if(self.contents.len == 0) {
|
||||
if(self.handle._inner == spacetime.RowIter.INVALID._inner) {
|
||||
return null;
|
||||
}
|
||||
buffer_len = self.buffer.len;
|
||||
ret = spacetime.row_iter_bsatn_advance(self.handle, @constCast(@ptrCast(&self.buffer)), &buffer_len);
|
||||
self.contents = self.buffer[0..buffer_len];
|
||||
|
||||
if(ret == spacetime.EXHAUSTED) {
|
||||
self.handle = spacetime.RowIter.INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
switch(ret) {
|
||||
spacetime.EXHAUSTED, spacetime.OK => {
|
||||
return StructDeserializer(table_type)(self.allocator, &self.contents);
|
||||
},
|
||||
spacetime.BUFFER_TOO_SMALL => {
|
||||
return error.BUFFER_TOO_SMALL;
|
||||
},
|
||||
spacetime.NO_SUCH_ITER => {
|
||||
return error.NO_SUCH_ITER;
|
||||
},
|
||||
else => {
|
||||
var buffer: [512]u8 = undefined;
|
||||
const msg = try std.fmt.bufPrint(&buffer, "Iter Err: {}!", .{ ret });
|
||||
console_log(2, null, 0, null, 0, 0, msg.ptr, msg.len);
|
||||
@panic("Fix Me!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
pub fn insert(self: @This(), data: table_type) void {
|
||||
var id: TableId = undefined;
|
||||
_ = spacetime.table_id_from_name(table_name.ptr, table_name.len, &id);
|
||||
const raw_data = StructSerializer(table_type)(self.allocator, data) catch return;
|
||||
defer self.allocator.free(raw_data);
|
||||
var raw_data_len: usize = raw_data.len;
|
||||
_ = spacetime.datastore_insert_bsatn(id, raw_data.ptr, &raw_data_len);
|
||||
}
|
||||
|
||||
pub fn iter(self: @This()) Iter {
|
||||
var id: TableId = undefined;
|
||||
_ = spacetime.table_id_from_name(table_name.ptr, table_name.len, &id);
|
||||
var rowIter: spacetime.RowIter = undefined;
|
||||
_ = spacetime.datastore_table_scan_bsatn(id, &rowIter);
|
||||
return Iter{
|
||||
.allocator = self.allocator,
|
||||
.handle = rowIter,
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub const Local = struct {
|
||||
pub fn get(self: @This(), table: anytype) Table2Struct(@TypeOf(table)) {
|
||||
_ = self;
|
||||
allocator: std.mem.Allocator,
|
||||
|
||||
pub fn get(self: @This(), table: anytype) Table2Struct(table) {
|
||||
return .{
|
||||
//.name = "blahsss",
|
||||
.allocator = self.allocator,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue