working on protocol architecture
This commit is contained in:
parent
510c19fbd5
commit
ee790cf700
@ -131,6 +131,7 @@ pub fn build(b: *std.Build) void {
|
||||
.optimize = optimize,
|
||||
});
|
||||
|
||||
// shared.linkLibrary(enet.artifact("enet"));
|
||||
client.root_module.linkLibrary(enet.artifact("enet"));
|
||||
server.root_module.linkLibrary(enet.artifact("enet"));
|
||||
}
|
||||
|
||||
@ -44,8 +44,8 @@
|
||||
.path = "vendor/enet",
|
||||
},
|
||||
.bufzilla = .{
|
||||
.url = "https://github.com/theseyan/bufzilla/archive/refs/tags/v0.3.2.tar.gz",
|
||||
.hash = "bufzilla-0.3.0-gU6dXi67AQAg3WIFrNQ0iafrvexj3iBwVcczrVzrN3Ir",
|
||||
.url = "https://github.com/theseyan/bufzilla/archive/refs/tags/v0.3.3.tar.gz",
|
||||
.hash = "bufzilla-0.3.0-gU6dXie7AQDTXB7ptRjLa1plj3txaUVKFvT39e3v-pop",
|
||||
},
|
||||
.tracy = .{
|
||||
.path = "vendor/tracy",
|
||||
|
||||
@ -134,10 +134,20 @@ pub fn main() !void {
|
||||
while (enet.enet_host_service(host, &event, 0) > 0) {
|
||||
switch (event.type) {
|
||||
enet.ENET_EVENT_TYPE_CONNECT => {
|
||||
std.log.info("connect", .{});
|
||||
std.log.info("A new client connected from {d}:{d}.", .{
|
||||
event.peer.*.address.host,
|
||||
event.peer.*.address.port});
|
||||
|
||||
event.peer.*.data = @constCast(@ptrCast("Client information"));
|
||||
},
|
||||
enet.ENET_EVENT_TYPE_RECEIVE => {
|
||||
std.log.info("receive", .{});
|
||||
std.log.info("A packet of length {d} containing {s} was received from {s} on channel {d}.", .{
|
||||
event.packet.*.dataLength,
|
||||
event.packet.*.data,
|
||||
@as([*:0]const u8, @ptrCast(event.peer.*.data.?)),
|
||||
event.channelID});
|
||||
|
||||
enet.enet_packet_destroy(event.packet);
|
||||
},
|
||||
enet.ENET_EVENT_TYPE_DISCONNECT => {
|
||||
std.log.info("disconnect", .{});
|
||||
@ -304,7 +314,7 @@ pub fn main() !void {
|
||||
rl.EndDrawing();
|
||||
drawing_zone.End();
|
||||
|
||||
const swap_zone = tracy.ZoneNC(@src(), "swapScreenBuffer", 0x00_ff_00_00);
|
||||
const swap_zone = tracy.ZoneNC(@src(), "SwapScreenBuffer", 0x00_ff_00_00);
|
||||
rl.SwapScreenBuffer();
|
||||
swap_zone.End();
|
||||
|
||||
|
||||
@ -3,6 +3,7 @@ const bufzilla = @import("bufzilla");
|
||||
|
||||
const shared = @import("shared");
|
||||
const server = @import("server.zig");
|
||||
const enet = @import("c.zig").enet;
|
||||
|
||||
pub fn spawn(chunk: *shared.chunk.Chunk, comptime T: type, allocator: std.mem.Allocator, value: T) !void {
|
||||
std.debug.assert(value.id == shared.entity.INVALID_ID);
|
||||
@ -14,12 +15,14 @@ pub fn spawn(chunk: *shared.chunk.Chunk, comptime T: type, allocator: std.mem.Al
|
||||
entity.id = id;
|
||||
|
||||
inline for (@typeInfo(shared.chunk.Chunk).@"struct".fields) |field| {
|
||||
if (field.type == shared.chunk.Storage(T)) {
|
||||
try @field(chunk, field.name).items.append(allocator, entity);
|
||||
if (field.type == std.ArrayList(T)) {
|
||||
try @field(chunk, field.name).append(allocator, entity);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std.log.info("{}", .{entity.to_message()});
|
||||
|
||||
// serialize entity
|
||||
var buffer: [128]u8 = undefined;
|
||||
var fixed = std.io.Writer.fixed(&buffer);
|
||||
@ -40,3 +43,11 @@ pub fn spawn(chunk: *shared.chunk.Chunk, comptime T: type, allocator: std.mem.Al
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
enet.enet_host_broadcast(host, 0, packet);
|
||||
}
|
||||
|
||||
@ -14,6 +14,8 @@ var accumulator : f32 = 0;
|
||||
var k : f32 = 1.0;
|
||||
var frame : i32 = 0;
|
||||
|
||||
var send_accumulator : f32 = 0;
|
||||
|
||||
var dbg_allocator = std.heap.DebugAllocator(.{}){};
|
||||
|
||||
pub fn main() !void {
|
||||
@ -45,6 +47,13 @@ pub fn main() !void {
|
||||
var the_chunk = try shared.chunk.initChunk(allocator);
|
||||
defer shared.chunk.deinitChunk(&the_chunk, allocator);
|
||||
|
||||
try chunk.spawn(&the_chunk, shared.entity.Soldier, allocator, .{
|
||||
.pos = zm.f32x4(1, 0, 0, 0),
|
||||
.vel = zm.f32x4(0, 0, 0, 0),
|
||||
.hp = 10,
|
||||
|
||||
});
|
||||
|
||||
var old_time = std.time.nanoTimestamp();
|
||||
|
||||
while (true) {
|
||||
@ -57,6 +66,7 @@ pub fn main() !void {
|
||||
|
||||
t += frame_time;
|
||||
accumulator += frame_time * k;
|
||||
send_accumulator += frame_time;
|
||||
|
||||
var event = enet.ENetEvent{};
|
||||
while (enet.enet_host_service(host, &event, 0) > 0) {
|
||||
@ -70,7 +80,7 @@ pub fn main() !void {
|
||||
enet.ENET_EVENT_TYPE_DISCONNECT => {
|
||||
std.log.info("disconnect", .{});
|
||||
},
|
||||
else => {}
|
||||
else => {},
|
||||
}
|
||||
}
|
||||
|
||||
@ -88,13 +98,6 @@ pub fn main() !void {
|
||||
// const w = &writer.interface;
|
||||
// try shared.protocol.sendHello(w, .{ .msg = "Hello from server!" });
|
||||
|
||||
try chunk.spawn(&the_chunk, shared.entity.Elf, allocator, .{
|
||||
.pos = zm.f32x4(1, 0, 0, 0),
|
||||
.vel = zm.f32x4(0, 0, 0, 0),
|
||||
.hp = 10,
|
||||
|
||||
});
|
||||
|
||||
// try chunk.spawn(&the_chunk, shared.entity.Monster, allocator, .{
|
||||
// .pos = zm.f32x4(1, 1, 0, 0),
|
||||
// .hp = 20,
|
||||
@ -105,7 +108,20 @@ pub fn main() !void {
|
||||
// .vel = zm.f32x4(0.2, 0, 0, 0),
|
||||
// }, w);
|
||||
|
||||
while (accumulator > dt * k) {
|
||||
shared.chunk.updateChunk(&the_chunk);
|
||||
|
||||
accumulator -= dt * k;
|
||||
gt += dt * k;
|
||||
}
|
||||
|
||||
if (send_accumulator > 1) {
|
||||
try chunk.broadcastChanges(&the_chunk, host);
|
||||
|
||||
send_accumulator = 0;
|
||||
}
|
||||
|
||||
frame += 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
3
src/shared/c.zig
Normal file
3
src/shared/c.zig
Normal file
@ -0,0 +1,3 @@
|
||||
pub const enet = @cImport({
|
||||
@cInclude("enet/enet.h");
|
||||
});
|
||||
@ -2,29 +2,29 @@ const std = @import("std");
|
||||
const entity = @import("entity.zig");
|
||||
const misc = @import("misc.zig");
|
||||
|
||||
pub fn Storage(comptime T: type) type {
|
||||
return struct {
|
||||
items: std.ArrayList(T),
|
||||
// pub fn Storage(comptime T: type) type {
|
||||
// return struct {
|
||||
// items: std.ArrayList(T),
|
||||
|
||||
pub fn init(allocator: std.mem.Allocator) !@This() {
|
||||
return .{
|
||||
.items = try std.ArrayList(T).initCapacity(allocator, 32),
|
||||
};
|
||||
}
|
||||
// pub fn init(allocator: std.mem.Allocator) !@This() {
|
||||
// return .{
|
||||
// .items = try std.ArrayList(T).initCapacity(allocator, 32),
|
||||
// };
|
||||
// }
|
||||
|
||||
pub fn deinit(self: *@This(), allocator: std.mem.Allocator) void {
|
||||
self.items.deinit(allocator);
|
||||
}
|
||||
// pub fn deinit(self: *@This(), allocator: std.mem.Allocator) void {
|
||||
// self.items.deinit(allocator);
|
||||
// }
|
||||
|
||||
pub fn update(self: *@This()) void {
|
||||
for (self.items.items, 0..) |*item, i| {
|
||||
_ = i;
|
||||
if (@hasDecl(T, "update"))
|
||||
item.update();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
// pub fn update(self: *@This()) void {
|
||||
// for (self.items.items, 0..) |*item, i| {
|
||||
// _ = i;
|
||||
// if (@hasDecl(T, "update"))
|
||||
// item.update();
|
||||
// }
|
||||
// }
|
||||
// };
|
||||
// }
|
||||
|
||||
pub const Chunk = _Chunk();
|
||||
|
||||
@ -36,10 +36,10 @@ fn _Chunk() type {
|
||||
inline for (entity.EntityKinds, 0..) |T, i| {
|
||||
fields[i] = .{
|
||||
.name = misc.short_type_name(T),
|
||||
.type = Storage(T),
|
||||
.type = std.ArrayList(T),
|
||||
.default_value_ptr = null,
|
||||
.is_comptime = false,
|
||||
.alignment = @alignOf(Storage(T)),
|
||||
.alignment = @alignOf(std.ArrayList(T)),
|
||||
};
|
||||
}
|
||||
|
||||
@ -56,14 +56,9 @@ fn _Chunk() type {
|
||||
pub fn initChunk(allocator: std.mem.Allocator) !Chunk {
|
||||
var chunk: Chunk = undefined;
|
||||
|
||||
switch (@typeInfo(Chunk)) {
|
||||
.@"struct" => |s| {
|
||||
inline for (s.fields) |field| {
|
||||
const StorageT = field.type;
|
||||
@field(chunk, field.name) = try StorageT.init(allocator);
|
||||
}
|
||||
},
|
||||
else => unreachable,
|
||||
inline for (@typeInfo(Chunk).@"struct".fields) |field| {
|
||||
const ListT = field.type;
|
||||
@field(chunk, field.name) = try ListT.initCapacity(allocator, 32);
|
||||
}
|
||||
|
||||
return chunk;
|
||||
@ -81,14 +76,13 @@ pub fn deinitChunk(chunk: *Chunk, allocator: std.mem.Allocator) void {
|
||||
}
|
||||
|
||||
pub fn updateChunk(chunk: *Chunk) void {
|
||||
const info = @typeInfo(Chunk);
|
||||
inline for (@typeInfo(Chunk).@"struct".fields) |field| {
|
||||
const list = &@field(chunk, field.name);
|
||||
|
||||
switch (info) {
|
||||
.@"struct" => |s| {
|
||||
inline for (s.fields) |field| {
|
||||
@field(chunk, field.name).update();
|
||||
}
|
||||
},
|
||||
else => unreachable,
|
||||
for (list.items, 0..) |*item, i| {
|
||||
_ = i;
|
||||
if (@hasDecl(@TypeOf(item.*), "update"))
|
||||
item.update();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,49 +1,61 @@
|
||||
const std = @import("std");
|
||||
const zm = @import("zmath");
|
||||
const protocol = @import("protocol.zig");
|
||||
const misc = @import("misc.zig");
|
||||
|
||||
pub const id = u64;
|
||||
pub const INVALID_ID: id = 0;
|
||||
|
||||
pub const EntityKinds = .{
|
||||
Elf,
|
||||
Cow,
|
||||
Pig,
|
||||
Soldier,
|
||||
Alien,
|
||||
};
|
||||
|
||||
pub const Elf = struct {
|
||||
pub const Soldier = struct {
|
||||
id: id = INVALID_ID,
|
||||
pos: zm.Vec,
|
||||
vel: zm.Vec,
|
||||
hp: i32,
|
||||
|
||||
pub fn update(self: *Elf) void {
|
||||
pub fn update(self: *Soldier) void {
|
||||
self.pos += self.pos + self.vel;
|
||||
}
|
||||
|
||||
pub fn to_message(self: *Elf) protocol.Elf_v1 {
|
||||
return protocol.Elf_v1.init(self);
|
||||
}
|
||||
};
|
||||
|
||||
pub const Cow = struct {
|
||||
pub const Alien = struct {
|
||||
id: id = INVALID_ID,
|
||||
pos: zm.Vec,
|
||||
vel: zm.Vec,
|
||||
hp: i32,
|
||||
|
||||
pub fn update(self: *Cow) void {
|
||||
pub fn update(self: *Alien) void {
|
||||
self.pos = self.pos + self.vel;
|
||||
}
|
||||
};
|
||||
|
||||
pub const Pig = struct {
|
||||
id: id = INVALID_ID,
|
||||
pos: zm.Vec,
|
||||
vel: zm.Vec,
|
||||
hp: i32,
|
||||
fn makeUnion() type {
|
||||
const FieldCount = EntityKinds.len;
|
||||
|
||||
pub fn update(self: *Pig) void {
|
||||
self.pos = self.pos + self.vel;
|
||||
}
|
||||
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),
|
||||
};
|
||||
}
|
||||
|
||||
return @Type(.{
|
||||
.@"union" = .{
|
||||
.layout = .auto,
|
||||
.fields = &fields,
|
||||
.decls = &.{},
|
||||
.tag_type = u8,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
const EntityRef = makeUnion();
|
||||
|
||||
@ -12,18 +12,15 @@ pub const Message = union(enum) {
|
||||
};
|
||||
|
||||
pub const SpawnEntity = union(enum) {
|
||||
elf_v1: Elf_v1,
|
||||
cow_v1: Cow_v1,
|
||||
pig_v1: Pig_v1,
|
||||
soldier_v1: Soldier_v1,
|
||||
alien_v1: Alien_v1,
|
||||
};
|
||||
|
||||
pub fn makeSpawnMessage(comptime T: type, e: T) Message {
|
||||
if (T == entity.Elf) {
|
||||
return .{ .spawn_entity = .{ .elf_v1 = Elf_v1.init(e) } };
|
||||
} else if (T == entity.Cow) {
|
||||
return .{ .spawn_entity = .{ .cow_v1 = Cow_v1.init(e) } };
|
||||
} else if (T == entity.Pig) {
|
||||
return .{ .spawn_entity = .{ .pig_v1 = Pig_v1.init(e) } };
|
||||
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) } };
|
||||
}
|
||||
}
|
||||
|
||||
@ -51,20 +48,26 @@ pub fn makeSpawnMessage(comptime T: type, e: T) Message {
|
||||
// };
|
||||
// }
|
||||
|
||||
pub const Elf_v1 = struct {
|
||||
pub const Soldier_v1 = struct {
|
||||
id: entity.id = entity.INVALID_ID,
|
||||
pos: zm.Vec,
|
||||
hp: i32,
|
||||
|
||||
pub fn init(elf: entity.Elf) Elf_v1 {
|
||||
pub fn init(soldier: entity.Soldier) Soldier_v1 {
|
||||
return .{
|
||||
.id = elf.id,
|
||||
.pos = elf.pos,
|
||||
.hp = elf.hp,
|
||||
.id = soldier.id,
|
||||
.pos = soldier.pos,
|
||||
.hp = soldier.hp,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn decode(r: *bufzilla.Reader) !Elf_v1 {
|
||||
pub fn encode(self: Soldier_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: *bufzilla.Reader) !Soldier_v1 {
|
||||
_ = r;
|
||||
return .{
|
||||
// .id = try r.readInt(u64, .little),
|
||||
@ -74,54 +77,26 @@ pub const Elf_v1 = struct {
|
||||
}
|
||||
};
|
||||
|
||||
pub const Cow_v1 = struct {
|
||||
pub const Alien_v1 = struct {
|
||||
id: entity.id = entity.INVALID_ID,
|
||||
pos: zm.Vec,
|
||||
hp: i32,
|
||||
|
||||
pub fn init(cow: entity.Cow) Cow_v1 {
|
||||
pub fn init(alien: entity.Alien) Alien_v1 {
|
||||
return .{
|
||||
.id = cow.id,
|
||||
.pos = cow.pos,
|
||||
.hp = cow.hp,
|
||||
.id = alien.id,
|
||||
.pos = alien.pos,
|
||||
.hp = alien.hp,
|
||||
};
|
||||
}
|
||||
|
||||
// pub fn encode(self: Cow_v1, w: *std.Io.Writer) !void {
|
||||
// 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) !Cow_v1 {
|
||||
return .{
|
||||
.id = try r.readInt(u64, .little),
|
||||
.pos = try readVec4(r),
|
||||
.vel = try readVec4(r),
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
pub const Pig_v1 = struct {
|
||||
id: entity.id = entity.INVALID_ID,
|
||||
pos: zm.Vec,
|
||||
vel: zm.Vec,
|
||||
|
||||
pub fn init(pig: entity.Pig) Pig_v1 {
|
||||
return .{
|
||||
.id = pig.id,
|
||||
.pos = pig.pos,
|
||||
.vel = pig.vel,
|
||||
};
|
||||
}
|
||||
|
||||
// pub fn encode(self: Pig_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) !Pig_v1 {
|
||||
pub fn decode(r: *std.Io.Reader) !Alien_v1 {
|
||||
return .{
|
||||
.id = try r.readInt(u64, .little),
|
||||
.pos = try readVec4(r),
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user