networking progress

This commit is contained in:
jacob 2025-02-08 07:06:56 -06:00
parent 78ace4b38a
commit a78c5e1a47
14 changed files with 191 additions and 192 deletions

View File

@ -113,7 +113,7 @@ INTERNAL struct buddy_block *buddy_block_get_unused(struct buddy_ctx *ctx, struc
block = left; block = left;
ASSERT(block->memory); ASSERT(block->memory);
} else { } else {
#if 0 #if 1
/* Create left block from arena */ /* Create left block from arena */
struct buddy_block *left = buddy_block_alloc_internal(ctx); struct buddy_block *left = buddy_block_alloc_internal(ctx);
left->used = true; left->used = true;

View File

@ -91,9 +91,9 @@ void bw_seek_to(struct byte_writer *bw, u64 pos)
bw->at = bw->buff.text + pos; bw->at = bw->buff.text + pos;
} }
void bw_write_buffer(struct byte_writer *bw, struct string buff) void br_write_bytes(struct byte_writer *bw, struct string bytes)
{ {
write(bw, buff.text, buff.len); write(bw, bytes.text, bytes.len);
} }
void bw_write_u8(struct byte_writer *bw, u8 v) void bw_write_u8(struct byte_writer *bw, u8 v)
@ -167,7 +167,7 @@ void bw_write_v2(struct byte_writer *bw, struct v2 v)
void bw_write_string(struct byte_writer *bw, struct string str) void bw_write_string(struct byte_writer *bw, struct string str)
{ {
bw_write_var_uint(bw, str.len); bw_write_var_uint(bw, str.len);
bw_write_buffer(bw, str); br_write_bytes(bw, str);
} }
/* ========================== * /* ========================== *

View File

@ -25,7 +25,7 @@ struct byte_writer bw_branch(struct byte_writer *bw, u64 size);
void bw_seek(struct byte_writer *bw, u64 amount); void bw_seek(struct byte_writer *bw, u64 amount);
void bw_seek_to(struct byte_writer *bw, u64 pos); void bw_seek_to(struct byte_writer *bw, u64 pos);
void bw_write_buffer(struct byte_writer *bw, struct string buff); void br_write_bytes(struct byte_writer *bw, struct string bytes);
void bw_write_u8(struct byte_writer *bw, u8 v); void bw_write_u8(struct byte_writer *bw, u8 v);
void bw_write_u16(struct byte_writer *bw, u16 v); void bw_write_u16(struct byte_writer *bw, u16 v);
void bw_write_u32(struct byte_writer *bw, u32 v); void bw_write_u32(struct byte_writer *bw, u32 v);

View File

@ -58,7 +58,7 @@
#define USER_INTERP_OFFSET_TICK_RATIO 1.1 #define USER_INTERP_OFFSET_TICK_RATIO 1.1
#define USER_INTERP_ENABLED 1 #define USER_INTERP_ENABLED 1
#define COLLIDER_DEBUG RTC #define COLLIDER_DEBUG 0
#define COLLIDER_DEBUG_DETAILED 0 #define COLLIDER_DEBUG_DETAILED 0
#define COLLIDER_DEBUG_DETAILED_DRAW_MENKOWSKI 1 #define COLLIDER_DEBUG_DETAILED_DRAW_MENKOWSKI 1

View File

@ -81,13 +81,13 @@ INTERNAL struct entity *entity_alloc_internal(struct entity_store *store)
} else { } else {
/* Make new */ /* Make new */
entity = arena_push(&store->arena, struct entity); entity = arena_push(&store->arena, struct entity);
handle = (struct entity_handle) { .gen = 1, .idx = store->reserved++ }; handle = (struct entity_handle) { .gen = 1, .idx = store->num_reserved++ };
} }
*entity = _g_entity_nil; *entity = _g_entity_nil;
entity->valid = true; entity->valid = true;
entity->handle = handle; entity->handle = handle;
entity->cached_global_xform_dirty = true; entity->cached_global_xform_dirty = true;
++store->allocated; ++store->num_allocated;
return entity; return entity;
} }
@ -115,7 +115,7 @@ INTERNAL void entity_release_internal(struct entity_store *store, struct entity
ent->valid = false; ent->valid = false;
ent->next_free = store->first_free; ent->next_free = store->first_free;
store->first_free = ent->handle; store->first_free = ent->handle;
--store->allocated; --store->num_allocated;
} }
void entity_release(struct entity_store *store, struct entity *ent) void entity_release(struct entity_store *store, struct entity *ent)
@ -145,7 +145,7 @@ struct entity_store *entity_store_from_entity(struct entity *ent)
/* Returns a valid entity or read-only nil entity. Always safe to read result, need to check `valid` to write. */ /* Returns a valid entity or read-only nil entity. Always safe to read result, need to check `valid` to write. */
struct entity *entity_from_handle(struct entity_store *store, struct entity_handle handle) struct entity *entity_from_handle(struct entity_store *store, struct entity_handle handle)
{ {
if (handle.gen != 0 && handle.idx < store->reserved) { if (handle.gen != 0 && handle.idx < store->num_reserved) {
struct entity *entity = &store->entities[handle.idx]; struct entity *entity = &store->entities[handle.idx];
if (entity->handle.gen == handle.gen) { if (entity->handle.gen == handle.gen) {
return entity; return entity;
@ -156,7 +156,7 @@ struct entity *entity_from_handle(struct entity_store *store, struct entity_hand
struct entity *entity_find_first_match_one(struct entity_store *store, enum entity_prop prop) struct entity *entity_find_first_match_one(struct entity_store *store, enum entity_prop prop)
{ {
u64 count = store->reserved; u64 count = store->num_reserved;
struct entity *entities = store->entities; struct entity *entities = store->entities;
for (u64 entity_index = 0; entity_index < count; ++entity_index) { for (u64 entity_index = 0; entity_index < count; ++entity_index) {
struct entity *ent = &entities[entity_index]; struct entity *ent = &entities[entity_index];
@ -169,7 +169,7 @@ struct entity *entity_find_first_match_one(struct entity_store *store, enum enti
struct entity *entity_find_first_match_all(struct entity_store *store, struct entity_prop_array props) struct entity *entity_find_first_match_all(struct entity_store *store, struct entity_prop_array props)
{ {
u64 count = store->reserved; u64 count = store->num_reserved;
struct entity *entities = store->entities; struct entity *entities = store->entities;
for (u64 entity_index = 0; entity_index < count; ++entity_index) { for (u64 entity_index = 0; entity_index < count; ++entity_index) {
struct entity *ent = &entities[entity_index]; struct entity *ent = &entities[entity_index];

View File

@ -50,8 +50,8 @@ enum entity_prop {
struct entity_store { struct entity_store {
b32 valid; b32 valid;
struct arena arena; struct arena arena;
u64 allocated; u64 num_allocated;
u64 reserved; u64 num_reserved;
struct entity_handle first_free; struct entity_handle first_free;
struct entity_handle root; struct entity_handle root;
struct entity *entities; struct entity *entities;

View File

@ -72,7 +72,6 @@ struct game_startup_receipt game_startup(struct mixer_startup_receipt *mixer_sr,
G.client_store = client_store_alloc(); G.client_store = client_store_alloc();
/* Intialize host */ /* Intialize host */
//struct sock_address bind_address = sock_address_from_port(12345);
G.host = host_alloc(12345); G.host = host_alloc(12345);
/* Initialize empty world */ /* Initialize empty world */
@ -307,7 +306,7 @@ INTERNAL void release_entities_with_prop(enum entity_prop prop)
struct entity **ents_to_release = arena_dry_push(scratch.arena, struct entity *); struct entity **ents_to_release = arena_dry_push(scratch.arena, struct entity *);
u64 ents_to_release_count = 0; u64 ents_to_release_count = 0;
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) { for (u64 entity_index = 0; entity_index < store->num_reserved; ++entity_index) {
struct entity *ent = &store->entities[entity_index]; struct entity *ent = &store->entities[entity_index];
if (!ent->valid) continue; if (!ent->valid) continue;
@ -496,7 +495,7 @@ INTERNAL void game_update(void)
* Activate entities * Activate entities
* ========================== */ * ========================== */
for (u64 entity_index = 0; entity_index < entity_store->reserved; ++entity_index) { for (u64 entity_index = 0; entity_index < entity_store->num_reserved; ++entity_index) {
struct entity *ent = &entity_store->entities[entity_index]; struct entity *ent = &entity_store->entities[entity_index];
if (!ent->valid) continue; if (!ent->valid) continue;
@ -512,7 +511,7 @@ INTERNAL void game_update(void)
* Reset triggered entities * Reset triggered entities
* ========================== */ * ========================== */
for (u64 entity_index = 0; entity_index < entity_store->reserved; ++entity_index) { for (u64 entity_index = 0; entity_index < entity_store->num_reserved; ++entity_index) {
struct entity *ent = &entity_store->entities[entity_index]; struct entity *ent = &entity_store->entities[entity_index];
if (!entity_is_valid_and_active(ent)) continue; if (!entity_is_valid_and_active(ent)) continue;
@ -594,7 +593,7 @@ INTERNAL void game_update(void)
* Update entities from sprite * Update entities from sprite
* ========================== */ * ========================== */
for (u64 entity_index = 0; entity_index < entity_store->reserved; ++entity_index) { for (u64 entity_index = 0; entity_index < entity_store->num_reserved; ++entity_index) {
struct entity *ent = &entity_store->entities[entity_index]; struct entity *ent = &entity_store->entities[entity_index];
if (!entity_is_valid_and_active(ent)) continue; if (!entity_is_valid_and_active(ent)) continue;
if (sprite_tag_is_nil(ent->sprite)) continue; if (sprite_tag_is_nil(ent->sprite)) continue;
@ -689,7 +688,7 @@ INTERNAL void game_update(void)
* Update attachments * Update attachments
* ========================== */ * ========================== */
for (u64 entity_index = 0; entity_index < entity_store->reserved; ++entity_index) { for (u64 entity_index = 0; entity_index < entity_store->num_reserved; ++entity_index) {
struct entity *ent = &entity_store->entities[entity_index]; struct entity *ent = &entity_store->entities[entity_index];
if (!entity_is_valid_and_active(ent)) continue; if (!entity_is_valid_and_active(ent)) continue;
if (!entity_has_prop(ent, ENTITY_PROP_ATTACHED)) continue; if (!entity_has_prop(ent, ENTITY_PROP_ATTACHED)) continue;
@ -714,7 +713,7 @@ INTERNAL void game_update(void)
* Update control from player cmds * Update control from player cmds
* ========================== */ * ========================== */
for (u64 entity_index = 0; entity_index < entity_store->reserved; ++entity_index) { for (u64 entity_index = 0; entity_index < entity_store->num_reserved; ++entity_index) {
struct entity *ent = &entity_store->entities[entity_index]; struct entity *ent = &entity_store->entities[entity_index];
if (!entity_is_valid_and_active(ent)) continue; if (!entity_is_valid_and_active(ent)) continue;
@ -773,7 +772,7 @@ INTERNAL void game_update(void)
* ========================== */ * ========================== */
#if 0 #if 0
for (u64 entity_index = 0; entity_index < entity_store->reserved; ++entity_index) { for (u64 entity_index = 0; entity_index < entity_store->num_reserved; ++entity_index) {
struct entity *ent = &entity_store->entities[entity_index]; struct entity *ent = &entity_store->entities[entity_index];
if (!entity_is_valid_and_active(ent)) continue; if (!entity_is_valid_and_active(ent)) continue;
if (!entity_has_prop(ent, ENTITY_PROP_TEST)) continue; if (!entity_has_prop(ent, ENTITY_PROP_TEST)) continue;
@ -823,7 +822,7 @@ INTERNAL void game_update(void)
* Trigger equipped * Trigger equipped
* ========================== */ * ========================== */
for (u64 entity_index = 0; entity_index < entity_store->reserved; ++entity_index) { for (u64 entity_index = 0; entity_index < entity_store->num_reserved; ++entity_index) {
struct entity *ent = &entity_store->entities[entity_index]; struct entity *ent = &entity_store->entities[entity_index];
if (!entity_is_valid_and_active(ent)) continue; if (!entity_is_valid_and_active(ent)) continue;
@ -839,7 +838,7 @@ INTERNAL void game_update(void)
* Process triggered entities * Process triggered entities
* ========================== */ * ========================== */
for (u64 entity_index = 0; entity_index < entity_store->reserved; ++entity_index) { for (u64 entity_index = 0; entity_index < entity_store->num_reserved; ++entity_index) {
struct entity *ent = &entity_store->entities[entity_index]; struct entity *ent = &entity_store->entities[entity_index];
if (!entity_is_valid_and_active(ent)) continue; if (!entity_is_valid_and_active(ent)) continue;
if (!entity_has_prop(ent, ENTITY_PROP_TRIGGERED_THIS_TICK)) continue; if (!entity_has_prop(ent, ENTITY_PROP_TRIGGERED_THIS_TICK)) continue;
@ -903,7 +902,7 @@ INTERNAL void game_update(void)
* ========================== */ * ========================== */
#if 0 #if 0
for (u64 entity_index = 0; entity_index < entity_store->reserved; ++entity_index) { for (u64 entity_index = 0; entity_index < entity_store->num_reserved; ++entity_index) {
struct entity *ent = &entity_store->entities[entity_index]; struct entity *ent = &entity_store->entities[entity_index];
if (!entity_is_valid_and_active(ent)) continue; if (!entity_is_valid_and_active(ent)) continue;
@ -914,7 +913,7 @@ INTERNAL void game_update(void)
} }
} }
#else #else
for (u64 entity_index = 0; entity_index < entity_store->reserved; ++entity_index) { for (u64 entity_index = 0; entity_index < entity_store->num_reserved; ++entity_index) {
struct entity *ent = &entity_store->entities[entity_index]; struct entity *ent = &entity_store->entities[entity_index];
if (!entity_is_valid_and_active(ent)) continue; if (!entity_is_valid_and_active(ent)) continue;
@ -948,7 +947,7 @@ INTERNAL void game_update(void)
* ========================== */ * ========================== */
#if GAME_PLAYER_AIM #if GAME_PLAYER_AIM
for (u64 entity_index = 0; entity_index < entity_store->reserved; ++entity_index) { for (u64 entity_index = 0; entity_index < entity_store->num_reserved; ++entity_index) {
struct entity *ent = &entity_store->entities[entity_index]; struct entity *ent = &entity_store->entities[entity_index];
if (!entity_is_valid_and_active(ent)) continue; if (!entity_is_valid_and_active(ent)) continue;
@ -1041,7 +1040,7 @@ INTERNAL void game_update(void)
* Create ground friction force (gravity) * Create ground friction force (gravity)
* ========================== */ * ========================== */
for (u64 entity_index = 0; entity_index < entity_store->reserved; ++entity_index) { for (u64 entity_index = 0; entity_index < entity_store->num_reserved; ++entity_index) {
struct entity *ent = &entity_store->entities[entity_index]; struct entity *ent = &entity_store->entities[entity_index];
if (!entity_is_valid_and_active(ent)) continue; if (!entity_is_valid_and_active(ent)) continue;
if (!entity_has_prop(ent, ENTITY_PROP_PHYSICAL_DYNAMIC)) continue; if (!entity_has_prop(ent, ENTITY_PROP_PHYSICAL_DYNAMIC)) continue;
@ -1100,7 +1099,7 @@ INTERNAL void game_update(void)
* Update tracers * Update tracers
* ========================== */ * ========================== */
for (u64 entity_index = 0; entity_index < entity_store->reserved; ++entity_index) { for (u64 entity_index = 0; entity_index < entity_store->num_reserved; ++entity_index) {
struct entity *ent = &entity_store->entities[entity_index]; struct entity *ent = &entity_store->entities[entity_index];
if (!entity_is_valid_and_active(ent)) continue; if (!entity_is_valid_and_active(ent)) continue;
if (!entity_has_prop(ent, ENTITY_PROP_TRACER)) continue; if (!entity_has_prop(ent, ENTITY_PROP_TRACER)) continue;
@ -1124,7 +1123,7 @@ INTERNAL void game_update(void)
* Initialize bullet kinematics from sources * Initialize bullet kinematics from sources
* ========================== */ * ========================== */
for (u64 entity_index = 0; entity_index < entity_store->reserved; ++entity_index) { for (u64 entity_index = 0; entity_index < entity_store->num_reserved; ++entity_index) {
struct entity *ent = &entity_store->entities[entity_index]; struct entity *ent = &entity_store->entities[entity_index];
if (!entity_is_valid_and_active(ent)) continue; if (!entity_is_valid_and_active(ent)) continue;
if (!entity_has_prop(ent, ENTITY_PROP_BULLET)) continue; if (!entity_has_prop(ent, ENTITY_PROP_BULLET)) continue;
@ -1179,7 +1178,7 @@ INTERNAL void game_update(void)
* Update cameras * Update cameras
* ========================== */ * ========================== */
for (u64 entity_index = 0; entity_index < entity_store->reserved; ++entity_index) { for (u64 entity_index = 0; entity_index < entity_store->num_reserved; ++entity_index) {
struct entity *ent = &entity_store->entities[entity_index]; struct entity *ent = &entity_store->entities[entity_index];
if (!entity_is_valid_and_active(ent)) continue; if (!entity_is_valid_and_active(ent)) continue;
if (!entity_has_prop(ent, ENTITY_PROP_CAMERA)) continue; if (!entity_has_prop(ent, ENTITY_PROP_CAMERA)) continue;
@ -1220,7 +1219,7 @@ INTERNAL void game_update(void)
{ {
/* TODO: Update based on distance to quake */ /* TODO: Update based on distance to quake */
ent->shake = 0; ent->shake = 0;
for (u64 quake_ent_index = 0; quake_ent_index < entity_store->reserved; ++quake_ent_index) { for (u64 quake_ent_index = 0; quake_ent_index < entity_store->num_reserved; ++quake_ent_index) {
struct entity *quake = &entity_store->entities[quake_ent_index]; struct entity *quake = &entity_store->entities[quake_ent_index];
if (!entity_is_valid_and_active(quake)) continue; if (!entity_is_valid_and_active(quake)) continue;
if (!entity_has_prop(quake, ENTITY_PROP_QUAKE)) continue; if (!entity_has_prop(quake, ENTITY_PROP_QUAKE)) continue;
@ -1235,7 +1234,7 @@ INTERNAL void game_update(void)
* Update quakes * Update quakes
* ========================== */ * ========================== */
for (u64 entity_index = 0; entity_index < entity_store->reserved; ++entity_index) { for (u64 entity_index = 0; entity_index < entity_store->num_reserved; ++entity_index) {
struct entity *ent = &entity_store->entities[entity_index]; struct entity *ent = &entity_store->entities[entity_index];
if (!entity_is_valid_and_active(ent)) continue; if (!entity_is_valid_and_active(ent)) continue;
if (!entity_has_prop(ent, ENTITY_PROP_QUAKE)) continue; if (!entity_has_prop(ent, ENTITY_PROP_QUAKE)) continue;
@ -1283,7 +1282,7 @@ INTERNAL void game_update(void)
* user thread. This is so sounds play at the correct time on the user * user thread. This is so sounds play at the correct time on the user
* thread regardless of interp delay. */ * thread regardless of interp delay. */
for (u64 entity_index = 0; entity_index < entity_store->reserved; ++entity_index) { for (u64 entity_index = 0; entity_index < entity_store->num_reserved; ++entity_index) {
struct entity *ent = &entity_store->entities[entity_index]; struct entity *ent = &entity_store->entities[entity_index];
if (!entity_is_valid_and_active(ent)) continue; if (!entity_is_valid_and_active(ent)) continue;
@ -1360,7 +1359,7 @@ struct string game_string_from_cmds(struct arena *arena, struct game_cmd_list cm
bw_write_i8(&bw, cmd->kind); bw_write_i8(&bw, cmd->kind);
bw_write_i8(&bw, cmd->state); bw_write_i8(&bw, cmd->state);
#if RTC #if COLLIDER_DEBUG
bw_write_u32(&bw, cmd->collider_gjk_steps); bw_write_u32(&bw, cmd->collider_gjk_steps);
#endif #endif
@ -1428,7 +1427,7 @@ void game_cmds_from_host_events(struct arena *arena, struct host_event_array hos
u64 cmd_pos_end = br_pos(&br) + cmd_size; u64 cmd_pos_end = br_pos(&br) + cmd_size;
cmd->kind = br_read_i8(&br); cmd->kind = br_read_i8(&br);
cmd->state = br_read_i8(&br); cmd->state = br_read_i8(&br);
#if RTC #if COLLIDER_DEBUG
cmd->collider_gjk_steps = br_read_u32(&br); cmd->collider_gjk_steps = br_read_u32(&br);
#endif #endif
@ -1563,13 +1562,13 @@ struct string game_string_from_tick(struct arena *arena, struct world *tick)
bw_write_var_sint(&bw, tick->dt_ns); bw_write_var_sint(&bw, tick->dt_ns);
bw_write_var_sint(&bw, tick->time_ns); bw_write_var_sint(&bw, tick->time_ns);
u64 num_entities = tick->entity_store->reserved; u64 num_entities = tick->entity_store->num_reserved;
bw_write_var_uint(&bw, num_entities); bw_write_var_uint(&bw, num_entities);
struct string entities_src = ZI; struct string entities_src = ZI;
entities_src.text = (u8 *)tick->entity_store->entities; entities_src.text = (u8 *)tick->entity_store->entities;
entities_src.len = sizeof(struct entity) * num_entities; entities_src.len = sizeof(struct entity) * num_entities;
bw_write_buffer(&bw, entities_src); br_write_bytes(&bw, entities_src);
return bw_get_written(&bw); return bw_get_written(&bw);
} }
@ -1588,14 +1587,18 @@ void game_tick_from_string(struct string str, struct world *tick_out)
tick_out->time_ns = br_read_var_sint(&br); tick_out->time_ns = br_read_var_sint(&br);
u64 num_entities = br_read_var_uint(&br); u64 num_entities = br_read_var_uint(&br);
arena_push_array(&tick_out->entity_store->arena, struct entity, num_entities - tick_out->entity_store->reserved); arena_push_array(&tick_out->entity_store->arena, struct entity, num_entities - tick_out->entity_store->num_reserved);
tick_out->entity_store->reserved = num_entities; tick_out->entity_store->num_reserved = num_entities;
tick_out->entity_store->num_allocated = 0;
struct entity *entities_src = br_seek(&br, num_entities * sizeof(struct entity)); struct entity *entities_src = br_seek(&br, num_entities * sizeof(struct entity));
if (entities_src) { if (entities_src) {
for (u64 i = 0; i < num_entities; ++i) { for (u64 i = 0; i < num_entities; ++i) {
struct entity *src = &entities_src[i]; struct entity *src = &entities_src[i];
struct entity *dst = &tick_out->entity_store->entities[i]; struct entity *dst = &tick_out->entity_store->entities[i];
if (dst->valid) {
++tick_out->entity_store->num_allocated;
}
*dst = *src; *dst = *src;
} }
} }

View File

@ -31,12 +31,11 @@ enum host_packet_flag {
HOST_PACKET_FLAG_RELIABLE = (1 << 0) HOST_PACKET_FLAG_RELIABLE = (1 << 0)
}; };
struct host_packet { struct host_snd_packet {
struct host_snd_packet *next;
u64 seq; u64 seq;
u8 flags;
u64 data_len;
struct host_packet *next;
u64 data_len;
u8 data[PACKET_DATA_MAX_LEN]; u8 data[PACKET_DATA_MAX_LEN];
}; };
@ -54,10 +53,10 @@ struct host_channel {
struct host_channel *prev_address_hash; struct host_channel *prev_address_hash;
/* NOTE: Packets are allocated in host's `arena` */ /* NOTE: Packets are allocated in host's `arena` */
struct host_packet *first_reliable_packet; struct host_snd_packet *first_reliable_packet;
struct host_packet *last_reliable_packet; struct host_snd_packet *last_reliable_packet;
struct host_packet *first_unreliable_packet; struct host_snd_packet *first_unreliable_packet;
struct host_packet *last_unreliable_packet; struct host_snd_packet *last_unreliable_packet;
u64 num_reliable_packets; u64 num_reliable_packets;
u64 num_unreliable_packets; u64 num_unreliable_packets;
@ -91,17 +90,17 @@ struct host_queued_event {
struct host_queued_event *next; struct host_queued_event *next;
}; };
struct host_recv_packet { struct host_rcv_packet {
struct sock *sock; struct sock *sock;
struct sock_address address; struct sock_address address;
struct string data; struct string data;
struct host_recv_packet *next; struct host_rcv_packet *next;
}; };
struct host_recv_buffer { struct host_rcv_buffer {
struct arena arena; struct arena arena;
struct host_recv_packet *first_packet; struct host_rcv_packet *first_packet;
struct host_recv_packet *last_packet; struct host_rcv_packet *last_packet;
}; };
struct host_msg_assembler { struct host_msg_assembler {
@ -171,10 +170,10 @@ struct host *host_alloc(u16 listen_port)
host->cmd_arena = arena_alloc(GIGABYTE(64)); host->cmd_arena = arena_alloc(GIGABYTE(64));
host->queued_event_arena = arena_alloc(GIGABYTE(64)); host->queued_event_arena = arena_alloc(GIGABYTE(64));
host->channel_arena = arena_alloc(GIGABYTE(64)); host->channel_arena = arena_alloc(GIGABYTE(64));
host->recv_buffer_read = arena_push_zero(&host->arena, struct host_recv_buffer); host->rcv_buffer_read = arena_push_zero(&host->arena, struct host_rcv_buffer);
host->recv_buffer_write = arena_push_zero(&host->arena, struct host_recv_buffer); host->rcv_buffer_write = arena_push_zero(&host->arena, struct host_rcv_buffer);
host->recv_buffer_read->arena = arena_alloc(GIGABYTE(64)); host->rcv_buffer_read->arena = arena_alloc(GIGABYTE(64));
host->recv_buffer_write->arena = arena_alloc(GIGABYTE(64)); host->rcv_buffer_write->arena = arena_alloc(GIGABYTE(64));
host->buddy = buddy_ctx_alloc(GIGABYTE(64)); host->buddy = buddy_ctx_alloc(GIGABYTE(64));
host->channels = arena_dry_push(&host->channel_arena, struct host_channel); host->channels = arena_dry_push(&host->channel_arena, struct host_channel);
@ -185,9 +184,9 @@ struct host *host_alloc(u16 listen_port)
host->num_msg_assembler_lookup_buckets = NUM_MSG_ASSEMBLER_LOOKUP_BUCKETS; host->num_msg_assembler_lookup_buckets = NUM_MSG_ASSEMBLER_LOOKUP_BUCKETS;
host->msg_assembler_lookup_buckets = arena_push_array_zero(&host->arena, struct host_msg_assembler_lookup_bucket, host->num_msg_assembler_lookup_buckets); host->msg_assembler_lookup_buckets = arena_push_array_zero(&host->arena, struct host_msg_assembler_lookup_bucket, host->num_msg_assembler_lookup_buckets);
host->sock = sock_alloc(listen_port); host->sock = sock_alloc(listen_port, MEGABYTE(2), MEGABYTE(2));
host->recv_buffer_write_mutex = sys_mutex_alloc(); host->rcv_buffer_write_mutex = sys_mutex_alloc();
host->receiver_thread = sys_thread_alloc(&host_receiver_thread_entry_point, host, LIT("[P6] Host receiver")); host->receiver_thread = sys_thread_alloc(&host_receiver_thread_entry_point, host, LIT("[P6] Host receiver"));
return host; return host;
@ -198,13 +197,13 @@ void host_release(struct host *host)
/* FIXME: Signal thread shutdown */ /* FIXME: Signal thread shutdown */
sys_thread_wait_release(&host->receiver_thread); sys_thread_wait_release(&host->receiver_thread);
sys_mutex_release(&host->recv_buffer_write_mutex); sys_mutex_release(&host->rcv_buffer_write_mutex);
sock_release(host->sock); sock_release(host->sock);
buddy_ctx_release(host->buddy); buddy_ctx_release(host->buddy);
arena_release(&host->recv_buffer_write->arena); arena_release(&host->rcv_buffer_write->arena);
arena_release(&host->recv_buffer_read->arena); arena_release(&host->rcv_buffer_read->arena);
arena_release(&host->channel_arena); arena_release(&host->channel_arena);
arena_release(&host->queued_event_arena); arena_release(&host->queued_event_arena);
arena_release(&host->cmd_arena); arena_release(&host->cmd_arena);
@ -532,15 +531,15 @@ INTERNAL void host_msg_assembler_set_chunk_received(struct host_msg_assembler *m
* Packet * Packet
* ========================== */ * ========================== */
INTERNAL struct host_packet *host_channel_packet_alloc(struct host_channel *channel, b32 is_reliable) INTERNAL struct host_snd_packet *host_channel_snd_packet_alloc(struct host_channel *channel, b32 is_reliable)
{ {
struct host *host = channel->host; struct host *host = channel->host;
struct host_packet *packet = NULL; struct host_snd_packet *packet = NULL;
if (host->first_free_packet) { if (host->first_free_packet) {
packet = host->first_free_packet; packet = host->first_free_packet;
host->first_free_packet = packet->next; host->first_free_packet = packet->next;
} else { } else {
packet = arena_push(&host->arena, struct host_packet); packet = arena_push(&host->arena, struct host_snd_packet);
} }
MEMZERO_STRUCT(packet); MEMZERO_STRUCT(packet);
@ -635,17 +634,17 @@ void host_update(struct host *host)
read_buff.len = PACKET_DATA_MAX_LEN; read_buff.len = PACKET_DATA_MAX_LEN;
read_buff.text = arena_push_array(scratch.arena, u8, read_buff.len); read_buff.text = arena_push_array(scratch.arena, u8, read_buff.len);
/* Swap read & write recv buffers */ /* Swap read & write rcv buffers */
{ {
struct sys_lock lock = sys_mutex_lock_e(&host->recv_buffer_write_mutex); struct sys_lock lock = sys_mutex_lock_e(&host->rcv_buffer_write_mutex);
struct host_recv_buffer *swp = host->recv_buffer_read; struct host_rcv_buffer *swp = host->rcv_buffer_read;
host->recv_buffer_read = host->recv_buffer_write; host->rcv_buffer_read = host->rcv_buffer_write;
host->recv_buffer_write = swp; host->rcv_buffer_write = swp;
sys_mutex_unlock(&lock); sys_mutex_unlock(&lock);
} }
/* Read incoming packets */ /* Read incoming packets */
struct host_recv_buffer *recv_buffer = host->recv_buffer_read; struct host_rcv_buffer *rcv_buffer = host->rcv_buffer_read;
for (struct host_recv_packet *packet = recv_buffer->first_packet; packet; packet = packet->next) { for (struct host_rcv_packet *packet = rcv_buffer->first_packet; packet; packet = packet->next) {
//struct sock *sock = packet->sock; //struct sock *sock = packet->sock;
struct sock_address address = packet->address; struct sock_address address = packet->address;
struct byte_reader br = br_from_buffer(packet->data); struct byte_reader br = br_from_buffer(packet->data);
@ -772,9 +771,9 @@ void host_update(struct host *host)
} }
} }
/* Reset read buffer */ /* Reset read buffer */
recv_buffer->first_packet = NULL; rcv_buffer->first_packet = NULL;
recv_buffer->last_packet = NULL; rcv_buffer->last_packet = NULL;
arena_reset(&recv_buffer->arena); arena_reset(&rcv_buffer->arena);
} }
/* Update channels */ /* Update channels */
@ -792,9 +791,9 @@ void host_update(struct host *host)
/* Release acked reliable packets */ /* Release acked reliable packets */
{ {
u64 acked_seq = channel->their_acked_seq; u64 acked_seq = channel->their_acked_seq;
struct host_packet *host_packet = channel->first_reliable_packet; struct host_snd_packet *host_packet = channel->first_reliable_packet;
while (host_packet) { while (host_packet) {
struct host_packet *next = host_packet->next; struct host_snd_packet *next = host_packet->next;
u64 seq = host_packet->seq; u64 seq = host_packet->seq;
if (seq < acked_seq) { if (seq < acked_seq) {
host_packet->next = host->first_free_packet; host_packet->next = host->first_free_packet;
@ -810,10 +809,10 @@ void host_update(struct host *host)
channel->last_reliable_packet = NULL; channel->last_reliable_packet = NULL;
} }
} }
/* TODO: Release timed out unreliable msg buffers */ /* Release timed out unreliable msg buffers */
{ {
/* TODO: Configurable timeout */ /* TODO: Configurable timeout */
i64 timeout_ns = NS_FROM_SECONDS(4); i64 timeout_ns = NS_FROM_SECONDS(1);
struct host_msg_assembler *ma = channel->least_recent_msg_assembler; struct host_msg_assembler *ma = channel->least_recent_msg_assembler;
while (ma) { while (ma) {
struct host_msg_assembler *next = ma->more_recent; struct host_msg_assembler *next = ma->more_recent;
@ -845,7 +844,7 @@ void host_update(struct host *host)
case HOST_CMD_KIND_TRY_CONNECT: case HOST_CMD_KIND_TRY_CONNECT:
{ {
u8 packet_flags = 0; u8 packet_flags = 0;
struct host_packet *host_packet = host_channel_packet_alloc(channel, false); struct host_snd_packet *host_packet = host_channel_snd_packet_alloc(channel, false);
struct byte_writer bw = bw_from_buffer(STRING_FROM_ARRAY(host_packet->data)); struct byte_writer bw = bw_from_buffer(STRING_FROM_ARRAY(host_packet->data));
bw_write_u32(&bw, PACKET_MAGIC); bw_write_u32(&bw, PACKET_MAGIC);
bw_write_i8(&bw, HOST_PACKET_KIND_TRY_CONNECT); bw_write_i8(&bw, HOST_PACKET_KIND_TRY_CONNECT);
@ -857,7 +856,7 @@ void host_update(struct host *host)
case HOST_CMD_KIND_CONNECT_SUCCESS: case HOST_CMD_KIND_CONNECT_SUCCESS:
{ {
u8 packet_flags = 0; u8 packet_flags = 0;
struct host_packet *host_packet = host_channel_packet_alloc(channel, false); struct host_snd_packet *host_packet = host_channel_snd_packet_alloc(channel, false);
struct byte_writer bw = bw_from_buffer(STRING_FROM_ARRAY(host_packet->data)); struct byte_writer bw = bw_from_buffer(STRING_FROM_ARRAY(host_packet->data));
bw_write_u32(&bw, PACKET_MAGIC); bw_write_u32(&bw, PACKET_MAGIC);
bw_write_i8(&bw, HOST_PACKET_KIND_CONNECT_SUCCESS); bw_write_i8(&bw, HOST_PACKET_KIND_CONNECT_SUCCESS);
@ -869,7 +868,7 @@ void host_update(struct host *host)
case HOST_CMD_KIND_DISCONNECT: case HOST_CMD_KIND_DISCONNECT:
{ {
u8 packet_flags = 0; u8 packet_flags = 0;
struct host_packet *host_packet = host_channel_packet_alloc(channel, false); struct host_snd_packet *host_packet = host_channel_snd_packet_alloc(channel, false);
struct byte_writer bw = bw_from_buffer(STRING_FROM_ARRAY(host_packet->data)); struct byte_writer bw = bw_from_buffer(STRING_FROM_ARRAY(host_packet->data));
bw_write_u32(&bw, PACKET_MAGIC); bw_write_u32(&bw, PACKET_MAGIC);
bw_write_i8(&bw, HOST_PACKET_KIND_DISCONNECT); bw_write_i8(&bw, HOST_PACKET_KIND_DISCONNECT);
@ -898,7 +897,7 @@ void host_update(struct host *host)
data_len = msg.len % PACKET_MSG_CHUNK_MAX_LEN; data_len = msg.len % PACKET_MSG_CHUNK_MAX_LEN;
} }
u8 *data = msg.text + (i * PACKET_MSG_CHUNK_MAX_LEN); u8 *data = msg.text + (i * PACKET_MSG_CHUNK_MAX_LEN);
struct host_packet *host_packet = host_channel_packet_alloc(channel, is_reliable); struct host_snd_packet *host_packet = host_channel_snd_packet_alloc(channel, is_reliable);
struct byte_writer bw = bw_from_buffer(STRING_FROM_ARRAY(host_packet->data)); struct byte_writer bw = bw_from_buffer(STRING_FROM_ARRAY(host_packet->data));
bw_write_u32(&bw, PACKET_MAGIC); bw_write_u32(&bw, PACKET_MAGIC);
bw_write_i8(&bw, HOST_PACKET_KIND_MSG_CHUNK); bw_write_i8(&bw, HOST_PACKET_KIND_MSG_CHUNK);
@ -914,7 +913,7 @@ void host_update(struct host *host)
/* FIXME: Ensure data_len can never be 0 */ /* FIXME: Ensure data_len can never be 0 */
bw_write_var_uint(&bw, data_len - 1); bw_write_var_uint(&bw, data_len - 1);
} }
bw_write_buffer(&bw, STRING(data_len, data)); br_write_bytes(&bw, STRING(data_len, data));
host_packet->data_len = bw_pos(&bw); host_packet->data_len = bw_pos(&bw);
} }
} break; } break;
@ -935,11 +934,11 @@ void host_update(struct host *host)
if (channel->valid) { if (channel->valid) {
struct sock_address address = channel->address; struct sock_address address = channel->address;
/* Send reliable packets to channel */ /* Send reliable packets to channel */
for (struct host_packet *host_packet = channel->first_reliable_packet; host_packet; host_packet = host_packet->next) { for (struct host_snd_packet *host_packet = channel->first_reliable_packet; host_packet; host_packet = host_packet->next) {
sock_write(sock, address, STRING(host_packet->data_len, host_packet->data)); sock_write(sock, address, STRING(host_packet->data_len, host_packet->data));
} }
/* Send unreliable packets to channel */ /* Send unreliable packets to channel */
for (struct host_packet *host_packet = channel->first_unreliable_packet; host_packet; host_packet = host_packet->next) { for (struct host_snd_packet *host_packet = channel->first_unreliable_packet; host_packet; host_packet = host_packet->next) {
sock_write(sock, address, STRING(host_packet->data_len, host_packet->data)); sock_write(sock, address, STRING(host_packet->data_len, host_packet->data));
} }
/* Release unreliable packets */ /* Release unreliable packets */
@ -1008,30 +1007,28 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(host_receiver_thread_entry_point, arg)
read_buff.text = arena_push_array(&read_buff_arena, u8, KILOBYTE(64)); read_buff.text = arena_push_array(&read_buff_arena, u8, KILOBYTE(64));
struct host *host = (struct host *)arg; struct host *host = (struct host *)arg;
struct sock *sock = host->sock;
struct sock_array socks = ZI; struct sock_array socks = ZI;
socks.socks = &sock; socks.socks = &host->sock;
socks.count = 1; socks.count = 1;
struct sock_read_result res;
volatile b32 run = true; volatile b32 run = true;
while (run) { while (run) {
res = sock_read_poll(socks, NULL, read_buff, F32_INFINITY); struct sock *sock = sock_wait_for_available_read(socks, NULL, F32_INFINITY);
if (res.valid) { struct sock_read_result res;
struct sys_lock lock = sys_mutex_lock_e(&host->recv_buffer_write_mutex); while (sock && (res = sock_read(sock, read_buff)).valid) {
struct sys_lock lock = sys_mutex_lock_e(&host->rcv_buffer_write_mutex);
{ {
struct host_recv_buffer *recv_buffer = host->recv_buffer_write; struct host_rcv_buffer *rcv_buffer = host->rcv_buffer_write;
struct host_recv_packet *packet = arena_push_zero(&recv_buffer->arena, struct host_recv_packet); struct host_rcv_packet *packet = arena_push_zero(&rcv_buffer->arena, struct host_rcv_packet);
packet->sock = res.sock;
packet->address = res.address; packet->address = res.address;
packet->data = string_copy(&recv_buffer->arena, res.data); packet->data = string_copy(&rcv_buffer->arena, res.data);
if (recv_buffer->last_packet) { if (rcv_buffer->last_packet) {
recv_buffer->last_packet->next = packet; rcv_buffer->last_packet->next = packet;
} else { } else {
recv_buffer->first_packet = packet; rcv_buffer->first_packet = packet;
} }
recv_buffer->last_packet = packet; rcv_buffer->last_packet = packet;
} }
sys_mutex_unlock(&lock); sys_mutex_unlock(&lock);
} }

View File

@ -8,9 +8,9 @@
#define HOST_CHANNEL_ID_ALL (struct host_channel_id) { .gen = U32_MAX, .idx = U32_MAX } #define HOST_CHANNEL_ID_ALL (struct host_channel_id) { .gen = U32_MAX, .idx = U32_MAX }
struct buddy_ctx; struct buddy_ctx;
struct host_packet; struct host_snd_packet;
struct host_channel_lookup_bucket; struct host_channel_lookup_bucket;
struct host_recv_buffer; struct host_rcv_buffer;
enum host_cmd_kind { enum host_cmd_kind {
HOST_CMD_KIND_NONE, HOST_CMD_KIND_NONE,
@ -77,7 +77,7 @@ struct host {
struct host_channel *first_free_channel; struct host_channel *first_free_channel;
u64 num_channels_reserved; u64 num_channels_reserved;
struct host_packet *first_free_packet; /* Allocated in `arena` */ struct host_snd_packet *first_free_packet; /* Allocated in `arena` */
struct host_msg_assembler *first_free_msg_assembler; /* Allocated in `arena` */ struct host_msg_assembler *first_free_msg_assembler; /* Allocated in `arena` */
struct host_channel_lookup_bucket *channel_lookup_buckets; /* Allocated in `arena` */ struct host_channel_lookup_bucket *channel_lookup_buckets; /* Allocated in `arena` */
@ -87,9 +87,9 @@ struct host {
u64 num_msg_assembler_lookup_buckets; u64 num_msg_assembler_lookup_buckets;
/* Double buffer for incoming data */ /* Double buffer for incoming data */
struct sys_mutex recv_buffer_write_mutex; struct sys_mutex rcv_buffer_write_mutex;
struct host_recv_buffer *recv_buffer_read; struct host_rcv_buffer *rcv_buffer_read;
struct host_recv_buffer *recv_buffer_write; struct host_rcv_buffer *rcv_buffer_write;
struct sys_thread receiver_thread; struct sys_thread receiver_thread;
}; };

View File

@ -52,7 +52,7 @@ struct phys_collision_data_array phys_create_and_update_contacts(struct arena *a
struct entity_store *store = ctx->store; struct entity_store *store = ctx->store;
struct entity *root = entity_from_handle(store, store->root); struct entity *root = entity_from_handle(store, store->root);
for (u64 check0_index = 0; check0_index < store->reserved; ++check0_index) { for (u64 check0_index = 0; check0_index < store->num_reserved; ++check0_index) {
struct entity *check0 = &store->entities[check0_index]; struct entity *check0 = &store->entities[check0_index];
if (!entity_is_valid_and_active(check0)) continue; if (!entity_is_valid_and_active(check0)) continue;
if (!(entity_has_prop(check0, ENTITY_PROP_PHYSICAL_DYNAMIC) || entity_has_prop(check0, ENTITY_PROP_PHYSICAL_KINEMATIC))) continue; if (!(entity_has_prop(check0, ENTITY_PROP_PHYSICAL_DYNAMIC) || entity_has_prop(check0, ENTITY_PROP_PHYSICAL_KINEMATIC))) continue;
@ -224,7 +224,7 @@ struct phys_collision_data_array phys_create_and_update_contacts(struct arena *a
contact->point_local_e1 = xform_invert_mul_v2(e1_xf, point); contact->point_local_e1 = xform_invert_mul_v2(e1_xf, point);
contact->starting_separation = sep; contact->starting_separation = sep;
#if COLLIDER_DEBUG #if DEVELOPER
contact->dbg_pt = point; contact->dbg_pt = point;
#endif #endif
} }
@ -286,7 +286,7 @@ void phys_prepare_contacts(struct phys_ctx *ctx, u64 phys_iteration)
struct entity_lookup *contact_lookup = ctx->contact_lookup; struct entity_lookup *contact_lookup = ctx->contact_lookup;
struct entity_store *store = ctx->store; struct entity_store *store = ctx->store;
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) { for (u64 entity_index = 0; entity_index < store->num_reserved; ++entity_index) {
struct entity *constraint_ent = &store->entities[entity_index]; struct entity *constraint_ent = &store->entities[entity_index];
if (!entity_is_valid_and_active(constraint_ent)) continue; if (!entity_is_valid_and_active(constraint_ent)) continue;
if (!entity_has_prop(constraint_ent, ENTITY_PROP_CONTACT_CONSTRAINT)) continue; if (!entity_has_prop(constraint_ent, ENTITY_PROP_CONTACT_CONSTRAINT)) continue;
@ -377,7 +377,7 @@ void phys_prepare_contacts(struct phys_ctx *ctx, u64 phys_iteration)
#if COLLIDER_DEBUG #if COLLIDER_DEBUG
struct entity_lookup *debug_lookup = ctx->debug_lookup; struct entity_lookup *debug_lookup = ctx->debug_lookup;
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) { for (u64 entity_index = 0; entity_index < store->num_reserved; ++entity_index) {
struct entity *dbg_ent = &store->entities[entity_index]; struct entity *dbg_ent = &store->entities[entity_index];
if (!entity_is_valid_and_active(dbg_ent)) continue; if (!entity_is_valid_and_active(dbg_ent)) continue;
if (!entity_has_prop(dbg_ent, ENTITY_PROP_COLLISION_DEBUG)) continue; if (!entity_has_prop(dbg_ent, ENTITY_PROP_COLLISION_DEBUG)) continue;
@ -412,7 +412,7 @@ void phys_warm_start_contacts(struct phys_ctx *ctx)
{ {
__prof; __prof;
struct entity_store *store = ctx->store; struct entity_store *store = ctx->store;
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) { for (u64 entity_index = 0; entity_index < store->num_reserved; ++entity_index) {
struct entity *constraint_ent = &store->entities[entity_index]; struct entity *constraint_ent = &store->entities[entity_index];
if (!entity_is_valid_and_active(constraint_ent)) continue; if (!entity_is_valid_and_active(constraint_ent)) continue;
if (!entity_has_prop(constraint_ent, ENTITY_PROP_CONTACT_CONSTRAINT)) continue; if (!entity_has_prop(constraint_ent, ENTITY_PROP_CONTACT_CONSTRAINT)) continue;
@ -467,7 +467,7 @@ void phys_solve_contacts(struct phys_ctx *ctx, f32 dt, b32 apply_bias)
{ {
__prof; __prof;
struct entity_store *store = ctx->store; struct entity_store *store = ctx->store;
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) { for (u64 entity_index = 0; entity_index < store->num_reserved; ++entity_index) {
struct entity *constraint_ent = &store->entities[entity_index]; struct entity *constraint_ent = &store->entities[entity_index];
if (!entity_is_valid_and_active(constraint_ent)) continue; if (!entity_is_valid_and_active(constraint_ent)) continue;
if (!entity_has_prop(constraint_ent, ENTITY_PROP_CONTACT_CONSTRAINT)) continue; if (!entity_has_prop(constraint_ent, ENTITY_PROP_CONTACT_CONSTRAINT)) continue;
@ -598,7 +598,7 @@ void phys_prepare_motor_joints(struct phys_ctx *ctx)
{ {
__prof; __prof;
struct entity_store *store = ctx->store; struct entity_store *store = ctx->store;
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) { for (u64 entity_index = 0; entity_index < store->num_reserved; ++entity_index) {
struct entity *joint_ent = &store->entities[entity_index]; struct entity *joint_ent = &store->entities[entity_index];
if (!entity_is_valid_and_active(joint_ent)) continue; if (!entity_is_valid_and_active(joint_ent)) continue;
if (!entity_has_prop(joint_ent, ENTITY_PROP_MOTOR_JOINT)) continue; if (!entity_has_prop(joint_ent, ENTITY_PROP_MOTOR_JOINT)) continue;
@ -662,7 +662,7 @@ void phys_warm_start_motor_joints(struct phys_ctx *ctx)
{ {
__prof; __prof;
struct entity_store *store = ctx->store; struct entity_store *store = ctx->store;
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) { for (u64 entity_index = 0; entity_index < store->num_reserved; ++entity_index) {
struct entity *joint_ent = &store->entities[entity_index]; struct entity *joint_ent = &store->entities[entity_index];
if (!entity_is_valid_and_active(joint_ent)) continue; if (!entity_is_valid_and_active(joint_ent)) continue;
if (!entity_has_prop(joint_ent, ENTITY_PROP_MOTOR_JOINT)) continue; if (!entity_has_prop(joint_ent, ENTITY_PROP_MOTOR_JOINT)) continue;
@ -694,7 +694,7 @@ void phys_solve_motor_joints(struct phys_ctx *ctx, f32 dt)
{ {
__prof; __prof;
struct entity_store *store = ctx->store; struct entity_store *store = ctx->store;
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) { for (u64 entity_index = 0; entity_index < store->num_reserved; ++entity_index) {
struct entity *joint_ent = &store->entities[entity_index]; struct entity *joint_ent = &store->entities[entity_index];
if (!entity_is_valid_and_active(joint_ent)) continue; if (!entity_is_valid_and_active(joint_ent)) continue;
if (!entity_has_prop(joint_ent, ENTITY_PROP_MOTOR_JOINT)) continue; if (!entity_has_prop(joint_ent, ENTITY_PROP_MOTOR_JOINT)) continue;
@ -789,7 +789,7 @@ void phys_create_mouse_joints(struct phys_ctx *ctx)
mouse_shape.points[0] = V2(0, 0); mouse_shape.points[0] = V2(0, 0);
mouse_shape.count = 1; mouse_shape.count = 1;
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) { for (u64 entity_index = 0; entity_index < store->num_reserved; ++entity_index) {
struct entity *ent = &store->entities[entity_index]; struct entity *ent = &store->entities[entity_index];
if (!entity_is_valid_and_active(ent)) continue; if (!entity_is_valid_and_active(ent)) continue;
if (!entity_has_prop(ent, ENTITY_PROP_PHYSICAL_DYNAMIC)) continue; if (!entity_has_prop(ent, ENTITY_PROP_PHYSICAL_DYNAMIC)) continue;
@ -843,7 +843,7 @@ void phys_prepare_mouse_joints(struct phys_ctx *ctx)
{ {
__prof; __prof;
struct entity_store *store = ctx->store; struct entity_store *store = ctx->store;
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) { for (u64 entity_index = 0; entity_index < store->num_reserved; ++entity_index) {
struct entity *joint_ent = &store->entities[entity_index]; struct entity *joint_ent = &store->entities[entity_index];
if (!entity_is_valid_and_active(joint_ent)) continue; if (!entity_is_valid_and_active(joint_ent)) continue;
if (!entity_has_prop(joint_ent, ENTITY_PROP_MOUSE_JOINT)) continue; if (!entity_has_prop(joint_ent, ENTITY_PROP_MOUSE_JOINT)) continue;
@ -890,7 +890,7 @@ void phys_warm_start_mouse_joints(struct phys_ctx *ctx)
{ {
__prof; __prof;
struct entity_store *store = ctx->store; struct entity_store *store = ctx->store;
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) { for (u64 entity_index = 0; entity_index < store->num_reserved; ++entity_index) {
struct entity *joint_ent = &store->entities[entity_index]; struct entity *joint_ent = &store->entities[entity_index];
if (!entity_is_valid_and_active(joint_ent)) continue; if (!entity_is_valid_and_active(joint_ent)) continue;
if (!entity_has_prop(joint_ent, ENTITY_PROP_MOUSE_JOINT)) continue; if (!entity_has_prop(joint_ent, ENTITY_PROP_MOUSE_JOINT)) continue;
@ -912,7 +912,7 @@ void phys_solve_mouse_joints(struct phys_ctx *ctx, f32 dt)
{ {
__prof; __prof;
struct entity_store *store = ctx->store; struct entity_store *store = ctx->store;
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) { for (u64 entity_index = 0; entity_index < store->num_reserved; ++entity_index) {
struct entity *joint_ent = &store->entities[entity_index]; struct entity *joint_ent = &store->entities[entity_index];
if (!entity_is_valid_and_active(joint_ent)) continue; if (!entity_is_valid_and_active(joint_ent)) continue;
if (!entity_has_prop(joint_ent, ENTITY_PROP_MOUSE_JOINT)) continue; if (!entity_has_prop(joint_ent, ENTITY_PROP_MOUSE_JOINT)) continue;
@ -999,7 +999,7 @@ void phys_integrate_forces(struct phys_ctx *ctx, f32 dt)
{ {
__prof; __prof;
struct entity_store *store = ctx->store; struct entity_store *store = ctx->store;
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) { for (u64 entity_index = 0; entity_index < store->num_reserved; ++entity_index) {
struct entity *ent = &store->entities[entity_index]; struct entity *ent = &store->entities[entity_index];
if (!entity_is_valid_and_active(ent)) continue; if (!entity_is_valid_and_active(ent)) continue;
@ -1041,7 +1041,7 @@ void phys_integrate_velocities(struct phys_ctx *ctx, f32 dt)
{ {
__prof; __prof;
struct entity_store *store = ctx->store; struct entity_store *store = ctx->store;
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) { for (u64 entity_index = 0; entity_index < store->num_reserved; ++entity_index) {
struct entity *ent = &store->entities[entity_index]; struct entity *ent = &store->entities[entity_index];
if (!entity_is_valid_and_active(ent)) continue; if (!entity_is_valid_and_active(ent)) continue;
if (!entity_has_prop(ent, ENTITY_PROP_PHYSICAL_DYNAMIC) && !entity_has_prop(ent, ENTITY_PROP_PHYSICAL_KINEMATIC)) continue; if (!entity_has_prop(ent, ENTITY_PROP_PHYSICAL_DYNAMIC) && !entity_has_prop(ent, ENTITY_PROP_PHYSICAL_KINEMATIC)) continue;
@ -1067,7 +1067,7 @@ f32 phys_determine_earliest_toi_for_bullets(struct phys_ctx *ctx, f32 step_dt, f
struct space *space = ctx->space; struct space *space = ctx->space;
f32 smallest_t = 1; f32 smallest_t = 1;
for (u64 e0_index = 0; e0_index < store->reserved; ++e0_index) { for (u64 e0_index = 0; e0_index < store->num_reserved; ++e0_index) {
struct entity *e0 = &store->entities[e0_index]; struct entity *e0 = &store->entities[e0_index];
if (!entity_is_valid_and_active(e0)) continue; if (!entity_is_valid_and_active(e0)) continue;
if (!(entity_has_prop(e0, ENTITY_PROP_PHYSICAL_DYNAMIC) || entity_has_prop(e0, ENTITY_PROP_PHYSICAL_KINEMATIC))) continue; if (!(entity_has_prop(e0, ENTITY_PROP_PHYSICAL_DYNAMIC) || entity_has_prop(e0, ENTITY_PROP_PHYSICAL_KINEMATIC))) continue;
@ -1114,7 +1114,7 @@ f32 phys_determine_earliest_toi_for_bullets(struct phys_ctx *ctx, f32 step_dt, f
void phys_update_aabbs(struct phys_ctx *ctx) void phys_update_aabbs(struct phys_ctx *ctx)
{ {
struct entity_store *store = ctx->store; struct entity_store *store = ctx->store;
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) { for (u64 entity_index = 0; entity_index < store->num_reserved; ++entity_index) {
struct entity *ent = &store->entities[entity_index]; struct entity *ent = &store->entities[entity_index];
if (!entity_is_valid_and_active(ent)) continue; if (!entity_is_valid_and_active(ent)) continue;
if (ent->local_collider.count <= 0) continue; if (ent->local_collider.count <= 0) continue;

View File

@ -70,7 +70,9 @@ struct phys_contact_point {
f32 inv_tangent_mass; f32 inv_tangent_mass;
/* Debugging */ /* Debugging */
#if DEVELOPER
struct v2 dbg_pt; struct v2 dbg_pt;
#endif
}; };
struct phys_contact_constraint { struct phys_contact_constraint {

View File

@ -31,7 +31,6 @@ struct sock_address {
struct sock_read_result { struct sock_read_result {
b32 valid; b32 valid;
struct sock *sock; /* In case of read from multiple sockets */
struct sock_address address; struct sock_address address;
struct string data; struct string data;
}; };
@ -47,11 +46,11 @@ INLINE b32 sock_address_eq(struct sock_address a, struct sock_address b)
return MEMEQ_STRUCT(&a, &b); return MEMEQ_STRUCT(&a, &b);
} }
struct sock *sock_alloc(u16 listen_port); struct sock *sock_alloc(u16 listen_port, u64 sndbuf_size, u64 rcvbuf_size);
void sock_release(struct sock *sock); void sock_release(struct sock *sock);
struct sock *sock_wait_for_available_read(struct sock_array socks, struct sock_signal *signal, f32 timeout);
struct sock_read_result sock_read(struct sock *sock, struct string read_buff); struct sock_read_result sock_read(struct sock *sock, struct string read_buff);
struct sock_read_result sock_read_poll(struct sock_array socks, struct sock_signal *signal, struct string read_buff, f32 timeout);
void sock_write(struct sock *sock, struct sock_address address, struct string data); void sock_write(struct sock *sock, struct sock_address address, struct string data);
#endif #endif

View File

@ -16,6 +16,8 @@
//#define MAX_IP_STR_LEN 46 //#define MAX_IP_STR_LEN 46
#define MAX_POLL_FDS 64
struct winsock_address { struct winsock_address {
i32 size; i32 size;
i32 family; i32 family;
@ -241,13 +243,20 @@ INTERNAL struct sock_address sock_address_from_winsock_address(struct winsock_ad
* Alloc * Alloc
* ========================== */ * ========================== */
struct sock *sock_alloc(u16 listen_port) struct sock *sock_alloc(u16 listen_port, u64 sndbuf_size, u64 rcvbuf_size)
{ {
struct sock_address addr = sock_address_from_port(listen_port); struct sock_address addr = sock_address_from_port(listen_port);
struct winsock_address ws_addr = winsock_address_from_sock_address(addr); struct winsock_address ws_addr = winsock_address_from_sock_address(addr);
SOCKET ws = socket(ws_addr.family, SOCK_DGRAM, IPPROTO_UDP); SOCKET ws = socket(ws_addr.family, SOCK_DGRAM, IPPROTO_UDP);
{
i32 sb = sndbuf_size;
i32 rb = rcvbuf_size;
setsockopt(ws, SOL_SOCKET, SO_SNDBUF, (char *)&sb, sizeof(sb));
setsockopt(ws, SOL_SOCKET, SO_RCVBUF, (char *)&rb, sizeof(rb));
}
#if 0 #if 0
if (listen_port != 0) { if (listen_port != 0) {
bind(ws, &ws_addr.sa, ws_addr.size); bind(ws, &ws_addr.sa, ws_addr.size);
@ -269,11 +278,60 @@ void sock_release(struct sock *sock)
* Read * Read
* ========================== */ * ========================== */
struct sock *sock_wait_for_available_read(struct sock_array socks, struct sock_signal *signal, f32 timeout)
{
struct temp_arena scratch = scratch_begin_no_conflict();
struct sock *res = NULL;
u64 num_fds = socks.count + (signal != NULL);
WSAPOLLFD fds[MAX_POLL_FDS] = ZI;
{
u32 fd_i = 0;
if (signal != NULL) {
fds[fd_i].fd = (SOCKET)signal;
fds[fd_i].events = POLLRDNORM;
++fd_i;
}
for (u32 i = 0; i < socks.count; ++i) {
if (fd_i >= ARRAY_COUNT(fds)) {
ASSERT(false);
break;
}
fds[fd_i].fd = (SOCKET)socks.socks[i];
fds[fd_i].events = POLLRDNORM;
++fd_i;
}
}
i32 timeout_ms;
if (timeout == F32_INFINITY) {
timeout_ms = -1;
} else {
timeout_ms = (i32)(timeout * 1000);
}
WSAPoll(fds, num_fds, timeout_ms);
for (u64 i = 0; i < num_fds; ++i) {
if (fds[i].revents & POLLRDNORM) {
if (i < socks.count) {
res = socks.socks[i];
break;
} else {
/* FIXME: Return signal */
ASSERT(false);
break;
}
}
}
scratch_end(scratch);
return res;
}
struct sock_read_result sock_read(struct sock *sock, struct string read_buff) struct sock_read_result sock_read(struct sock *sock, struct string read_buff)
{ {
SOCKET ws = (SOCKET)sock; SOCKET ws = (SOCKET)sock;
struct sock_read_result res = ZI; struct sock_read_result res = ZI;
res.sock = sock;
struct winsock_address ws_addr = ZI; struct winsock_address ws_addr = ZI;
ws_addr.size = sizeof(ws_addr.sas); ws_addr.size = sizeof(ws_addr.sas);
@ -298,66 +356,6 @@ struct sock_read_result sock_read(struct sock *sock, struct string read_buff)
return res; return res;
} }
struct sock_read_result sock_read_poll(struct sock_array socks, struct sock_signal *signal, struct string read_buff, f32 timeout)
{
struct temp_arena scratch = scratch_begin_no_conflict();
struct sock_read_result res = ZI;
u64 num_fds = socks.count + (signal != NULL);
WSAPOLLFD *fds = arena_push_array(scratch.arena, WSAPOLLFD, num_fds);
for (u64 i = 0; i < num_fds; ++i) {
if (i + 1 == num_fds && signal != NULL) {
fds[i].fd = (SOCKET)signal;
} else {
SOCKET ws = (SOCKET)socks.socks[i];
fds[i].fd = ws;
}
fds[i].events = POLLRDNORM;
}
i32 timeout_ms;
if (timeout == F32_INFINITY) {
timeout_ms = -1;
} else {
timeout_ms = (i32)(timeout * 1000);
}
WSAPoll(fds, num_fds, timeout_ms);
for (u64 i = 0; i < num_fds; ++i) {
if (fds[i].revents & POLLRDNORM) {
if (i < socks.count) {
SOCKET ws = fds[i].fd;
res.sock = socks.socks[i];
struct winsock_address ws_addr = ZI;
ws_addr.size = sizeof(ws_addr.sas);
i32 size = recvfrom(ws, (char *)read_buff.text, read_buff.len, 0, &ws_addr.sa, &ws_addr.size);
ws_addr.family = ws_addr.sin.sin_family;
res.address = sock_address_from_winsock_address(ws_addr);
if (size > 0) {
res.data.text = read_buff.text;
res.data.len = size;
res.valid = true;
break;
} else {
#if RTC
i32 err = WSAGetLastError();
if (err != WSAEWOULDBLOCK && err != WSAETIMEDOUT) {
ASSERT(false);
}
#endif
break;
}
}
}
}
scratch_end(scratch);
return res;
}
/* ========================== * /* ========================== *
* Write * Write
* ========================== */ * ========================== */

View File

@ -547,7 +547,7 @@ INTERNAL void user_update(void)
G.world.dt_ns = math_lerp_i64(t0->dt_ns, t1->dt_ns, (f64)tick_blend); G.world.dt_ns = math_lerp_i64(t0->dt_ns, t1->dt_ns, (f64)tick_blend);
/* Blend entities */ /* Blend entities */
u64 num_entities = min_u64(t0->entity_store->reserved, t1->entity_store->reserved); u64 num_entities = min_u64(t0->entity_store->num_reserved, t1->entity_store->num_reserved);
{ {
__profscope(tick_blending); __profscope(tick_blending);
for (u64 i = 0; i < num_entities; ++i) { for (u64 i = 0; i < num_entities; ++i) {
@ -796,7 +796,7 @@ INTERNAL void user_update(void)
* Apply shake * Apply shake
* ========================== */ * ========================== */
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) { for (u64 entity_index = 0; entity_index < store->num_reserved; ++entity_index) {
struct entity *ent = &store->entities[entity_index]; struct entity *ent = &store->entities[entity_index];
if (!entity_is_valid_and_active(ent)) continue; if (!entity_is_valid_and_active(ent)) continue;
@ -964,7 +964,7 @@ INTERNAL void user_update(void)
/* Copy valid entities */ /* Copy valid entities */
{ {
__profscope(copy_sprites_for_sorting); __profscope(copy_sprites_for_sorting);
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) { for (u64 entity_index = 0; entity_index < store->num_reserved; ++entity_index) {
struct entity *ent = &store->entities[entity_index]; struct entity *ent = &store->entities[entity_index];
if (entity_is_valid_and_active(ent)) { if (entity_is_valid_and_active(ent)) {
*arena_push(scratch.arena, struct entity *) = ent; *arena_push(scratch.arena, struct entity *) = ent;
@ -1605,7 +1605,7 @@ INTERNAL void user_update(void)
draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("world time: %F"), FMT_FLOAT(SECONDS_FROM_NS(G.world.time_ns)))); draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("world time: %F"), FMT_FLOAT(SECONDS_FROM_NS(G.world.time_ns))));
pos.y += spacing; pos.y += spacing;
draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("entities: %F/%F"), FMT_UINT(G.world.entity_store->allocated), FMT_UINT(G.world.entity_store->reserved))); draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("entities: %F/%F"), FMT_UINT(G.world.entity_store->num_allocated), FMT_UINT(G.world.entity_store->num_reserved)));
pos.y += spacing; pos.y += spacing;
draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("screen_size: (%F, %F)"), FMT_FLOAT((f64)G.screen_size.x), FMT_FLOAT((f64)G.screen_size.y))); draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("screen_size: (%F, %F)"), FMT_FLOAT((f64)G.screen_size.x), FMT_FLOAT((f64)G.screen_size.y)));