.
This commit is contained in:
parent
29c136d34c
commit
5a79ae71c0
2
.vscode/tasks.json
vendored
2
.vscode/tasks.json
vendored
@ -17,7 +17,7 @@
|
||||
"focus": false,
|
||||
"panel": "shared",
|
||||
"showReuseMessage": true,
|
||||
"clear": false
|
||||
"clear": true,
|
||||
},
|
||||
"problemMatcher": [],
|
||||
"group": {
|
||||
|
||||
41
build.zig
41
build.zig
@ -32,7 +32,7 @@ pub fn build(b: *std.Build) void {
|
||||
.imports = &.{
|
||||
.{
|
||||
.name = "shared",
|
||||
.module = shared
|
||||
.module = shared,
|
||||
},
|
||||
},
|
||||
}),
|
||||
@ -46,7 +46,10 @@ pub fn build(b: *std.Build) void {
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.imports = &.{
|
||||
.{ .name = "shared", .module = shared },
|
||||
.{
|
||||
.name = "shared",
|
||||
.module = shared,
|
||||
},
|
||||
},
|
||||
}),
|
||||
.use_llvm = true,
|
||||
@ -62,17 +65,20 @@ pub fn build(b: *std.Build) void {
|
||||
.enable_tracy = true,
|
||||
.enable_fibers = false,
|
||||
.on_demand = false,
|
||||
}
|
||||
},
|
||||
);
|
||||
client.root_module.addImport("tracy", tracy.module("tracy"));
|
||||
}
|
||||
|
||||
// freetype
|
||||
{
|
||||
const freetype = b.dependency("freetype", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
const freetype = b.dependency(
|
||||
"freetype",
|
||||
.{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
}
|
||||
);
|
||||
client.root_module.addImport("freetype", freetype.module("freetype"));
|
||||
}
|
||||
|
||||
@ -170,29 +176,32 @@ pub fn build(b: *std.Build) void {
|
||||
|
||||
b.getInstallStep().dependOn(&assets.step);
|
||||
|
||||
const run_step = b.step("run", "Run the app");
|
||||
const run_client_step = b.step("run-client", "Run the client");
|
||||
const run_server_step = b.step("run-server", "Run the server");
|
||||
|
||||
const run_cmd_client = b.addRunArtifact(client);
|
||||
const run_cmd_server = b.addRunArtifact(server);
|
||||
run_step.dependOn(&run_cmd_client.step);
|
||||
run_step.dependOn(&run_cmd_server.step);
|
||||
run_client_step.dependOn(&run_cmd_client.step);
|
||||
run_server_step.dependOn(&run_cmd_server.step);
|
||||
|
||||
run_cmd_client.step.dependOn(b.getInstallStep());
|
||||
run_cmd_server.step.dependOn(b.getInstallStep());
|
||||
|
||||
if (b.args) |args| {
|
||||
run_cmd_client.addArgs(args);
|
||||
run_cmd_server.addArgs(args);
|
||||
}
|
||||
|
||||
// Creates an executable that will run `test` blocks from the provided module.
|
||||
// Here `mod` needs to define a target, which is why earlier we made sure to
|
||||
// set the releative field.
|
||||
// const mod_tests = b.addTest(.{
|
||||
// .root_module = mod,
|
||||
// });
|
||||
const shared_tests = b.addTest(.{
|
||||
.root_module = shared,
|
||||
.use_llvm = true,
|
||||
});
|
||||
|
||||
// A run step that will run the test executable.
|
||||
// const run_mod_tests = b.addRunArtifact(mod_tests);
|
||||
const run_shared_tests = b.addRunArtifact(shared_tests);
|
||||
|
||||
// Creates an executable that will run `test` blocks from the executable's
|
||||
// root module. Note that test executables only test one module at a time,
|
||||
@ -207,8 +216,8 @@ pub fn build(b: *std.Build) void {
|
||||
// A top level step for running all tests. dependOn can be called multiple
|
||||
// times and since the two run steps do not depend on one another, this will
|
||||
// make the two of them run in parallel.
|
||||
// const test_step = b.step("test", "Run tests");
|
||||
// test_step.dependOn(&run_mod_tests.step);
|
||||
const test_step = b.step("test", "Run tests");
|
||||
test_step.dependOn(&run_shared_tests.step);
|
||||
// test_step.dependOn(&run_exe_tests.step);
|
||||
|
||||
// Just like flags, top level steps are also listed in the `--help` menu.
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
const std = @import("std");
|
||||
const std = @import("std");
|
||||
const shared = @import("shared");
|
||||
|
||||
const ConnectState = union(enum) {
|
||||
disconnected,
|
||||
|
||||
@ -14,8 +14,9 @@ const client = @import("client.zig");
|
||||
const entity = @import("entity.zig");
|
||||
const misc = @import("misc.zig");
|
||||
const font = @import("font.zig");
|
||||
const chunk = @import("chunk.zig");
|
||||
|
||||
const dt : f32 = 1.0 / 200.0;
|
||||
const dt : f32 = 1.0 / 240.0;
|
||||
var t : f32 = 0;
|
||||
var gt : f32 = 0;
|
||||
var accumulator : f32 = 0;
|
||||
@ -29,6 +30,8 @@ var running: bool = true;
|
||||
|
||||
var dbg_allocator = std.heap.DebugAllocator(.{}){};
|
||||
|
||||
var the_chunk : shared.chunk.Chunk = undefined;
|
||||
|
||||
pub fn main() !void {
|
||||
const tracy_zone = tracy.ZoneNC(@src(), "main", 0x00_ff_00_00);
|
||||
defer tracy_zone.End();
|
||||
@ -83,14 +86,14 @@ pub fn main() !void {
|
||||
const host = enet.enet_host_create(null, 32, 2, 0, 0);
|
||||
defer enet.enet_host_destroy(host);
|
||||
|
||||
var address = enet.ENetAddress{ .port = shared.protocol.SERVER_PORT };
|
||||
var address = enet.ENetAddress{ .port = shared.protocol_v1.SERVER_PORT };
|
||||
_ = enet.enet_address_set_host(&address, "localhost");
|
||||
|
||||
const peer = enet.enet_host_connect(host, &address, 2, 0);
|
||||
defer enet.enet_peer_reset(peer);
|
||||
|
||||
var the_chunk = try shared.chunk.initChunk(allocator);
|
||||
defer shared.chunk.deinitChunk(&the_chunk, allocator);
|
||||
the_chunk = try shared.chunk.Chunk.init(allocator);
|
||||
defer the_chunk.deinit(allocator);
|
||||
|
||||
// const camera = rl.Camera{
|
||||
// .fovy = 45,
|
||||
@ -135,13 +138,14 @@ pub fn main() !void {
|
||||
switch (event.type) {
|
||||
enet.ENET_EVENT_TYPE_CONNECT => {
|
||||
std.log.info("A new client connected from {d}:{d}.", .{
|
||||
event.peer.*.address.host,
|
||||
event.peer.*.address.port});
|
||||
event.peer.*.address.host,
|
||||
event.peer.*.address.port
|
||||
});
|
||||
|
||||
event.peer.*.data = @constCast(@ptrCast("Client information"));
|
||||
},
|
||||
enet.ENET_EVENT_TYPE_RECEIVE => {
|
||||
try on_packet(event.packet, event.peer, event.channelID);
|
||||
try on_packet(allocator, event.packet, event.peer, event.channelID);
|
||||
|
||||
enet.enet_packet_destroy(event.packet);
|
||||
},
|
||||
@ -163,6 +167,7 @@ pub fn main() !void {
|
||||
// rl.updateMusicStream(music);
|
||||
|
||||
while (accumulator > dt * k) {
|
||||
the_chunk.update(dt * k);
|
||||
accumulator -= dt * k;
|
||||
gt += dt * k;
|
||||
}
|
||||
@ -320,7 +325,7 @@ pub fn main() !void {
|
||||
}
|
||||
}
|
||||
|
||||
fn on_packet(packet: *enet.ENetPacket, peer: *enet.ENetPeer, channelID: i32) !void {
|
||||
fn on_packet(allocator: std.mem.Allocator, packet: *enet.ENetPacket, peer: *enet.ENetPeer, channelID: i32) !void {
|
||||
// std.log.info("A packet of length {d} containing {s} was received from {s} on channel {d}.", .{
|
||||
// packet.*.dataLength,
|
||||
// packet.*.data,
|
||||
@ -331,27 +336,72 @@ fn on_packet(packet: *enet.ENetPacket, peer: *enet.ENetPeer, channelID: i32) !vo
|
||||
_ = channelID;
|
||||
|
||||
const bytes: []const u8 = packet.*.data[0 .. packet.*.dataLength];
|
||||
|
||||
std.log.info("{d} bytes: {s}", .{bytes.len, bytes});
|
||||
|
||||
// var buffer2: [4096]u8 = undefined;
|
||||
// var fixed2 = std.io.Writer.fixed(&buffer2);
|
||||
var reader = shared.bits.BitReader.init(bytes);
|
||||
|
||||
// var inspector = bufzilla.Inspect(.{}).init(encoded, &fixed2, .{});
|
||||
// try inspector.inspect();
|
||||
const msg : shared.protocol_v1.Message = try reader.deserialize(allocator, shared.protocol_v1.Message);
|
||||
|
||||
// std.log.info("{s}\n", .{fixed2.buffered()});
|
||||
try on_message(allocator, msg);
|
||||
}
|
||||
|
||||
// var r = bufzilla.Reader(.{}).init(encoded);
|
||||
fn on_message(allocator: std.mem.Allocator, msg: shared.protocol_v1.Message) !void {
|
||||
switch (msg) {
|
||||
.spawn_entity => |se| { try on_spawn_entity(allocator, se); },
|
||||
.update_entity => |ue| { on_update_entity(ue); },
|
||||
.despawn_entity => |de| { on_despawn_entity(allocator, de); },
|
||||
}
|
||||
}
|
||||
|
||||
// Read values sequentially
|
||||
fn on_spawn_entity(allocator: std.mem.Allocator, se: shared.protocol_v1.SpawnEntity) !void {
|
||||
// _ = allocator; _ = se;
|
||||
switch (se) {
|
||||
.soldier => |s| {
|
||||
const soldier = shared.entity.Soldier{
|
||||
.id = s.id,
|
||||
.hp = s.hp,
|
||||
.pos = s.pos,
|
||||
.vel = s.vel,
|
||||
};
|
||||
_ = try chunk.spawn(&the_chunk, allocator, shared.entity.Soldier, soldier);
|
||||
},
|
||||
.alien => |a| {
|
||||
const alien = shared.entity.Alien{
|
||||
.id = a.id,
|
||||
.hp = a.hp,
|
||||
.pos = a.pos,
|
||||
};
|
||||
_ = try chunk.spawn(&the_chunk, allocator, shared.entity.Alien, alien);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// const e = try shared.protocol.Soldier_v1.decode(&r);
|
||||
// _ = e;
|
||||
fn on_update_entity(ue: shared.protocol_v1.UpdateEntity) void {
|
||||
switch (ue) {
|
||||
.soldier => |s| {
|
||||
if (chunk.findT(&the_chunk, shared.entity.Soldier, s.id)) |soldier| {
|
||||
soldier.hp = s.hp;
|
||||
soldier.pos = s.pos;
|
||||
soldier.vel = s.vel;
|
||||
}
|
||||
},
|
||||
.alien => |a| {
|
||||
if (chunk.findT(&the_chunk, shared.entity.Alien, a.id)) |alien| {
|
||||
alien.hp = a.hp;
|
||||
alien.pos = a.pos;
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn on_despawn_entity(allocator: std.mem.Allocator, de: shared.protocol_v1.DespawnEntity) void {
|
||||
switch (de) {
|
||||
.soldier => |s| { _ = chunk.despawn(&the_chunk, allocator, s.id); },
|
||||
.alien => |a| { _ = chunk.despawn(&the_chunk, allocator, a.id); },
|
||||
}
|
||||
}
|
||||
|
||||
fn connect() !void {
|
||||
// const address = try std.net.Address.parseIp4("127.0.0.1", shared.protocol.SERVER_PORT);
|
||||
// const address = try std.net.Address.parseIp4("127.0.0.1", shared.protocol_v1.SERVER_PORT);
|
||||
|
||||
// connection = try std.net.tcpConnectToAddress(address);
|
||||
|
||||
|
||||
@ -5,66 +5,52 @@ const shared = @import("shared");
|
||||
const server = @import("server.zig");
|
||||
const enet = @import("c.zig").enet;
|
||||
|
||||
pub fn spawn(allocator: std.mem.Allocator, host: *enet.ENetHost, chunk: *shared.chunk.Chunk, comptime T: type, value: T) !void {
|
||||
pub fn spawn(self: *shared.chunk.Chunk, allocator: std.mem.Allocator, host: *enet.ENetHost, comptime T: type, value: T) !shared.entity.id {
|
||||
std.debug.assert(value.id == shared.entity.INVALID_ID);
|
||||
|
||||
const id = server.next_entity_id;
|
||||
server.next_entity_id += 1;
|
||||
|
||||
var entity = value;
|
||||
entity.id = id;
|
||||
const ptr = try allocator.create(T);
|
||||
errdefer allocator.destroy(ptr);
|
||||
|
||||
ptr.* = value;
|
||||
ptr.id = id;
|
||||
|
||||
const ref = shared.entity.makeRef(T, ptr);
|
||||
|
||||
try self.entities.append(allocator, ref);
|
||||
|
||||
_ = host;
|
||||
|
||||
inline for (@typeInfo(shared.chunk.Chunk).@"struct".fields) |field| {
|
||||
if (field.type == std.ArrayList(T)) {
|
||||
try @field(chunk, field.name).append(allocator, entity);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// std.log.info("{}", .{shared.protocol.makeSpawnMessage(T, entity)});
|
||||
|
||||
// serialize entity
|
||||
var buffer: [128]u8 = undefined;
|
||||
var fixed = std.io.Writer.fixed(&buffer);
|
||||
|
||||
// const msg = shared.protocol.makeSpawnMessage(T, entity);
|
||||
|
||||
// var writer = bufzilla.Writer.init(&fixed);
|
||||
// try writer.writeAny(msg);
|
||||
// const data = fixed.buffered();
|
||||
// const packet = enet.enet_packet_create(data.ptr, data.len + 1, enet.ENET_PACKET_FLAG_RELIABLE);
|
||||
|
||||
// std.log.info("{s}", .{fixed.buffered()});
|
||||
// enet.enet_host_broadcast(host, 0, packet);
|
||||
|
||||
// var buffer2: [4096]u8 = undefined;
|
||||
// var fixed2 = std.io.Writer.fixed(&buffer2);
|
||||
|
||||
// var inspector = bufzilla.Inspect(.{}).init(fixed.buffered(), &fixed2, .{});
|
||||
// try inspector.inspect();
|
||||
|
||||
// std.log.info("{}", .{msg});
|
||||
|
||||
// std.debug.print("{s}\n", .{fixed2.buffered()});
|
||||
|
||||
const data = fixed.buffered();
|
||||
const packet = enet.enet_packet_create(data.ptr, data.len + 1, enet.ENET_PACKET_FLAG_RELIABLE);
|
||||
|
||||
enet.enet_host_broadcast(host, 0, packet);
|
||||
|
||||
// const encoded = fixed.buffered();
|
||||
|
||||
// const packet = try znet.Packet.init(encoded, 0, .reliable);
|
||||
// var iterator = server.host.iterPeers();
|
||||
|
||||
// while (iterator.next()) |peer| {
|
||||
// if (peer.state() == .connected) {
|
||||
// try peer.send(packet);
|
||||
// }
|
||||
// }
|
||||
return ptr.id;
|
||||
}
|
||||
|
||||
pub fn broadcastChanges(chunk: *shared.chunk.Chunk, host: *enet.ENetHost) !void {
|
||||
_ = chunk;
|
||||
const data = "packet";
|
||||
const packet = enet.enet_packet_create(data, data.len + 1, enet.ENET_PACKET_FLAG_RELIABLE);
|
||||
pub fn broadcastChanges(chunk: *shared.chunk.Chunk, allocator: std.mem.Allocator, host: *enet.ENetHost) !void {
|
||||
var aw = try std.ArrayList(u8).initCapacity(allocator, 128);
|
||||
defer aw.deinit(allocator);
|
||||
|
||||
var writer = shared.bits.BitWriter.init(&aw);
|
||||
|
||||
for (chunk.entities.items) |e| {
|
||||
const msg = shared.protocol_v1.makeUpdateMessage(e);
|
||||
try writer.serialize(allocator, msg);
|
||||
}
|
||||
|
||||
const encoded = writer.written();
|
||||
|
||||
const packet = enet.enet_packet_create(encoded.ptr, encoded.len, enet.ENET_PACKET_FLAG_RELIABLE);
|
||||
|
||||
enet.enet_host_broadcast(host, 0, packet);
|
||||
}
|
||||
|
||||
@ -8,17 +8,18 @@ const shared = @import("shared");
|
||||
const chunk = @import("chunk.zig");
|
||||
const server = @import("server.zig");
|
||||
|
||||
const dt : f32 = 1.0 / 200.0;
|
||||
const dt : f32 = 1.0 / 240.0;
|
||||
var t : f32 = 0;
|
||||
var gt : f32 = 0;
|
||||
var accumulator : f32 = 0;
|
||||
var k : f32 = 1.0;
|
||||
var frame : i32 = 0;
|
||||
|
||||
var send_accumulator : f32 = 0;
|
||||
const frame_dt_ns: i128 = std.time.ns_per_s / 10;
|
||||
|
||||
var dbg_allocator = std.heap.DebugAllocator(.{}){};
|
||||
|
||||
const log = std.log.scoped(.server);
|
||||
|
||||
pub fn main() !void {
|
||||
|
||||
const allocator = dbg_allocator.allocator();
|
||||
@ -33,46 +34,52 @@ pub fn main() !void {
|
||||
_ = try stdout.write("Hello, Server!\n");
|
||||
|
||||
if (enet.enet_initialize() != 0) {
|
||||
std.log.info("Failed to load ENet", .{});
|
||||
log.info("Failed to load ENet", .{});
|
||||
return;
|
||||
}
|
||||
defer enet.enet_deinitialize();
|
||||
|
||||
const address = enet.ENetAddress{ .host = enet.ENET_HOST_ANY, .port = shared.protocol.SERVER_PORT };
|
||||
const address = enet.ENetAddress{ .host = enet.ENET_HOST_ANY, .port = shared.protocol_v1.SERVER_PORT };
|
||||
const host = enet.enet_host_create(&address, 32, 2, 0, 0);
|
||||
if (host == null) {
|
||||
@panic("host is null");
|
||||
}
|
||||
defer enet.enet_host_destroy(host);
|
||||
|
||||
var the_chunk = try shared.chunk.initChunk(allocator);
|
||||
defer shared.chunk.deinitChunk(&the_chunk, allocator);
|
||||
var the_chunk = try shared.chunk.Chunk.init(allocator);
|
||||
defer the_chunk.deinit(allocator);
|
||||
|
||||
try chunk.spawn(
|
||||
_ = try chunk.spawn(
|
||||
&the_chunk,
|
||||
allocator,
|
||||
host,
|
||||
&the_chunk,
|
||||
shared.entity.Soldier,
|
||||
.{
|
||||
.hp = 10,
|
||||
.pos = zm.f32x4(5.0, 0, 0, 0),
|
||||
.vel = zm.f32x4(0, 0, 0, 0),
|
||||
.vel = zm.f32x4(0, 0, 0, 0),
|
||||
}
|
||||
);
|
||||
|
||||
var old_time = std.time.nanoTimestamp();
|
||||
var last_time: i128 = std.time.nanoTimestamp();
|
||||
var next_frame_deadline: i128 = last_time + frame_dt_ns;
|
||||
|
||||
var accumulator: f32 = 0;
|
||||
|
||||
while (true) {
|
||||
const new_time = std.time.nanoTimestamp();
|
||||
var frame_time : f32 = @as(f32, @floatFromInt(new_time - old_time)) / 1_000_000_000.0;
|
||||
old_time = new_time;
|
||||
const now = std.time.nanoTimestamp();
|
||||
var delta_ns = now - last_time;
|
||||
last_time = now;
|
||||
|
||||
if (frame_time > 0.25)
|
||||
frame_time = 0.25;
|
||||
if (delta_ns > std.time.ns_per_s / 4)
|
||||
delta_ns = std.time.ns_per_s / 4;
|
||||
|
||||
t += frame_time;
|
||||
accumulator += frame_time * k;
|
||||
send_accumulator += frame_time;
|
||||
const delta_s: f32 = @floatCast(@as(f64, @floatFromInt(delta_ns)) / 1e9);
|
||||
|
||||
t += delta_s;
|
||||
accumulator += delta_s * k;
|
||||
|
||||
log.info("Starting a the frame {} at time {}", .{frame, t});
|
||||
|
||||
var event = enet.ENetEvent{};
|
||||
while (enet.enet_host_service(host, &event, 0) > 0) {
|
||||
@ -81,10 +88,10 @@ pub fn main() !void {
|
||||
try on_connect(allocator, host, event.peer, &the_chunk);
|
||||
},
|
||||
enet.ENET_EVENT_TYPE_RECEIVE => {
|
||||
std.log.info("receive", .{});
|
||||
log.info("receive", .{});
|
||||
},
|
||||
enet.ENET_EVENT_TYPE_DISCONNECT => {
|
||||
std.log.info("disconnect", .{});
|
||||
log.info("disconnect", .{});
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
@ -97,7 +104,7 @@ pub fn main() !void {
|
||||
// var reader = connection.stream.reader(&recv_buffer);
|
||||
|
||||
// const line = try reader.interface().takeDelimiterExclusive('\n');
|
||||
// std.log.info("Received: {s}", .{line});
|
||||
// log.info("Received: {s}", .{line});
|
||||
|
||||
// var send_buffer: [4096]u8 = undefined;
|
||||
// var writer = connection.stream.writer(&send_buffer);
|
||||
@ -115,18 +122,29 @@ pub fn main() !void {
|
||||
// }, w);
|
||||
|
||||
while (accumulator > dt * k) {
|
||||
shared.chunk.updateChunk(&the_chunk);
|
||||
the_chunk.update(dt * k);
|
||||
|
||||
accumulator -= dt * k;
|
||||
gt += dt * k;
|
||||
}
|
||||
|
||||
if (send_accumulator > 1) {
|
||||
// try chunk.broadcastChanges(&the_chunk, host);
|
||||
try chunk.broadcastChanges(&the_chunk, allocator, host);
|
||||
|
||||
send_accumulator = 0;
|
||||
const spin_ns: i128 = 100_000; // 0.1 ms
|
||||
|
||||
while (true) {
|
||||
const _t = std.time.nanoTimestamp();
|
||||
const remaining = next_frame_deadline - _t;
|
||||
|
||||
if (remaining <= 0)
|
||||
break;
|
||||
|
||||
if (remaining > spin_ns)
|
||||
std.Thread.sleep(@intCast(remaining - spin_ns));
|
||||
}
|
||||
|
||||
next_frame_deadline += frame_dt_ns;
|
||||
|
||||
frame += 1;
|
||||
}
|
||||
}
|
||||
@ -137,74 +155,18 @@ fn on_connect(allocator: std.mem.Allocator, host: *enet.ENetHost, peer: *enet.EN
|
||||
|
||||
_ = peer;
|
||||
|
||||
// var w = bufzilla.Writer.init(&aw.writer);
|
||||
|
||||
var writer = shared.bits.BitWriter.init(&aw);
|
||||
|
||||
// Write 3 bits (101)
|
||||
try writer.write(allocator, @as(u3, 0x5));
|
||||
// Write 1 bit (true = 1)
|
||||
try writer.write(allocator, true);
|
||||
// Write 4 bits (0000)
|
||||
try writer.write(allocator, @as(u3, 0x1));
|
||||
|
||||
try writer.write(allocator, @as(u4, 0xE));
|
||||
|
||||
try writer.write(allocator, @as(u32, 0xFFFFFFFA));
|
||||
|
||||
var reader = shared.bits.BitReader.init(writer.written());
|
||||
|
||||
const _1 : u3 = reader.read(u3);
|
||||
const _2 : bool = reader.read(bool);
|
||||
const _3 : u3 = reader.read(u3);
|
||||
const _4 : u4 = reader.read(u4);
|
||||
const _5 : u32 = reader.read(u32);
|
||||
|
||||
std.log.info("_1: {}", .{_1});
|
||||
std.log.info("_1: {}", .{_2});
|
||||
std.log.info("_1: {}", .{_3});
|
||||
std.log.info("_1: {}", .{_4});
|
||||
std.log.info("_1: {}", .{_5});
|
||||
|
||||
const fields = @typeInfo(shared.chunk.Chunk).@"struct".fields;
|
||||
|
||||
inline for (fields) |field| {
|
||||
const list = &@field(the_chunk, field.name);
|
||||
|
||||
// const itemsType = @FieldType(field.type, "items");
|
||||
// const T = std.meta.Child(itemsType);
|
||||
|
||||
for (list.items) |entity| {
|
||||
|
||||
// const msg = shared.protocol.makeSpawnMessage(T, entity);
|
||||
|
||||
// w.write(entity);
|
||||
|
||||
std.log.info("{}", .{entity});
|
||||
|
||||
// try writer.writeAny(msg);
|
||||
}
|
||||
for (the_chunk.entities.items) |e| {
|
||||
const msg = shared.protocol_v1.makeSpawnMessage(e);
|
||||
try writer.serialize(allocator, msg);
|
||||
}
|
||||
|
||||
// const encoded = aw.written();
|
||||
|
||||
// std.log.info("{d} bytes: {s}", .{encoded.len, encoded});
|
||||
|
||||
// var buffer2: [4096]u8 = undefined;
|
||||
// var fixed2 = std.io.Writer.fixed(&buffer2);
|
||||
|
||||
// var inspector = bufzilla.Inspect(.{}).init(encoded, &fixed2, .{});
|
||||
// try inspector.inspect();
|
||||
|
||||
// std.log.info("{s}\n", .{fixed2.buffered()});
|
||||
const encoded = writer.written();
|
||||
|
||||
// const packet = enet.enet_packet_create(encoded.ptr, encoded.len, enet.ENET_PACKET_FLAG_RELIABLE);
|
||||
const packet = enet.enet_packet_create(encoded.ptr, encoded.len, enet.ENET_PACKET_FLAG_RELIABLE);
|
||||
|
||||
// enet.enet_host_broadcast(host, 0, packet);
|
||||
_ = host;
|
||||
// if (enet.enet_peer_send(peer, 0, packet) != 0) {
|
||||
// std.log.err("Could not send packet to peer.", .{});
|
||||
// }
|
||||
enet.enet_host_broadcast(host, 0, packet);
|
||||
}
|
||||
|
||||
//fn handle_connection(connection: std.net.Server.Connection) !void {}
|
||||
|
||||
@ -1,5 +1,38 @@
|
||||
const std = @import("std");
|
||||
|
||||
// pub fn serialize(writer: *BitWriter, allocator: std.mem.Allocator, comptime T: type, value: T) !void {
|
||||
// const info = @typeInfo(T);
|
||||
|
||||
// switch (info) {
|
||||
// .int, .bool => {
|
||||
// try writer.write(allocator, T, value);
|
||||
// },
|
||||
|
||||
// .@"struct" => |s| {
|
||||
// if (!s.is_packed)
|
||||
// @compileError("serialize only supports packed structs (got " ++ @typeName(T) ++ ")");
|
||||
|
||||
// inline for (s.fields) |field| {
|
||||
// const field_value = @field(value, field.name);
|
||||
// try serialize(writer, allocator, field_value);
|
||||
// }
|
||||
// },
|
||||
|
||||
// .@"union" => |u| {
|
||||
// if (u.layout != .@"packed")
|
||||
// @compileError("serialize only supports packed structs (got " ++ @typeName(T) ++ ")");
|
||||
|
||||
// inline for (u.fields) |field| {
|
||||
// const field_value = @field(value, field.name);
|
||||
// try serialize(writer, allocator, field_value);
|
||||
// }
|
||||
// },
|
||||
|
||||
// else => @compileError("Unsupported type in serialize: " ++ @typeName(T)),
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
pub const BitWriter = struct {
|
||||
// We store a pointer to the ArrayList so we can grow it
|
||||
bytes: *std.ArrayList(u8),
|
||||
@ -9,15 +42,54 @@ pub const BitWriter = struct {
|
||||
return .{ .bytes = bytes };
|
||||
}
|
||||
|
||||
pub fn write(self: *BitWriter, allocator: std.mem.Allocator, value: anytype) !void {
|
||||
pub fn serialize(self: *BitWriter, allocator: std.mem.Allocator, value: anytype) !void {
|
||||
const T = @TypeOf(value);
|
||||
const info = @typeInfo(T);
|
||||
|
||||
const bit_width = switch (info) {
|
||||
.int => |int| int.bits,
|
||||
.bool => 1,
|
||||
else => @compileError("Unsupported type: " ++ @typeName(T)),
|
||||
};
|
||||
switch (info) {
|
||||
.@"struct" => |s| {
|
||||
inline for (s.fields) |f|
|
||||
try self.serialize(allocator, @field(value, f.name));
|
||||
},
|
||||
.@"union" => |u| {
|
||||
const E = u.tag_type orelse @compileError(std.fmt.comptimePrint("Union {s} has to tag type.", .{@typeName(T)}));
|
||||
try self.serialize(allocator, @as(E, value));
|
||||
switch (value) {
|
||||
inline else => |f| try self.serialize(allocator, f),
|
||||
}
|
||||
},
|
||||
.@"enum" => try self.serialize(allocator, @intFromEnum(value)),
|
||||
.pointer => |p| switch (p.size) {
|
||||
.one => try self.serialize(allocator, value.*),
|
||||
.slice => {
|
||||
try self.serialize(allocator, value.len);
|
||||
for (value) |e|
|
||||
try self.serialize(allocator, e);
|
||||
},
|
||||
.many, .c => @compileError(std.fmt.comptimePrint("Unsupported type: {}", .{T})),
|
||||
},
|
||||
.int, .bool, .float, => try self.write(allocator, value),
|
||||
.void => {},
|
||||
.array => |a| if (@sizeOf(a.child) == 1) {
|
||||
try self.write(allocator, @ptrCast(&value));
|
||||
} else {
|
||||
for (value) |e|
|
||||
try self.serialize(allocator, e);
|
||||
},
|
||||
.optional => if (value) |_t| {
|
||||
try self.serialize(allocator, true);
|
||||
try self.serialize(allocator, _t);
|
||||
} else {
|
||||
try self.serialize(allocator, false);
|
||||
},
|
||||
.vector => |v| try self.serialize(allocator, @as([v.len]v.child, value)),
|
||||
else => @compileError(std.fmt.comptimePrint("Unsupported type: {}", .{T})),
|
||||
}
|
||||
}
|
||||
|
||||
fn write(self: *BitWriter, allocator: std.mem.Allocator, value: anytype) !void {
|
||||
const T = @TypeOf(value);
|
||||
const bit_width = @bitSizeOf(T);
|
||||
|
||||
const UnsignedT = std.meta.Int(.unsigned, bit_width);
|
||||
const bits_to_write = @as(UnsignedT, @bitCast(value));
|
||||
@ -60,14 +132,64 @@ pub const BitReader = struct {
|
||||
return .{ .bytes = bytes };
|
||||
}
|
||||
|
||||
pub fn read(self: *BitReader, comptime T: type) T {
|
||||
const info = @typeInfo(T);
|
||||
|
||||
const bit_width = switch (info) {
|
||||
.int => |int| int.bits,
|
||||
.bool => 1,
|
||||
else => @compileError("Unsupported type: " ++ @typeName(T)),
|
||||
pub fn deserialize(self: *BitReader, allocator: std.mem.Allocator, T: type) !T {
|
||||
return switch (@typeInfo(T)) {
|
||||
.@"struct" => |s| b: {
|
||||
var data: T = undefined;
|
||||
inline for (s.fields) |f|
|
||||
@field(data, f.name) = try self.deserialize(allocator, f.type);
|
||||
break :b data;
|
||||
},
|
||||
.@"union" => |u| switch (try self.deserialize(allocator, u.tag_type.?)) {
|
||||
inline else => |t| b: {
|
||||
var data: T = @unionInit(T, @tagName(t), undefined);
|
||||
const field = &@field(data, @tagName(t));
|
||||
field.* = try self.deserialize(allocator, @TypeOf(field.*));
|
||||
break :b data;
|
||||
},
|
||||
},
|
||||
.@"enum" => |e| @enumFromInt(try self.deserialize(allocator, e.tag_type)),
|
||||
.pointer => |p| switch (p.size) {
|
||||
.one => b: {
|
||||
const ptr = try allocator.create(p.child);
|
||||
errdefer allocator.destroy(ptr);
|
||||
ptr.* = try self.deserialize(allocator, p.child);
|
||||
break :b ptr;
|
||||
},
|
||||
.slice => b: {
|
||||
const slice = try allocator.alloc(p.child, try self.deserialize(allocator, usize));
|
||||
errdefer allocator.free(slice);
|
||||
for (slice) |*e|
|
||||
e.* = try self.deserialize(allocator, p.child);
|
||||
break :b slice;
|
||||
},
|
||||
.many, .c => @compileError(std.fmt.comptimePrint("Unsupported type: {}", .{T})),
|
||||
},
|
||||
.int, .bool, .float => self.read(T),
|
||||
.void => {},
|
||||
.array => |a| b: {
|
||||
var array: T = undefined;
|
||||
if (@sizeOf(a.child) == 1) {
|
||||
try self.read(&array);
|
||||
} else {
|
||||
for (&array) |*e|
|
||||
e.* = try self.deserialize(allocator, a.child);
|
||||
}
|
||||
break :b array;
|
||||
},
|
||||
.optional => |o| if (try self.deserialize(allocator, bool))
|
||||
try self.deserialize(o.child, allocator)
|
||||
else
|
||||
null,
|
||||
.vector => |v| try self.deserialize(allocator, [v.len]v.child),
|
||||
else => @compileError(std.fmt.comptimePrint("Unsupported type: {}", .{T})),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn read(self: *BitReader, comptime T: type) T {
|
||||
// const info = @typeInfo(T);
|
||||
|
||||
const bit_width = @bitSizeOf(T);
|
||||
|
||||
const UnsignedT = std.meta.Int(.unsigned, bit_width);
|
||||
|
||||
@ -98,3 +220,67 @@ pub const BitReader = struct {
|
||||
return @bitCast(result);
|
||||
}
|
||||
};
|
||||
|
||||
test "Bit Stream" {
|
||||
std.debug.print("Bit Stream\n", .{});
|
||||
const allocator = std.testing.allocator;
|
||||
|
||||
var aw = try std.ArrayList(u8).initCapacity(allocator, 128);
|
||||
defer aw.deinit(allocator);
|
||||
|
||||
var writer = BitWriter.init(&aw);
|
||||
|
||||
const _a : u3 = 0x5;
|
||||
const _b : bool = true;
|
||||
const _c : u3 = 0x1;
|
||||
const _d : u4 = 0xE;
|
||||
const _e : u32 = 0xFFFFFFFA;
|
||||
const _f : i32 = -3;
|
||||
const _g : f32 = 6.667;
|
||||
|
||||
const ts = struct {
|
||||
a: i32,
|
||||
n: []const u8,
|
||||
|
||||
pub fn format(self: @This(), w: *std.io.Writer) !void {
|
||||
|
||||
try w.print(".{{ .a = {}, .n = \"{s}\" }}", .{ self.a, self.n });
|
||||
}
|
||||
};
|
||||
|
||||
const _h : ts = .{
|
||||
.a = 44,
|
||||
.n = "hello",
|
||||
};
|
||||
|
||||
try writer.serialize(allocator, _a);
|
||||
try writer.serialize(allocator, _b);
|
||||
try writer.serialize(allocator, _c);
|
||||
try writer.serialize(allocator, _d);
|
||||
try writer.serialize(allocator, _e);
|
||||
try writer.serialize(allocator, _f);
|
||||
try writer.serialize(allocator, _g);
|
||||
try writer.serialize(allocator, _h);
|
||||
|
||||
var reader = BitReader.init(writer.written());
|
||||
|
||||
const _1 : u3 = try reader.deserialize(allocator, u3);
|
||||
const _2 : bool = try reader.deserialize(allocator, bool);
|
||||
const _3 : u3 = try reader.deserialize(allocator, u3);
|
||||
const _4 : u4 = try reader.deserialize(allocator, u4);
|
||||
const _5 : u32 = try reader.deserialize(allocator, u32);
|
||||
const _6 : i32 = try reader.deserialize(allocator, i32);
|
||||
const _7 = try reader.deserialize(allocator, f32);
|
||||
const _8 = try reader.deserialize(allocator, ts);
|
||||
defer allocator.free(_8.n);
|
||||
|
||||
try std.testing.expectEqual(_a, _1);
|
||||
try std.testing.expectEqual(_b, _2);
|
||||
try std.testing.expectEqual(_c, _3);
|
||||
try std.testing.expectEqual(_d, _4);
|
||||
try std.testing.expectEqual(_e, _5);
|
||||
try std.testing.expectEqual(_f, _6);
|
||||
try std.testing.expectEqual(_g, _7);
|
||||
|
||||
try std.testing.expectEqualDeep(_h, _8);
|
||||
}
|
||||
|
||||
@ -26,63 +26,96 @@ const misc = @import("misc.zig");
|
||||
// };
|
||||
// }
|
||||
|
||||
pub const Chunk = _Chunk();
|
||||
// pub const Chunk = _Chunk();
|
||||
|
||||
fn _Chunk() type {
|
||||
const FieldCount = entity.EntityKinds.len;
|
||||
// fn _Chunk() type {
|
||||
// const FieldCount = entity.EntityKinds.len;
|
||||
|
||||
var fields: [FieldCount]std.builtin.Type.StructField = undefined;
|
||||
// var fields: [FieldCount]std.builtin.Type.StructField = undefined;
|
||||
|
||||
inline for (entity.EntityKinds, 0..) |T, i| {
|
||||
fields[i] = .{
|
||||
.name = misc.short_type_name(T),
|
||||
.type = std.ArrayList(T),
|
||||
.default_value_ptr = null,
|
||||
.is_comptime = false,
|
||||
.alignment = @alignOf(std.ArrayList(T)),
|
||||
// inline for (entity.EntityKinds, 0..) |T, i| {
|
||||
// fields[i] = .{
|
||||
// .name = misc.short_type_name(T),
|
||||
// .type = std.ArrayList(T),
|
||||
// .default_value_ptr = null,
|
||||
// .is_comptime = false,
|
||||
// .alignment = @alignOf(std.ArrayList(T)),
|
||||
// };
|
||||
// }
|
||||
|
||||
// return @Type(.{
|
||||
// .@"struct" = .{
|
||||
// .layout = .auto,
|
||||
// .fields = &fields,
|
||||
// .decls = &.{},
|
||||
// .is_tuple = false,
|
||||
// },
|
||||
// });
|
||||
// }
|
||||
|
||||
// pub fn initChunk(allocator: std.mem.Allocator) !Chunk {
|
||||
// var chunk: Chunk = undefined;
|
||||
|
||||
// inline for (@typeInfo(Chunk).@"struct".fields) |field| {
|
||||
// const ListT = field.type;
|
||||
// @field(chunk, field.name) = try ListT.initCapacity(allocator, 32);
|
||||
// }
|
||||
|
||||
// return chunk;
|
||||
// }
|
||||
|
||||
// pub fn deinitChunk(chunk: *Chunk, allocator: std.mem.Allocator) void {
|
||||
// switch (@typeInfo(Chunk)) {
|
||||
// .@"struct" => |s| {
|
||||
// inline for (s.fields) |field| {
|
||||
// @field(chunk, field.name).deinit(allocator);
|
||||
// }
|
||||
// },
|
||||
// else => unreachable,
|
||||
// }
|
||||
// }
|
||||
|
||||
// pub fn updateChunk(chunk: *Chunk) void {
|
||||
// inline for (@typeInfo(Chunk).@"struct".fields) |field| {
|
||||
// const list = &@field(chunk, field.name);
|
||||
|
||||
// for (list.items, 0..) |*item, i| {
|
||||
// _ = i;
|
||||
// if (@hasDecl(@TypeOf(item.*), "update"))
|
||||
// item.update();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
pub const Chunk = struct {
|
||||
entities : std.ArrayList(entity.Ref),
|
||||
|
||||
pub fn init(allocator: std.mem.Allocator) !Chunk {
|
||||
return .{
|
||||
.entities = try std.ArrayList(entity.Ref).initCapacity(allocator, 128),
|
||||
};
|
||||
}
|
||||
|
||||
return @Type(.{
|
||||
.@"struct" = .{
|
||||
.layout = .auto,
|
||||
.fields = &fields,
|
||||
.decls = &.{},
|
||||
.is_tuple = false,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
pub fn initChunk(allocator: std.mem.Allocator) !Chunk {
|
||||
var chunk: Chunk = undefined;
|
||||
|
||||
inline for (@typeInfo(Chunk).@"struct".fields) |field| {
|
||||
const ListT = field.type;
|
||||
@field(chunk, field.name) = try ListT.initCapacity(allocator, 32);
|
||||
}
|
||||
|
||||
return chunk;
|
||||
}
|
||||
|
||||
pub fn deinitChunk(chunk: *Chunk, allocator: std.mem.Allocator) void {
|
||||
switch (@typeInfo(Chunk)) {
|
||||
.@"struct" => |s| {
|
||||
inline for (s.fields) |field| {
|
||||
@field(chunk, field.name).deinit(allocator);
|
||||
pub fn deinit(self: *@This(), allocator: std.mem.Allocator) void {
|
||||
for (self.entities.items) |ref| {
|
||||
switch (ref) {
|
||||
inline else => |ptr| allocator.destroy(ptr),
|
||||
}
|
||||
},
|
||||
else => unreachable,
|
||||
}
|
||||
|
||||
self.entities.deinit(allocator);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn updateChunk(chunk: *Chunk) void {
|
||||
inline for (@typeInfo(Chunk).@"struct".fields) |field| {
|
||||
const list = &@field(chunk, field.name);
|
||||
|
||||
for (list.items, 0..) |*item, i| {
|
||||
_ = i;
|
||||
if (@hasDecl(@TypeOf(item.*), "update"))
|
||||
item.update();
|
||||
pub fn update(self: *@This(), dt: f32) void {
|
||||
for (self.entities.items) |e| {
|
||||
switch (e) {
|
||||
.Soldier => |s| {
|
||||
s.update(dt);
|
||||
},
|
||||
.Alien => |a| {
|
||||
a.update(dt);
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
const std = @import("std");
|
||||
const zm = @import("zmath");
|
||||
const protocol = @import("protocol.zig");
|
||||
const misc = @import("misc.zig");
|
||||
const std = @import("std");
|
||||
const zm = @import("zmath");
|
||||
const misc = @import("misc.zig");
|
||||
|
||||
pub const id = u64;
|
||||
pub const INVALID_ID: id = 0;
|
||||
@ -11,39 +10,59 @@ pub const EntityKinds = .{
|
||||
Alien,
|
||||
};
|
||||
|
||||
const Entity = struct {
|
||||
|
||||
};
|
||||
|
||||
pub const Soldier = struct {
|
||||
id: id = INVALID_ID,
|
||||
hp: i32,
|
||||
pos: zm.Vec,
|
||||
vel: zm.Vec,
|
||||
hp: i32 = 0,
|
||||
pos: zm.Vec = .{0, 0, 0, 0},
|
||||
vel: zm.Vec = .{0, 0, 0, 0},
|
||||
|
||||
pub fn update(self: *Soldier) void {
|
||||
self.pos += self.vel;
|
||||
pub fn update(self: *@This(), dt: f32) void {
|
||||
self.pos = self.pos + self.vel * zm.splat(zm.Vec, dt);
|
||||
}
|
||||
};
|
||||
|
||||
pub const Alien = struct {
|
||||
id: id = INVALID_ID,
|
||||
pos: zm.Vec,
|
||||
vel: zm.Vec,
|
||||
hp: i32,
|
||||
hp: i32 = 0,
|
||||
pos: zm.Vec = .{0, 0, 0, 0},
|
||||
vel: zm.Vec = .{0, 0, 0, 0},
|
||||
|
||||
pub fn update(self: *Alien) void {
|
||||
self.pos = self.pos + self.vel;
|
||||
pub fn update(self: *@This(), dt: f32) void {
|
||||
self.pos = self.pos + self.vel * zm.splat(zm.Vec, dt);
|
||||
}
|
||||
};
|
||||
|
||||
fn makeUnion() type {
|
||||
fn _Ref() type {
|
||||
const FieldCount = EntityKinds.len;
|
||||
|
||||
var tag_fields: [FieldCount]std.builtin.Type.EnumField = undefined;
|
||||
|
||||
inline for (EntityKinds, 0..) |T, i| {
|
||||
tag_fields[i] = .{
|
||||
.name = misc.short_type_name(T),
|
||||
.value = i,
|
||||
};
|
||||
}
|
||||
|
||||
const Tag = @Type(.{
|
||||
.@"enum" = .{
|
||||
.tag_type = u8,
|
||||
.fields = &tag_fields,
|
||||
.decls = &.{},
|
||||
.is_exhaustive = true,
|
||||
},
|
||||
});
|
||||
|
||||
var fields: [FieldCount]std.builtin.Type.UnionField = undefined;
|
||||
|
||||
inline for (EntityKinds, 0..) |T, i| {
|
||||
fields[i] = .{
|
||||
.name = misc.short_type_name(T),
|
||||
.type = *T,
|
||||
.default_value_ptr = null,
|
||||
.is_comptime = false,
|
||||
.alignment = @alignOf(*T),
|
||||
};
|
||||
}
|
||||
@ -53,9 +72,32 @@ fn makeUnion() type {
|
||||
.layout = .auto,
|
||||
.fields = &fields,
|
||||
.decls = &.{},
|
||||
.tag_type = u8,
|
||||
.tag_type = Tag,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
const EntityRef = makeUnion();
|
||||
pub const Ref = _Ref();
|
||||
|
||||
pub fn setPos(self: Ref, pos: zm.Vec) void {
|
||||
switch (self) {
|
||||
.Soldier => |s| { s.pos = pos; },
|
||||
.Alien => |a| { a.pos = pos; },
|
||||
else => unreachable
|
||||
}
|
||||
}
|
||||
|
||||
pub fn makeRef(comptime T: type, ptr: *T) Ref {
|
||||
inline for (EntityKinds) |U| {
|
||||
if (T == U) {
|
||||
return @unionInit(
|
||||
Ref,
|
||||
misc.short_type_name(U),
|
||||
ptr,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@compileError("Type not in EntityKinds: " ++ @typeName(T));
|
||||
}
|
||||
|
||||
|
||||
@ -1,129 +0,0 @@
|
||||
const std = @import("std");
|
||||
const zm = @import("zmath");
|
||||
// const bufzilla = @import("bufzilla");
|
||||
|
||||
const entity = @import("entity.zig");
|
||||
const bits = @import("bits.zig");
|
||||
|
||||
pub const SERVER_PORT: u16 = 1337;
|
||||
|
||||
pub const Message = union(enum) {
|
||||
spawn_entity: SpawnEntity,
|
||||
// later: despawn_entity, update_entity, snapshot, etc.
|
||||
};
|
||||
|
||||
pub const SpawnEntity = union(enum) {
|
||||
soldier_v1: Soldier_v1,
|
||||
alien_v1: Alien_v1,
|
||||
};
|
||||
|
||||
pub fn makeSpawnMessage(comptime T: type, e: T) Message {
|
||||
if (T == entity.Soldier) {
|
||||
return .{ .spawn_entity = .{ .soldier_v1 = Soldier_v1.init(e) } };
|
||||
} else if (T == entity.Alien) {
|
||||
return .{ .spawn_entity = .{ .alien_v1 = Alien_v1.init(e) } };
|
||||
}
|
||||
}
|
||||
|
||||
// pub fn write_message(writer: *std.Io.Writer, msg_type: MessageType, payload: []const u8) !void {
|
||||
// try writer.writeByte(@intFromEnum(msg_type));
|
||||
// try writer.writeInt(u32, @intCast(payload.len), .little);
|
||||
// try writer.writeAll(payload);
|
||||
// }
|
||||
|
||||
// pub fn read_message(reader: *std.Io.Reader, allocator: std.mem.Allocator) !struct {
|
||||
// msg_type: MessageType,
|
||||
// payload: []u8,
|
||||
// } {
|
||||
// const msg_type = try reader.readByte();
|
||||
// const size = try reader.readInt(u32, .little);
|
||||
|
||||
// const payload = try allocator.alloc(u8, size);
|
||||
// errdefer allocator.free(payload);
|
||||
|
||||
// try reader.readNoEof(payload);
|
||||
|
||||
// return .{
|
||||
// .msg_type = @enumFromInt(msg_type),
|
||||
// .payload = payload,
|
||||
// };
|
||||
// }
|
||||
|
||||
pub const Soldier_v1 = struct {
|
||||
id: entity.id = entity.INVALID_ID,
|
||||
hp: i32,
|
||||
pos: zm.Vec,
|
||||
vel: zm.Vec,
|
||||
|
||||
pub fn init(soldier: entity.Soldier) Soldier_v1 {
|
||||
return .{
|
||||
.id = soldier.id,
|
||||
.hp = soldier.hp,
|
||||
.pos = soldier.pos,
|
||||
.vel = soldier.vel,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn decode() !Soldier_v1 {
|
||||
const soldier_v1 : Soldier_v1 = .{
|
||||
.id = 0,
|
||||
.hp = 0,
|
||||
.pos = .{0, 0, 0, 0},
|
||||
.vel = .{0, 0, 0, 0},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// switch (kv.value) {
|
||||
// .i32 => |val| {
|
||||
// if (std.mem.eql(u8, kv.key.bytes, "hp")) soldier_v1.hp = val;
|
||||
// },
|
||||
// else => {}
|
||||
// }
|
||||
|
||||
return soldier_v1;
|
||||
}
|
||||
};
|
||||
|
||||
pub const Alien_v1 = struct {
|
||||
id: entity.id = entity.INVALID_ID,
|
||||
pos: zm.Vec,
|
||||
hp: i32,
|
||||
|
||||
pub fn init(alien: entity.Alien) Alien_v1 {
|
||||
return .{
|
||||
.id = alien.id,
|
||||
.pos = alien.pos,
|
||||
.hp = alien.hp,
|
||||
};
|
||||
}
|
||||
|
||||
// pub fn encode(self: Alien_v1, w: *std.Io.Writer) !void {
|
||||
// try w.writeInt(u64, self.id, .little);
|
||||
// try writeVec4(w, self.pos);
|
||||
// try writeVec4(w, self.vel);
|
||||
// }
|
||||
|
||||
pub fn decode(r: *std.Io.Reader) !Alien_v1 {
|
||||
return .{
|
||||
.id = try r.readInt(u64, .little),
|
||||
.pos = try readVec4(r),
|
||||
.vel = try readVec4(r),
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
fn writeVec4(w: *std.Io.Writer, v: zm.Vec) !void {
|
||||
const a = zm.vecToArr4(v);
|
||||
inline for (a) |f| {
|
||||
try w.writeFloat(f32, f, .little);
|
||||
}
|
||||
}
|
||||
|
||||
fn readVec4(r: *std.Io.Reader) !zm.Vec4 {
|
||||
var a: [4]f32 = undefined;
|
||||
inline for (&a) |*f| {
|
||||
f.* = try r.readFloat(f32, .little);
|
||||
}
|
||||
return zm.loadArr4(a);
|
||||
}
|
||||
@ -1,5 +1,10 @@
|
||||
pub const entity = @import("entity.zig");
|
||||
pub const chunk = @import("chunk.zig");
|
||||
pub const misc = @import("misc.zig");
|
||||
pub const protocol = @import("protocol.zig");
|
||||
pub const bits = @import("bits.zig");
|
||||
pub const entity = @import("entity.zig");
|
||||
pub const chunk = @import("chunk.zig");
|
||||
pub const misc = @import("misc.zig");
|
||||
pub const protocol_v1 = @import("protocol_v1.zig");
|
||||
pub const bits = @import("bits.zig");
|
||||
|
||||
test {
|
||||
const std = @import("std");
|
||||
std.testing.refAllDecls(@This());
|
||||
}
|
||||
|
||||
1
vendor/freetype/build.zig.zon
vendored
1
vendor/freetype/build.zig.zon
vendored
@ -1,5 +1,6 @@
|
||||
.{
|
||||
.name = .freetype,
|
||||
.fingerprint = 0xac2059b69e282536,
|
||||
.version = "0.1.0",
|
||||
.minimum_zig_version = "0.15.2",
|
||||
.paths = .{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user