adler32 checksum for packets

This commit is contained in:
jacob 2026-01-16 16:34:47 -06:00
parent e6f1bb6661
commit 27c337202d
7 changed files with 318 additions and 234 deletions

View File

@ -40,6 +40,15 @@ Struct(NET_MsgList)
NET_Msg *last; NET_Msg *last;
}; };
////////////////////////////////////////////////////////////
//~ Stat types
Struct(NET_PipeStatistics)
{
i64 total_bytes_sent;
i64 total_bytes_received;
};
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ @hookdecl Bootstrap //~ @hookdecl Bootstrap
@ -48,10 +57,13 @@ void NET_Bootstrap(void);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ @hookdecl Net ops //~ @hookdecl Net ops
NET_PipeHandle NET_AcquirePipe(void);
void NET_Bind(NET_PipeHandle pipe, u64 port);
NET_Key NET_KeyFromString(String host, String port); NET_Key NET_KeyFromString(String host, String port);
NET_MsgList NET_Swap(Arena *arena, NET_PipeHandle pipe); NET_PipeHandle NET_AcquirePipe(void);
void NET_Bind(NET_PipeHandle pipe_handle, u64 port);
NET_MsgList NET_Swap(Arena *arena, NET_PipeHandle pipe_handle);
void NET_Push(NET_PipeHandle pipe_handle, NET_Key dst, String data, b32 burst); void NET_Push(NET_PipeHandle pipe_handle, NET_Key dst, String data, b32 burst);
NET_PipeStatistics NET_StatsFromPipe(NET_PipeHandle pipe_handle);

View File

@ -146,9 +146,62 @@ NET_W32_Peer *NET_W32_TouchPeerFromKey(NET_W32_Pipe *pipe, NET_Key key)
return peer; return peer;
} }
u32 NET_W32_ChecksumFromString(String str)
{
// Adler-32
// https://en.wikipedia.org/wiki/Adler-32
u32 a = 1;
u32 b = 0;
for (u64 idx = 0; idx < str.len; ++idx)
{
a = (a + str.text[idx]) % 65521;
b = (b + a) % 65521;
}
return (b << 16) | a;
}
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ @hookimpl Net ops //~ @hookimpl Net ops
NET_Key NET_KeyFromString(String host, String port)
{
NET_Key result = Zi;
TempArena scratch = BeginScratchNoConflict();
{
struct addrinfo hints = Zi;
hints.ai_family = AF_INET6;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_protocol = IPPROTO_UDP;
hints.ai_flags = AI_V4MAPPED | AI_ADDRCONFIG;
char *host_cstr = CstrFromString(scratch.arena, host);
char *port_cstr = CstrFromString(scratch.arena, port);
struct sockaddr_in6 addr = Zi;
{
struct addrinfo *first_ai = 0;
if (getaddrinfo(host_cstr, port_cstr, &hints, &first_ai) == 0)
{
for (struct addrinfo *ai = first_ai; ai; ai = ai->ai_next)
{
if (ai->ai_family == AF_INET6 && ai->ai_addrlen >= sizeof(addr))
{
CopyBytes(&addr, ai->ai_addr, sizeof(addr));
break;
}
}
}
if (first_ai)
{
freeaddrinfo(first_ai);
}
}
result = NET_W32_KeyFromAddress(addr);
}
EndScratch(scratch);
return result;
}
NET_PipeHandle NET_AcquirePipe(void) NET_PipeHandle NET_AcquirePipe(void)
{ {
Arena *perm = PermArena(); Arena *perm = PermArena();
@ -193,45 +246,6 @@ void NET_Bind(NET_PipeHandle pipe_handle, u64 port)
// FIXME: Signal here if ports don't match // FIXME: Signal here if ports don't match
} }
NET_Key NET_KeyFromString(String host, String port)
{
NET_Key result = Zi;
TempArena scratch = BeginScratchNoConflict();
{
struct addrinfo hints = Zi;
hints.ai_family = AF_INET6;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_protocol = IPPROTO_UDP;
hints.ai_flags = AI_V4MAPPED | AI_ADDRCONFIG;
char *host_cstr = CstrFromString(scratch.arena, host);
char *port_cstr = CstrFromString(scratch.arena, port);
struct sockaddr_in6 addr = Zi;
{
struct addrinfo *first_ai = 0;
if (getaddrinfo(host_cstr, port_cstr, &hints, &first_ai) == 0)
{
for (struct addrinfo *ai = first_ai; ai; ai = ai->ai_next)
{
if (ai->ai_family == AF_INET6 && ai->ai_addrlen >= sizeof(addr))
{
CopyBytes(&addr, ai->ai_addr, sizeof(addr));
break;
}
}
}
if (first_ai)
{
freeaddrinfo(first_ai);
}
}
result = NET_W32_KeyFromAddress(addr);
}
EndScratch(scratch);
return result;
}
NET_MsgList NET_Swap(Arena *arena, NET_PipeHandle pipe_handle) NET_MsgList NET_Swap(Arena *arena, NET_PipeHandle pipe_handle)
{ {
NET_W32_Pipe *pipe = NET_W32_PipeFromHandle(pipe_handle); NET_W32_Pipe *pipe = NET_W32_PipeFromHandle(pipe_handle);
@ -267,6 +281,15 @@ void NET_Push(NET_PipeHandle pipe_handle, NET_Key dst, String data, b32 burst)
NET_W32_SignalWorker(); NET_W32_SignalWorker();
} }
NET_PipeStatistics NET_StatsFromPipe(NET_PipeHandle pipe_handle)
{
NET_PipeStatistics result = Zi;
NET_W32_Pipe *pipe = NET_W32_PipeFromHandle(pipe_handle);
result.total_bytes_sent = Atomic64Fetch(&pipe->total_bytes_sent);
result.total_bytes_received = Atomic64Fetch(&pipe->total_bytes_received);
return result;
}
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Worker //~ Worker
@ -281,7 +304,9 @@ void NET_W32_TickForever(WaveLaneCtx *lane)
u32 magic = 0xde8c590b; u32 magic = 0xde8c590b;
i64 heartbeat_threshold_ns = NsFromSeconds(0.250); i64 heartbeat_threshold_ns = NsFromSeconds(0.250);
i64 passive_run_threshold_ns = NsFromSeconds(0.250); i64 passive_run_threshold_ns = NsFromSeconds(0.250);
i64 msg_resend_threshold_ns = NsFromSeconds(0.500);
// TODO: Base this on peer's latency w/ rolling backoff
i64 msg_resend_threshold_ns = NsFromSeconds(0.250);
////////////////////////////// //////////////////////////////
//- Wait //- Wait
@ -365,12 +390,15 @@ void NET_W32_TickForever(WaveLaneCtx *lane)
NET_W32_Pipe *pipe = pipes[pipe_idx]; NET_W32_Pipe *pipe = pipes[pipe_idx];
////////////////////////////// //////////////////////////////
//- Reset peer data //- Reset frame data
{
pipe->num_msg_packets_received_this_frame = 0;
for (NET_W32_Peer *peer = pipe->first_peer; peer; peer = peer->next) for (NET_W32_Peer *peer = pipe->first_peer; peer; peer = peer->next)
{ {
peer->num_msg_packets_received_this_frame = 0; peer->num_msg_packets_received_this_frame = 0;
} }
}
////////////////////////////// //////////////////////////////
//- Bind //- Bind
@ -538,15 +566,16 @@ void NET_W32_TickForever(WaveLaneCtx *lane)
struct sockaddr_in6 addr = Zi; struct sockaddr_in6 addr = Zi;
i32 addr_sz = sizeof(addr); i32 addr_sz = sizeof(addr);
len = recvfrom(pipe->udp, (char *)buff, countof(buff), 0, (struct sockaddr *)&addr, &addr_sz); len = recvfrom(pipe->udp, (char *)buff, countof(buff), 0, (struct sockaddr *)&addr, &addr_sz);
if ( Atomic64FetchAdd(&pipe->total_bytes_received, len);
len >= sizeof(NET_W32_PacketHeader) && if (len >= sizeof(NET_W32_PacketHeader) && len <= sizeof(NET_W32_PacketHeader) + NET_PacketSize)
len <= sizeof(NET_W32_PacketHeader) + NET_PacketSize &&
MatchBytes(buff, &magic, sizeof(magic))
)
{ {
NET_Key key = NET_W32_KeyFromAddress(addr);
NET_W32_PacketHeader header = Zi; NET_W32_PacketHeader header = Zi;
CopyBytes(&header, buff, sizeof(header)); CopyBytes(&header, buff, sizeof(header));
CopyBytes(buff, &magic, sizeof(magic));
u32 checksum = NET_W32_ChecksumFromString(STRING(len, buff));
if (header.checksum == checksum)
{
NET_Key key = NET_W32_KeyFromAddress(addr);
String src_data = Zi; String src_data = Zi;
src_data.text = buff + sizeof(header); src_data.text = buff + sizeof(header);
src_data.len = len - sizeof(header); src_data.len = len - sizeof(header);
@ -583,6 +612,7 @@ void NET_W32_TickForever(WaveLaneCtx *lane)
peer->ack_bits |= ack_bit; peer->ack_bits |= ack_bit;
} }
peer->num_msg_packets_received_this_frame += 1; peer->num_msg_packets_received_this_frame += 1;
pipe->num_msg_packets_received_this_frame += 1;
// Process packet // Process packet
if (should_process) if (should_process)
@ -672,15 +702,16 @@ void NET_W32_TickForever(WaveLaneCtx *lane)
} }
} }
LogDebugF( // LogDebugF(
"Received msg packet. seq: %F, msg seq: %F, new bottom ack: %F, new ack bits: %F, should_process: %F, data: \"%F\"", // "Received msg packet. seq: %F, msg seq: %F, new bottom ack: %F, new ack bits: %F, should_process: %F, data: \"%F\"",
FmtSint(header.seq), // FmtSint(header.seq),
FmtSint(header.msg_seq), // FmtSint(header.msg_seq),
FmtSint(peer->bottom_ack), // FmtSint(peer->bottom_ack),
FmtUint(peer->ack_bits), // FmtUint(peer->ack_bits),
FmtUint(should_process), // FmtUint(should_process),
FmtString(src_data) // FmtString(src_data)
); // );
}
} }
} }
} }
@ -690,8 +721,8 @@ void NET_W32_TickForever(WaveLaneCtx *lane)
//- Assemble read messages //- Assemble read messages
// TODO: Maximum message size // TODO: Maximum message size
// TODO: Don't lock if no msgs received on pipe
if (pipe->num_msg_packets_received_this_frame > 0)
{ {
LockTicketMutex(&pipe->back_msg_buff_seq_tm); LockTicketMutex(&pipe->back_msg_buff_seq_tm);
{ {
@ -741,11 +772,10 @@ void NET_W32_TickForever(WaveLaneCtx *lane)
msg_data.text = ArenaNext(msg_buff->arena, u8); msg_data.text = ArenaNext(msg_buff->arena, u8);
msg_data.len = 0; msg_data.len = 0;
LogDebugF( LogSuccessF(
"Assembled msg with msg seq: %F, data (%F bytes): \"%F\"", "Assembled msg with msg seq: %F, data (%F bytes)",
FmtSint(packet->msg_seq), FmtSint(packet->msg_seq),
FmtUint(msg->data.len), FmtUint(msg->data.len)
FmtString(msg->data)
); );
} }
} }
@ -786,11 +816,12 @@ void NET_W32_TickForever(WaveLaneCtx *lane)
String src_data = cmd->data; String src_data = cmd->data;
i64 src_pos = 0; i64 src_pos = 0;
i64 msg_seq = ++peer->msg_seq; i64 msg_seq = ++peer->msg_seq;
LogDebugF("Queued msg with seq %F", FmtSint(msg_seq)); // LogDebugF("Queued msg with seq %F", FmtSint(msg_seq));
// TODO: Burst packets // TODO: Burst packets
while (src_pos < (i64)src_data.len) b32 is_msg_end = 0;
while (!is_msg_end)
{ {
i64 copy_len = MinI64(NET_PacketSize - (i64)peer->fragment.len, src_data.len - src_pos); i64 copy_len = MinI64(NET_PacketSize - (i64)peer->fragment.len, src_data.len - src_pos);
CopyBytes(peer->fragment.text + peer->fragment.len, src_data.text + src_pos, copy_len); CopyBytes(peer->fragment.text + peer->fragment.len, src_data.text + src_pos, copy_len);
@ -798,7 +829,7 @@ void NET_W32_TickForever(WaveLaneCtx *lane)
peer->fragment.len += copy_len; peer->fragment.len += copy_len;
// Push packet // Push packet
b32 is_msg_end = src_pos >= (i64)src_data.len; is_msg_end = src_pos >= (i64)src_data.len;
if (peer->fragment.len == NET_PacketSize || is_msg_end) if (peer->fragment.len == NET_PacketSize || is_msg_end)
{ {
NET_W32_Packet *packet = NET_W32.first_free_packet; NET_W32_Packet *packet = NET_W32.first_free_packet;
@ -819,7 +850,6 @@ void NET_W32_TickForever(WaveLaneCtx *lane)
packet->msg_seq = msg_seq; packet->msg_seq = msg_seq;
CopyBytes(packet->data.text, peer->fragment.text, peer->fragment.len); CopyBytes(packet->data.text, peer->fragment.text, peer->fragment.len);
packet->data.len = peer->fragment.len; packet->data.len = peer->fragment.len;
if (is_msg_end) if (is_msg_end)
{ {
packet->flags |= NET_W32_PacketFlag_EndMsg; packet->flags |= NET_W32_PacketFlag_EndMsg;
@ -859,13 +889,16 @@ void NET_W32_TickForever(WaveLaneCtx *lane)
u8 buff[Kibi(2)]; u8 buff[Kibi(2)];
NET_W32_PacketHeader header = Zi; NET_W32_PacketHeader header = Zi;
{ {
header.magic = magic; header.checksum = magic;
header.flags = NET_W32_PacketFlag_Heartbeat; header.flags = NET_W32_PacketFlag_Heartbeat;
header.bottom_ack = peer->bottom_ack; header.bottom_ack = peer->bottom_ack;
header.ack_bits = peer->ack_bits; header.ack_bits = peer->ack_bits;
} }
CopyBytes(buff, &header, sizeof(header)); CopyBytes(buff, &header, sizeof(header));
buff_len += sizeof(header); buff_len += sizeof(header);
u32 checksum = NET_W32_ChecksumFromString(STRING(buff_len, buff));
CopyBytes(buff, &checksum, sizeof(checksum));
sendto( sendto(
pipe->udp, pipe->udp,
(char *)buff, (char *)buff,
@ -874,6 +907,7 @@ void NET_W32_TickForever(WaveLaneCtx *lane)
(struct sockaddr *)&addr, (struct sockaddr *)&addr,
sizeof(addr) sizeof(addr)
); );
Atomic64FetchAdd(&pipe->total_bytes_sent, buff_len);
peer->last_packet_sent_ns = now_ns; peer->last_packet_sent_ns = now_ns;
} }
} }
@ -920,22 +954,18 @@ void NET_W32_TickForever(WaveLaneCtx *lane)
} }
else else
{ {
// Transmit unacked packet
i64 now_ns = TimeNs(); i64 now_ns = TimeNs();
if (packet->last_sent_ns == 0 || (now_ns - packet->last_sent_ns > msg_resend_threshold_ns)) if (packet->last_sent_ns == 0 || (now_ns - packet->last_sent_ns > msg_resend_threshold_ns))
{ {
peer->last_packet_sent_ns = now_ns; peer->last_packet_sent_ns = now_ns;
packet->last_sent_ns = now_ns; packet->last_sent_ns = now_ns;
// Transmit unacked packet
// FIXME: Rate limit, don't send if we've already sent in the last second.
// NOTE: If we do this we should probably put the net worker on something like a 1-second auto-run timer
// TODO: crc32
i64 buff_len = 0; i64 buff_len = 0;
u8 buff[Kibi(2)]; u8 buff[Kibi(2)];
NET_W32_PacketHeader header = Zi; NET_W32_PacketHeader header = Zi;
{ {
header.magic = magic; header.checksum = magic;
header.flags = packet->flags; header.flags = packet->flags;
header.seq = packet->seq; header.seq = packet->seq;
header.msg_seq = packet->msg_seq; header.msg_seq = packet->msg_seq;
@ -948,6 +978,8 @@ void NET_W32_TickForever(WaveLaneCtx *lane)
CopyBytes(buff + buff_len, packet->data.text, packet->data.len); CopyBytes(buff + buff_len, packet->data.text, packet->data.len);
buff_len += packet->data.len; buff_len += packet->data.len;
u32 checksum = NET_W32_ChecksumFromString(STRING(buff_len, buff));
CopyBytes(buff, &checksum, sizeof(checksum));
sendto( sendto(
pipe->udp, pipe->udp,
(char *)buff, (char *)buff,
@ -956,13 +988,14 @@ void NET_W32_TickForever(WaveLaneCtx *lane)
(struct sockaddr *)&addr, (struct sockaddr *)&addr,
sizeof(addr) sizeof(addr)
); );
Atomic64FetchAdd(&pipe->total_bytes_sent, buff_len);
LogDebugF( // LogDebugF(
"Sent msg packet. seq: %F, msg seq: %F, data: \"%F\"", // "Sent msg packet. seq: %F, msg seq: %F, data: \"%F\"",
FmtSint(header.seq), // FmtSint(header.seq),
FmtSint(header.msg_seq), // FmtSint(header.msg_seq),
FmtString(packet->data) // FmtString(packet->data)
); // );
} }
} }
} }

View File

@ -46,7 +46,7 @@ Enum(NET_W32_PacketFlag)
Struct(NET_W32_PacketHeader) Struct(NET_W32_PacketHeader)
{ {
u32 magic; u32 checksum;
NET_W32_PacketFlag flags; NET_W32_PacketFlag flags;
i64 seq; i64 seq;
i64 msg_seq; i64 msg_seq;
@ -121,6 +121,9 @@ Struct(NET_W32_Pipe)
Atomic64 desired_port; // >64k means ephemeral Atomic64 desired_port; // >64k means ephemeral
Atomic64 total_bytes_sent;
Atomic64 total_bytes_received;
TicketMutex back_cmd_buff_seq_tm; TicketMutex back_cmd_buff_seq_tm;
i64 back_cmd_buff_seq; i64 back_cmd_buff_seq;
NET_W32_CmdBuff cmd_buffs[2]; NET_W32_CmdBuff cmd_buffs[2];
@ -133,6 +136,7 @@ Struct(NET_W32_Pipe)
NET_W32_Peer *first_peer; NET_W32_Peer *first_peer;
NET_W32_Peer *last_peer; NET_W32_Peer *last_peer;
i64 num_msg_packets_received_this_frame;
i64 peer_bins_count; i64 peer_bins_count;
NET_W32_PeerBin *peer_bins; NET_W32_PeerBin *peer_bins;
@ -177,6 +181,7 @@ struct sockaddr_in6 NET_W32_AddressFromKey(NET_Key key);
u64 NET_W32_HashFromKey(NET_Key key); u64 NET_W32_HashFromKey(NET_Key key);
void NET_W32_SignalWorker(void); void NET_W32_SignalWorker(void);
NET_W32_Peer *NET_W32_TouchPeerFromKey(NET_W32_Pipe *pipe, NET_Key key); NET_W32_Peer *NET_W32_TouchPeerFromKey(NET_W32_Pipe *pipe, NET_Key key);
u32 NET_W32_ChecksumFromString(String str);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Worker //~ Worker

View File

@ -16,8 +16,7 @@ Readonly P_Frame P_NilFrame = {
void P_Bootstrap(void) void P_Bootstrap(void)
{ {
P.u2s_msgs_arena = AcquireArena(Gibi(64)); P.s2u.arena = AcquireArena(Gibi(64));
P.s2u_msgs_arena = AcquireArena(Gibi(64));
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////

View File

@ -284,10 +284,6 @@ Struct(P_SimSnapshot)
i64 deltas_count; i64 deltas_count;
P_SimDeltaNode *first_delta_node; P_SimDeltaNode *first_delta_node;
P_SimDeltaNode *last_delta_node; P_SimDeltaNode *last_delta_node;
i64 debug_draw_nodes_count;
P_DebugDrawNode *first_debug_draw_node;
P_DebugDrawNode *last_debug_draw_node;
}; };
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
@ -421,20 +417,18 @@ Struct(P_RaycastResult)
Struct(P_Ctx) Struct(P_Ctx)
{ {
//- User -> sim messages // Sim -> User state
Arena *u2s_msgs_arena; TicketMutex s2u_tm;
TicketMutex u2s_msgs_mutex; struct
P_MsgList u2s_msgs; {
i64 gen;
Arena *arena;
i64 debug_draw_nodes_count;
P_DebugDrawNode *first_debug_draw_node;
P_DebugDrawNode *last_debug_draw_node;
//- Sim -> user messages NET_PipeStatistics pipe_stats;
Arena *s2u_msgs_arena; } s2u;
TicketMutex s2u_msgs_mutex;
P_MsgList s2u_msgs;
//- Sim -> user snapshot
Arena *s2u_snapshot_arena;
TicketMutex s2u_snapshot_mutex;
P_SimSnapshot s2u_snapshot;
}; };
Struct(P_ThreadLocalCtx) Struct(P_ThreadLocalCtx)

View File

@ -614,6 +614,26 @@ void S_TickForever(WaveLaneCtx *lane)
} }
} }
//////////////////////////////
//- Publish Sim -> User data
{
LockTicketMutex(&P.s2u_tm);
{
{
i64 old_gen = P.s2u.gen;
Arena *old_arena = P.s2u.arena;
ZeroStruct(&P.s2u);
P.s2u.arena = old_arena;
P.s2u.gen = old_gen;
}
ZeroStruct(P.s2u.arena);
P.s2u.gen += 1;
P.s2u.pipe_stats = NET_StatsFromPipe(net_pipe);
}
UnlockTicketMutex(&P.s2u_tm);
}
////////////////////////////// //////////////////////////////
//- End sim frame //- End sim frame

View File

@ -350,9 +350,11 @@ void V_TickForever(WaveLaneCtx *lane)
////////////////////////////// //////////////////////////////
//- Init vis state //- Init vis state
i64 s2u_gen = 0;
Arena *sim_debug_arena = AcquireArena(Gibi(64)); Arena *sim_debug_arena = AcquireArena(Gibi(64));
P_DebugDrawNode *first_sim_debug_draw_node = 0; P_DebugDrawNode *first_sim_debug_draw_node = 0;
P_DebugDrawNode *last_sim_debug_draw_node = 0; P_DebugDrawNode *last_sim_debug_draw_node = 0;
NET_PipeStatistics sim_pipe_stats = Zi;
P_World *sim_world = P_AcquireWorld(); P_World *sim_world = P_AcquireWorld();
P_World *predict_world = P_AcquireWorld(); P_World *predict_world = P_AcquireWorld();
@ -644,6 +646,27 @@ void V_TickForever(WaveLaneCtx *lane)
frame->ui_dims.y = MaxF32(frame->ui_dims.y, 64); frame->ui_dims.y = MaxF32(frame->ui_dims.y, 64);
frame->draw_dims = frame->ui_dims; frame->draw_dims = frame->ui_dims;
//////////////////////////////
//- Pop sim -> user data
{
LockTicketMutex(&P.s2u_tm);
{
if (P.s2u.gen > s2u_gen)
{
s2u_gen = P.s2u.gen;
sim_pipe_stats = P.s2u.pipe_stats;
}
}
UnlockTicketMutex(&P.s2u_tm);
}
//////////////////////////////
//- Update pipe stats
NET_PipeStatistics vis_pipe_stats = NET_StatsFromPipe(net_pipe);
////////////////////////////// //////////////////////////////
//- Process controller events into vis cmds //- Process controller events into vis cmds
@ -2290,6 +2313,13 @@ void V_TickForever(WaveLaneCtx *lane)
UI_BuildLabelF("Hovered ent: %F", P_FmtKey(hovered_ent->key)); UI_BuildLabelF("Hovered ent: %F", P_FmtKey(hovered_ent->key));
} }
UI_BuildSpacer(UI_PIX(padding, 1), Axis_Y); UI_BuildSpacer(UI_PIX(padding, 1), Axis_Y);
{
UI_BuildLabelF("Client send: %F MiB", FmtFloat(CeilF64((f64)vis_pipe_stats.total_bytes_sent / 1024) / 1024, .p = 3));
UI_BuildLabelF("Client recv: %F MiB", FmtFloat(CeilF64((f64)vis_pipe_stats.total_bytes_received / 1024) / 1024, .p = 3));
UI_BuildLabelF("Server send: %F MiB", FmtFloat(CeilF64((f64)sim_pipe_stats.total_bytes_sent / 1024) / 1024, .p = 3));
UI_BuildLabelF("Server recv: %F MiB", FmtFloat(CeilF64((f64)sim_pipe_stats.total_bytes_received / 1024) / 1024, .p = 3));
}
UI_BuildSpacer(UI_PIX(padding, 1), Axis_Y);
{ {
{ {
UI_Push(FontSize, UI_Top(FontSize) * theme.h2); UI_Push(FontSize, UI_Top(FontSize) * theme.h2);
@ -2644,15 +2674,6 @@ void V_TickForever(WaveLaneCtx *lane)
} }
} }
//////////////////////////////
//- Pop snapshot from sim
// { // {
// LockTicketMutex(&P.s2u_snapshot_mutex); // LockTicketMutex(&P.s2u_snapshot_mutex);
// P_SimSnapshot *src_snapshot = &P.s2u_snapshot; // P_SimSnapshot *src_snapshot = &P.s2u_snapshot;
@ -2775,22 +2796,22 @@ void V_TickForever(WaveLaneCtx *lane)
} }
//- Update sim debug info //- Update sim debug info
{ // {
ResetArena(sim_debug_arena); // ResetArena(sim_debug_arena);
first_sim_debug_draw_node = 0; // first_sim_debug_draw_node = 0;
last_sim_debug_draw_node = 0; // last_sim_debug_draw_node = 0;
{ // {
i64 dst_idx = 0; // i64 dst_idx = 0;
P_DebugDrawNode *dst_nodes = PushStructsNoZero(sim_debug_arena, P_DebugDrawNode, snapshot->debug_draw_nodes_count); // P_DebugDrawNode *dst_nodes = PushStructsNoZero(sim_debug_arena, P_DebugDrawNode, snapshot->debug_draw_nodes_count);
for (P_DebugDrawNode *src = snapshot->first_debug_draw_node; src; src = src->next) // for (P_DebugDrawNode *src = snapshot->first_debug_draw_node; src; src = src->next)
{ // {
P_DebugDrawNode *dst = &dst_nodes[dst_idx]; // P_DebugDrawNode *dst = &dst_nodes[dst_idx];
*dst = *src; // *dst = *src;
dst_idx += 1; // dst_idx += 1;
SllQueuePush(first_sim_debug_draw_node, last_sim_debug_draw_node, dst); // SllQueuePush(first_sim_debug_draw_node, last_sim_debug_draw_node, dst);
} // }
} // }
} // }
} }
// TODO: Remove this // TODO: Remove this
@ -3762,12 +3783,8 @@ void V_TickForever(WaveLaneCtx *lane)
if (frame->held_buttons[Button_R] && !prev_frame->held_buttons[Button_R]) if (frame->held_buttons[Button_R] && !prev_frame->held_buttons[Button_R])
{ {
for (i64 i = 0; i < 100; ++i) LogDebugF("Sending test payload");
{ NET_Push(net_pipe, server_key, STRING(P_TilesCount, predict_world->tiles), 0);
// NET_Push(net_pipe, server_key, Lit("HELLO!!!!"), 0);
NET_Push(net_pipe, server_key, Lit("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"), 0);
}
// NET_Push(net_pipe, server_key, Lit("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"), 0);
} }
@ -3779,6 +3796,10 @@ void V_TickForever(WaveLaneCtx *lane)
String packed = P_PackMessage(frame->arena, msg); String packed = P_PackMessage(frame->arena, msg);
NET_Push(net_pipe, server_key, packed, msg->burst); NET_Push(net_pipe, server_key, packed, msg->burst);
} }
ResetArena(P_tl.out_msgs_arena);
ZeroStruct(&P_tl.out_msgs);
////////////////////////////// //////////////////////////////
//- End frame //- End frame