power_play/src/net/net_core.h
2025-07-29 18:12:41 -05:00

160 lines
3.6 KiB
C

#define HOST_CHANNEL_ID_NIL (N_ChannelId) { .gen = 0, .idx = 0 }
#define HOST_CHANNEL_ID_ALL (N_ChannelId) { .gen = U32_MAX, .idx = U32_MAX }
#define N_PacketMagic 0xd9e3b8b6
#define N_MaxPacketChunkLen 1024
#define N_MaxPacketLen 1280 /* Give enough space for msg chunk + header */
#define N_NumChannelLookupBins 512
#define N_NumMsgAssemblerLookupBins 16384
typedef i32 N_CmdKind; enum {
HOST_CMD_KIND_NONE,
HOST_CMD_KIND_TRY_CONNECT,
HOST_CMD_KIND_CONNECT_SUCCESS,
HOST_CMD_KIND_DISCONNECT,
HOST_CMD_KIND_HEARTBEAT,
HOST_CMD_KIND_WRITE
};
typedef i32 N_EventKind; enum {
HOST_EVENT_KIND_NONE,
HOST_EVENT_KIND_CHANNEL_OPENED,
HOST_EVENT_KIND_CHANNEL_CLOSED,
HOST_EVENT_KIND_MSG
};
typedef i32 N_WriteFlag; enum {
HOST_WRITE_FLAG_NONE = 0,
HOST_WRITE_FLAG_RELIABLE = (1 << 0)
};
Struct(N_ChannelId) {
u32 gen;
u32 idx;
};
Struct(N_Cmd) {
N_CmdKind kind;
N_ChannelId channel_id;
u16 heartbeat_id;
u16 heartbeat_ack_id;
b32 write_reliable;
String write_msg;
N_Cmd *next;
};
Struct(N_Event) {
N_EventKind kind;
N_ChannelId channel_id;
String msg;
N_Event *next;
};
Struct(N_EventList) {
N_Event *first;
N_Event *last;
};
Struct(N_ChannelLookupBin) {
struct host_channel *first;
struct host_channel *last;
};
Struct(N_RcvBuffer) {
Arena *arena;
struct host_rcv_packet *first_packet;
struct host_rcv_packet *last_packet;
};
Struct(N_SndPacket) {
N_SndPacket *next;
u64 seq;
u64 data_len;
u8 data[N_MaxPacketLen];
};
Struct(N_Host) {
Arena *arena;
P_Sock *sock;
BuddyCtx *buddy; /* For storing msg assembler data */
Arena *cmd_arena;
N_Cmd *first_cmd;
N_Cmd *last_cmd;
N_Cmd *first_free_cmd;
Arena *channel_arena;
struct host_channel *channels;
struct host_channel *first_free_channel;
u64 num_channels_reserved;
N_SndPacket *first_free_packet; /* Allocated in `arena` */
struct host_msg_assembler *first_free_msg_assembler; /* Allocated in `arena` */
N_ChannelLookupBin *channel_lookup_bins; /* Allocated in `arena` */
u64 num_channel_lookup_bins;
struct host_msg_assembler_lookup_bin *msg_assembler_lookup_bins; /* Allocated in `arena` */
u64 num_msg_assembler_lookup_bins;
/* Double buffer for incoming data */
P_Mutex rcv_buffer_write_mutex;
N_RcvBuffer *rcv_buffer_read;
N_RcvBuffer *rcv_buffer_write;
u64 bytes_received;
u64 bytes_sent;
};
/* ========================== *
* Startup
* ========================== */
Struct(N_StartupReceipt) { i32 _; };
N_StartupReceipt host_startup(void);
/* ========================== *
* Host
* ========================== */
N_Host *host_alloc(u16 listen_port);
void host_release(N_Host *host);
/* ========================== *
* Queue
* ========================== */
void host_queue_connect_to_address(N_Host *host, P_Address connect_address);
void host_queue_disconnect(N_Host *host, N_ChannelId channel_id);
void host_queue_write(N_Host *host, N_ChannelId channel_id, String msg, u32 flags);
/* ========================== *
* Info
* ========================== */
i64 host_get_channel_last_rtt_ns(N_Host *host, N_ChannelId channel_id);
INLINE b32 host_channel_id_eq(N_ChannelId a, N_ChannelId b) { return a.idx == b.idx && a.gen == b.gen; }
INLINE b32 host_channel_id_is_nil(N_ChannelId id) { return id.gen == 0 && id.idx == 0; }
/* ========================== *
* Update
* ========================== */
N_EventList host_update_begin(Arena *arena, N_Host *host);
void host_update_end(N_Host *host);