sim ctx decoupling progress

This commit is contained in:
jacob 2025-02-19 10:00:44 -06:00
parent b049a56a28
commit 80ed6a7852
6 changed files with 22 additions and 282 deletions

View File

@ -965,7 +965,7 @@ void OnBuild(StringList cli_args)
BuildStepSimpleCommandArg *bs_arg = ArenaPush(&perm, BuildStepSimpleCommandArg);
bs_arg->cmd = StringF(&perm, link_args_fmt, FmtStr(link_files_str), FmtStr(executable_file.full_path));
bs_arg->skip_flag = &src_success_flag;
String step_name = Lit("Linking");
String step_name = Lit("Linked");
AddStep(step_name, &BuildStepSimpleCommand, bs_arg);
}
}

View File

@ -17,70 +17,6 @@
#include "bitbuff.h"
#include "host.h"
/* ========================== *
* Ctx
* ========================== */
#if 0
struct sim_ctx *sim_ctx_alloc(struct sprite_startup_receipt *sprite_sr,
struct phys_startup_receipt *phys_sr,
struct host_startup_receipt *host_sr,
struct sim_snapshot_startup_receipt *sim_snapshot_sr,
u16 host_port)
{
struct arena arena = arena_alloc(GIGABYTE(64));
struct sim_ctx *ctx = arena_push_zero(&arena, struct sim_ctx);
ctx->arena = arena;
(UNUSED)sprite_sr;
(UNUSED)phys_sr;
(UNUSED)host_sr;
(UNUSED)sim_snapshot_sr;
/* Intialize host */
host = host_alloc(host_port);
/* Allocate encoder bitbuff */
encoder_bitbuff = bitbuff_alloc(GIGABYTE(64));
/* Create bookkeeping */
ctx->contact_lookup = sim_ent_lookup_alloc(4096);
#if COLLIDER_DEBUG
ctx->collision_debug_lookup = sim_ent_lookup_alloc(4096);
#endif
ctx->space = space_alloc(SPACE_CELL_SIZE, SPACE_CELL_BUCKETS_SQRT);
/* Create snapshot store */
snapshot_store = sim_snapshot_store_alloc();
ss_blended = sim_snapshot_nil();
return ctx;
}
void sim_ctx_release(struct sim_ctx *ctx)
{
__prof;
/* Release snapshot store */
sim_snapshot_store_release(snapshot_store);
/* Release bookkeeping */
space_release(ctx->space);
#if COLLIDER_DEBUG
sim_ent_lookup_release(&ctx->collision_debug_lookup);
#endif
sim_ent_lookup_release(&ctx->contact_lookup);
/* Release encoder bitbuff */
bitbuff_release(&encoder_bitbuff);
/* Release host */
host_release(host);
arena_release(&ctx->arena);
}
#endif
/* ========================== *
* Test
* ========================== */

View File

@ -120,55 +120,6 @@ struct sim_cmd_frame_list {
#define SIM_LAYER_RELATIVE_DEFAULT 0
#define SIM_LAYER_RELATIVE_WEAPON 1
/* ========================== *
* Ctx
* ========================== */
#if 0
struct sim_ctx {
struct arena arena;
/* Dynamic bitbuff used by encoders */
struct bitbuff encoder_bitbuff;
/* When did the last tick simulate in program time */
i64 last_tick_ns;
struct sprite_scope *sprite_frame_scope;
struct host *host;
/* TODO: Store in snapshot for determinism */
u64 last_phys_iteration;
/* This is the oldest tick stored in ctx that we need to hold a reference to for delta encoding */
u64 oldest_client_ack_tick;
/* Bookkeeping structures */
/* TODO: Store in snapshot for determinism */
struct sim_ent_lookup contact_lookup;
#if COLLIDER_DEBUG
struct sim_ent_lookup collision_debug_lookup;
#endif
struct space *space;
/* Snapshot */
struct sim_snapshot_store *snapshot_store;
struct sim_snapshot *ss_blended;
};
/* TODO: Get rid of startup receipts */
struct sim_ctx *sim_ctx_alloc(struct sprite_startup_receipt *sprite_sr,
struct phys_startup_receipt *phys_sr,
struct host_startup_receipt *host_sr,
struct sim_snapshot_startup_receipt *sim_snapshot_sr,
u16 host_port);
void sim_ctx_release(struct sim_ctx *ctx);
#endif
struct host;
struct bitbuff;
struct sim_snapshot;
struct sim_snapshot_store;
struct sim_snapshot *sim_step(struct sim_snapshot_store *snapshot_store, struct sim_snapshot *prev_snapshot, struct sim_cmd_frame_list input_frames, i64 real_dt_ns);

View File

@ -199,7 +199,6 @@ struct sim_snapshot *sim_snapshot_alloc(struct sim_snapshot_store *store, struct
ss->world_timescale = src->world_timescale;
ss->world_dt_ns = src->world_dt_ns;
ss->world_time_ns = src->world_time_ns;
ss->received_at_ns = src->received_at_ns;
ss->continuity_gen = src->continuity_gen;
ss->local_client = src->local_client;

View File

@ -51,9 +51,6 @@ struct sim_snapshot {
i64 world_dt_ns;
i64 world_time_ns;
/* When was this snapshot received */
i64 received_at_ns;
/* If != previous tick's continuity then don't lerp */
u64 continuity_gen;

View File

@ -46,7 +46,6 @@ GLOBAL struct {
struct arena arena;
struct sys_window *window;
struct host *host;
struct string connect_address_str;
struct sim_snapshot_store *unblended_snapshot_store; /* Contains buffered snapshots from sim */
@ -208,9 +207,6 @@ struct user_startup_receipt user_startup(struct work_startup_receipt *work_sr,
G.local_sim_ss_mutex = sys_mutex_alloc();
G.local_sim_ss_store = sim_snapshot_store_alloc();
//struct sock_address bind_addr = sock_address_from_any_local_interface_with_dynamic_port();
G.host = host_alloc(0);
G.encoder_bitbuff = bitbuff_alloc(GIGABYTE(64));
G.world_to_ui_xf = XFORM_IDENT;
@ -400,120 +396,8 @@ INTERNAL void user_update(void)
struct sprite_scope *sprite_frame_scope = sprite_scope_begin();
#if 0
/* ========================== *
* Process host events into sim cmds
* ========================== */
struct sim_cmd_frame incoming_cmd_frame = ZI;
{
host_update(G.host);
struct host_event_array host_events = host_pop_events(scratch.arena, G.host);
struct sim_cmd_frame_list l = ZI;
sim_cmd_frames_decode(scratch.arena, host_events, &l);
for (struct sim_cmd_frame *frame = l.first; frame; frame = frame->next) {
if (frame->tick == 0 || frame->tick > incoming_cmd_frame.tick) {
incoming_cmd_frame = *frame;
incoming_cmd_frame.next = NULL;
}
}
}
/* ========================== *
* Process sim cmd frame
* ========================== */
#if 0
{
static f64 last_try_connect = 0;
f64 now = SECONDS_FROM_NS(sys_time_ns());
if (last_try_connect == 0 || (now - last_try_connect) > 0.1) {
struct sock_address connect_addr = sock_address_from_string(G.connect_address_str);
host_queue_connect_to_address(G.host, connect_addr);
last_try_connect = now;
}
for (struct sim_cmd *cmd = incoming_cmd_frame.first; cmd; cmd = cmd->next) {
enum sim_cmd_kind kind = cmd->kind;
switch (kind) {
case SIM_CMD_KIND_CONNECT:
{
last_try_connect = F64_INFINITY;
} break;
case SIM_CMD_KIND_DISCONNECT:
{
last_try_connect = 0;
} break;
case SIM_CMD_KIND_SNAPSHOT:
{
/* TODO: Only read newest tick cmd */
if (cmd->snapshot_tick_end > G.ss_blended->tick) {
u64 ss0_tick = cmd->snapshot_tick_start;
u64 ss1_tick = cmd->snapshot_tick_end;
struct sim_snapshot *ss0 = sim_snapshot_from_tick(G.sim_snapshot_store, ss0_tick);
struct sim_snapshot *ss1 = sim_snapshot_from_tick(G.sim_snapshot_store, ss1_tick);
if (ss0->tick == ss0_tick) {
if (!ss1->valid) {
ss1 = sim_snapshot_alloc(G.sim_snapshot_store, ss0, ss1_tick);
ss1->received_at_ns = G.real_time_ns;
struct bitbuff bb = bitbuff_from_string(cmd->snapshot_encoded);
struct bitbuff_reader br = br_from_bitbuff(&bb);
sim_snapshot_decode(&br, ss1);
}
} else {
/* User should always have src tick present */
ASSERT(false);
}
}
} break;
default: break;
}
}
}
#else
{
for (struct sim_cmd *cmd = incoming_cmd_frame.first; cmd; cmd = cmd->next) {
enum sim_cmd_kind kind = cmd->kind;
switch (kind) {
case SIM_CMD_KIND_SNAPSHOT:
{
/* TODO: Only read newest tick cmd */
if (cmd->snapshot_tick_end > G.ss_blended->tick) {
u64 ss0_tick = cmd->snapshot_tick_start;
u64 ss1_tick = cmd->snapshot_tick_end;
struct sim_snapshot *ss0 = sim_snapshot_from_tick(G.sim_snapshot_store, ss0_tick);
struct sim_snapshot *ss1 = sim_snapshot_from_tick(G.sim_snapshot_store, ss1_tick);
if (ss0->tick == ss0_tick) {
if (!ss1->valid) {
ss1 = sim_snapshot_alloc(G.sim_snapshot_store, ss0, ss1_tick);
ss1->received_at_ns = G.real_time_ns;
struct bitbuff bb = bitbuff_from_string(cmd->snapshot_encoded);
struct bitbuff_reader br = br_from_bitbuff(&bb);
sim_snapshot_decode(&br, ss1);
}
} else {
/* User should always have src tick present */
ASSERT(false);
}
}
} break;
default: break;
}
}
}
#endif
#endif
/* ========================== *
* Pull latest snapshot
* Pull latest local sim snapshot
* ========================== */
{
@ -536,11 +420,7 @@ INTERNAL void user_update(void)
struct sim_snapshot *newest_snapshot = sim_snapshot_from_tick(G.unblended_snapshot_store, G.unblended_snapshot_store->last_tick);
G.local_sim_last_known_time_ns = newest_snapshot->real_time_ns;
G.local_sim_last_known_tick = newest_snapshot->tick;
/* This is the the tick that we know the sim has received our ack of.
* Therefore we must keep it around or else risk the server sending us
* a snapshot delta for a snapshot we've released. */
u64 oldest_possible_delta_base_tick = sim_client_from_handle(newest_snapshot, newest_snapshot->local_client)->ack;
u64 keep_unblended_tick = newest_snapshot->tick;
/* Predict local sim time based on last received snapshot time,
* then smooth it out to prevent sudden jumps in rendering due
@ -565,10 +445,6 @@ INTERNAL void user_update(void)
u64 next_tick = ss->next_tick;
i64 ss_time_ns = ss->real_time_ns;
if (ss_time_ns < render_time_ns && ss_time_ns > left_snapshot->real_time_ns) {
if (left_snapshot->valid && left_snapshot->tick < oldest_possible_delta_base_tick) {
/* Snapshot no longer needed since render time has passed & it's older than any delta's we may receive, release it. */
sim_snapshot_release(left_snapshot);
}
left_snapshot = ss;
}
if (ss_time_ns > render_time_ns && ss_time_ns < right_snapshot->real_time_ns) {
@ -578,6 +454,10 @@ INTERNAL void user_update(void)
}
}
if (left_snapshot->tick < keep_unblended_tick) {
keep_unblended_tick = left_snapshot->tick;
}
/* Create world from blended snapshots */
if (left_snapshot->valid && right_snapshot->valid) {
f64 blend = (f64)(render_time_ns - left_snapshot->real_time_ns) / (f64)(right_snapshot->real_time_ns - left_snapshot->real_time_ns);
@ -587,8 +467,21 @@ INTERNAL void user_update(void)
} else if (right_snapshot->valid) {
G.ss_blended = sim_snapshot_alloc(G.blended_snapshot_store, right_snapshot, right_snapshot->tick);
}
#else
if (G.ss_blended->tick != newest_snapshot->tick) {
if (G.ss_blended->valid) {
sim_snapshot_release(G.ss_blended);
}
G.ss_blended = sim_snapshot_alloc(G.blended_snapshot_store, newest_snapshot, newest_snapshot->tick);
}
#endif
/* Release all other blended snapshots */
/* Release unneeded unblended sim snapshots */
if (keep_unblended_tick > 0) {
sim_snapshot_store_release_ticks_in_range(G.unblended_snapshot_store, 0, keep_unblended_tick - 1);
}
/* Release unused blended snapshots */
{
struct sim_snapshot *ss = sim_snapshot_from_tick(G.blended_snapshot_store, G.blended_snapshot_store->first_tick);
while (ss->valid) {
@ -599,28 +492,6 @@ INTERNAL void user_update(void)
ss = sim_snapshot_from_tick(G.blended_snapshot_store, next_tick);
}
}
#else
/* Release sim snapshots all except for newest tick */
{
struct sim_snapshot *ss = sim_snapshot_from_tick(G.sim_snapshot_store, G.sim_snapshot_store->first_tick);
while (ss->valid) {
u64 next_tick = ss->next_tick;
if (ss->tick != newest_snapshot->tick && ss->tick < oldest_possible_delta_base_tick) {
sim_snapshot_release(ss);
}
ss = sim_snapshot_from_tick(G.sim_snapshot_store, next_tick);
}
}
if (G.ss_blended->tick != newest_snapshot->tick) {
if (G.ss_blended->valid) {
sim_snapshot_release(G.ss_blended);
}
G.ss_blended = sim_snapshot_alloc(G.blended_snapshot_store, newest_snapshot, newest_snapshot->tick);
}
#endif
}
/* ========================== *
@ -1641,21 +1512,6 @@ INTERNAL void user_update(void)
}
#if 0
/* Publish sim cmds */
{
struct sim_cmd_frame_list l = ZI;
l.first = &cmd_frame;
l.last = &cmd_frame;
struct bitbuff_writer bw = bw_from_bitbuff(&G.encoder_bitbuff);
sim_cmd_frames_encode(&bw, l, G.local_sim_last_known_tick);
struct string cmds_str = bw_get_written(scratch.arena, &bw);
host_queue_write(G.host, HOST_CHANNEL_ID_ALL, cmds_str, 0);
}
host_update(G.host);
#endif
/* Update network usage stats */
G.client_bytes_read.last_second_end = G.host->bytes_received;
G.client_bytes_sent.last_second_end = G.host->bytes_sent;
@ -1666,6 +1522,7 @@ INTERNAL void user_update(void)
G.client_bytes_read.last_second_start = G.client_bytes_read.last_second_end;
G.client_bytes_sent.last_second_start = G.client_bytes_sent.last_second_end;
}
#endif
/* ========================== *
* Render