more timing debug info

This commit is contained in:
jacob 2025-02-11 08:22:34 -06:00
parent dcbabbdfd1
commit 46c7414f71
8 changed files with 184 additions and 160 deletions

View File

@ -59,7 +59,7 @@
#define COLLIDER_DEBUG 0 #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 0
/* ========================== * /* ========================== *
* Settings * Settings

View File

@ -236,7 +236,7 @@ struct phys_collision_data_array phys_create_and_update_contacts(struct arena *a
struct sim_ent *dbg_ent = sim_ent_nil(); struct sim_ent *dbg_ent = sim_ent_nil();
struct sim_ent_lookup_entry *dbg_entry = sim_ent_lookup_get(debug_lookup, key); struct sim_ent_lookup_entry *dbg_entry = sim_ent_lookup_get(debug_lookup, key);
if (dbg_entry) { if (dbg_entry) {
dbg_ent = sim_ent_from_handle(store, dbg_entry->sim_ent); dbg_ent = sim_ent_from_handle(store, dbg_entry->entity);
} }
if (!dbg_ent->valid) { if (!dbg_ent->valid) {
@ -1098,12 +1098,11 @@ u64 phys_step(struct phys_ctx *ctx, f32 timestep, u64 last_phys_iteration)
const u32 max_iterations = 16; const u32 max_iterations = 16;
f32 earliest_toi = max_f32(phys_determine_earliest_toi_for_bullets(ctx, step_dt, tolerance, max_iterations), min_toi); f32 earliest_toi = max_f32(phys_determine_earliest_toi_for_bullets(ctx, step_dt, tolerance, max_iterations), min_toi);
step_dt = remaining_dt * earliest_toi; step_dt = remaining_dt * earliest_toi;
remaining_dt -= step_dt;
#else #else
(UNUSED)toi; (UNUSED)phys_determine_earliest_toi_for_bullets;
(UNUSED)determine_earliest_toi_for_bullets;
#endif #endif
} }
remaining_dt -= step_dt;
struct phys_collision_data_array collision_data = phys_create_and_update_contacts(scratch.arena, ctx, timestep - remaining_dt, phys_iteration); struct phys_collision_data_array collision_data = phys_create_and_update_contacts(scratch.arena, ctx, timestep - remaining_dt, phys_iteration);

View File

@ -1,7 +1,7 @@
#include "sim.h" #include "sim.h"
#include "sim_ent.h" #include "sim_ent.h"
#include "sim_client.h" #include "sim_client.h"
#include "sim_msg.h" #include "sim_encode.h"
#include "sim_snapshot.h" #include "sim_snapshot.h"
#include "sys.h" #include "sys.h"
#include "util.h" #include "util.h"
@ -429,7 +429,7 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns)
ctx->world->real_dt_ns = max_i64(0, target_dt_ns); ctx->world->real_dt_ns = max_i64(0, target_dt_ns);
ctx->world->real_time_ns += ctx->world->real_dt_ns; ctx->world->real_time_ns += ctx->world->real_dt_ns;
ctx->world->world_timescale = 1; ctx->world->world_timescale = SIM_TIMESCALE;
ctx->world->world_dt_ns = max_i64(0, target_dt_ns * ctx->world->world_timescale); ctx->world->world_dt_ns = max_i64(0, target_dt_ns * ctx->world->world_timescale);
ctx->world->world_time_ns += ctx->world->world_dt_ns; ctx->world->world_time_ns += ctx->world->world_dt_ns;
@ -1154,7 +1154,7 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns)
phys.pre_solve_callback = on_collision; phys.pre_solve_callback = on_collision;
phys.pre_solve_callback_udata = ctx; phys.pre_solve_callback_udata = ctx;
#if COLLIDER_DEBUG #if COLLIDER_DEBUG
phys.debug_lookup = &phys->collision_debug_lookup; phys.debug_lookup = &ctx->collision_debug_lookup;
#endif #endif
/* Step */ /* Step */
@ -1359,7 +1359,7 @@ void sim_update(struct sim_ctx *ctx, i64 target_dt_ns)
struct sim_event snapshot_event = ZI; struct sim_event snapshot_event = ZI;
snapshot_event.tick = ctx->world->tick; snapshot_event.tick = ctx->world->tick;
snapshot_event.kind = SIM_EVENT_KIND_SNAPSHOT; snapshot_event.kind = SIM_EVENT_KIND_SNAPSHOT;
snapshot_event.snapshot_data = sim_snapshot_encode(temp.arena, client, ctx->world); snapshot_event.snapshot_data = sim_encode_snapshot(temp.arena, client, ctx->world);
struct sim_event_list l = ZI; struct sim_event_list l = ZI;
l.first = &snapshot_event; l.first = &snapshot_event;

107
src/sim.h
View File

@ -11,6 +11,101 @@ struct sim_ent_startup_receipt;
struct sim_client_startup_receipt; struct sim_client_startup_receipt;
struct sim_snapshot_startup_receipt; struct sim_snapshot_startup_receipt;
/* ========================== *
* Cmd
* ========================== */
enum sim_cmd_state {
SIM_CMD_STATE_STOP = -1,
SIM_CMD_STATE_NO_CHANGE = 0,
SIM_CMD_STATE_START = 1
};
enum sim_cmd_kind {
SIM_CMD_KIND_NONE,
SIM_CMD_KIND_PLAYER_CONTROL,
SIM_CMD_KIND_PLAYER_FIRE,
SIM_CMD_KIND_SIM_CLIENT_CONNECT,
SIM_CMD_KIND_SIM_CLIENT_DISCONNECT,
/* Testing */
SIM_CMD_KIND_CLEAR_ALL,
SIM_CMD_KIND_SPAWN_TEST,
SIM_CMD_KIND_PAUSE,
SIM_CMD_KIND_STEP,
SIM_CMD_KIND_DRAG_OBJECT,
SIM_CMD_KIND_CURSOR_MOVE,
SIM_CMD_KIND_COUNT
};
struct sim_cmd {
enum sim_cmd_kind kind;
enum sim_cmd_state state;
struct host_channel_id channel_id;
/* SIM_CMD_KIND_PLAYER_CONTROL */
struct v2 move_dir;
struct v2 aim_dir;
/* SIM_CMD_KIND_CURSOR_MOVE */
struct v2 cursor_pos;
/* SIM_CMD_KIND_PLAYER_DISCONNECT */
struct string disconnect_reason;
#if RTC
u32 collider_gjk_steps;
#endif
struct sim_cmd *next;
};
struct sim_cmd_list {
struct sim_cmd *first;
struct sim_cmd *last;
};
/* ========================== *
* Event
* ========================== */
enum sim_event_kind {
SIM_EVENT_KIND_NONE,
SIM_EVENT_KIND_CONNECT,
SIM_EVENT_KIND_DISCONNECT,
SIM_EVENT_KIND_SNAPSHOT,
//SIM_EVENT_KIND_ENTITY_UPDATE,
//SIM_EVENT_KIND_ENTITY_CREATE,
//SIM_EVENT_KIND_ENTITY_DESTROY
};
struct sim_event {
u64 tick;
enum sim_event_kind kind;
struct host_channel_id channel_id;
struct string disconnect_reason;
/* SIM_EVENT_KIND_SNAPSHOT */
struct string snapshot_data;
struct sim_event *next;
};
struct sim_event_list {
struct sim_event *first;
struct sim_event *last;
};
/* ========================== *
* Layers
* ========================== */
/* Absolute layers */ /* Absolute layers */
#define SIM_LAYER_FLOOR_DECALS -300 #define SIM_LAYER_FLOOR_DECALS -300
#define SIM_LAYER_BULLETS -200 #define SIM_LAYER_BULLETS -200
@ -21,17 +116,25 @@ struct sim_snapshot_startup_receipt;
#define SIM_LAYER_RELATIVE_DEFAULT 0 #define SIM_LAYER_RELATIVE_DEFAULT 0
#define SIM_LAYER_RELATIVE_WEAPON 1 #define SIM_LAYER_RELATIVE_WEAPON 1
/* ========================== *
* Ctx
* ========================== */
struct sim_ctx { struct sim_ctx {
struct arena arena; struct arena arena;
i64 last_tick_ns; i64 last_tick_ns; /* When did the last tick simulate in program time */
u64 last_phys_iteration;
struct sprite_scope *sprite_frame_scope; struct sprite_scope *sprite_frame_scope;
struct host *host; struct host *host;
/* TODO: Store in snapshot for determinism */
u64 last_phys_iteration;
/* Bookkeeping structures */ /* Bookkeeping structures */
/* TODO: Store in snapshot for determinism */
struct sim_ent_lookup contact_lookup; struct sim_ent_lookup contact_lookup;
#if COLLIDER_DEBUG #if COLLIDER_DEBUG
struct sim_ent_lookup collision_debug_lookup; struct sim_ent_lookup collision_debug_lookup;

View File

@ -1,4 +1,4 @@
#include "sim_msg.h" #include "sim_encode.h"
#include "sim_snapshot.h" #include "sim_snapshot.h"
#include "arena.h" #include "arena.h"
#include "byteio.h" #include "byteio.h"
@ -212,7 +212,7 @@ void sim_events_from_host_events(struct arena *arena, struct host_event_array ho
* Snapshot * Snapshot
* ========================== */ * ========================== */
struct string sim_snapshot_encode(struct arena *arena, struct sim_client *client, struct sim_snapshot *snapshot) struct string sim_encode_snapshot(struct arena *arena, struct sim_client *client, struct sim_snapshot *snapshot)
{ {
__prof; __prof;
struct byte_writer bw = bw_from_arena(arena); struct byte_writer bw = bw_from_arena(arena);
@ -250,7 +250,7 @@ struct string sim_snapshot_encode(struct arena *arena, struct sim_client *client
return bw_get_written(&bw); return bw_get_written(&bw);
} }
void sim_snapshot_decode(struct string str, struct sim_snapshot *snapshot) void sim_decode_snapshot(struct string str, struct sim_snapshot *snapshot)
{ {
__prof; __prof;
struct byte_reader br = br_from_buffer(str); struct byte_reader br = br_from_buffer(str);

23
src/sim_encode.h Normal file
View File

@ -0,0 +1,23 @@
#ifndef SIM_ENCODE_H
#define SIM_ENCODE_H
#include "host.h"
#include "sim.h"
struct sim_snapshot;
struct sim_client;
struct string sim_string_from_cmds(struct arena *arena, struct sim_cmd_list cmds);
void sim_cmds_from_host_events(struct arena *arena, struct host_event_array host_events, struct sim_cmd_list *cmds_out);
struct string sim_string_from_events(struct arena *arena, struct sim_event_list events);
void sim_events_from_host_events(struct arena *arena, struct host_event_array host_events, struct sim_event_list *events_out);
/* ========================== *
* Snapshot
* ========================== */
struct string sim_encode_snapshot(struct arena *arena, struct sim_client *client, struct sim_snapshot *snapshot);
void sim_decode_snapshot(struct string str, struct sim_snapshot *snapshot);
#endif

View File

@ -1,113 +0,0 @@
#ifndef SIM_MSG_H
#define SIM_MSG_H
#include "host.h"
struct sim_snapshot;
struct sim_client;
/* ========================== *
* Sim cmd
* ========================== */
enum sim_cmd_state {
SIM_CMD_STATE_STOP = -1,
SIM_CMD_STATE_NO_CHANGE = 0,
SIM_CMD_STATE_START = 1
};
enum sim_cmd_kind {
SIM_CMD_KIND_NONE,
SIM_CMD_KIND_PLAYER_CONTROL,
SIM_CMD_KIND_PLAYER_FIRE,
SIM_CMD_KIND_SIM_CLIENT_CONNECT,
SIM_CMD_KIND_SIM_CLIENT_DISCONNECT,
/* Testing */
SIM_CMD_KIND_CLEAR_ALL,
SIM_CMD_KIND_SPAWN_TEST,
SIM_CMD_KIND_PAUSE,
SIM_CMD_KIND_STEP,
SIM_CMD_KIND_DRAG_OBJECT,
SIM_CMD_KIND_CURSOR_MOVE,
SIM_CMD_KIND_COUNT
};
struct sim_cmd {
enum sim_cmd_kind kind;
enum sim_cmd_state state;
struct host_channel_id channel_id;
/* SIM_CMD_KIND_PLAYER_CONTROL */
struct v2 move_dir;
struct v2 aim_dir;
/* SIM_CMD_KIND_CURSOR_MOVE */
struct v2 cursor_pos;
/* SIM_CMD_KIND_PLAYER_DISCONNECT */
struct string disconnect_reason;
#if RTC
u32 collider_gjk_steps;
#endif
struct sim_cmd *next;
};
struct sim_cmd_list {
struct sim_cmd *first;
struct sim_cmd *last;
};
struct string sim_string_from_cmds(struct arena *arena, struct sim_cmd_list cmds);
void sim_cmds_from_host_events(struct arena *arena, struct host_event_array host_events, struct sim_cmd_list *cmds_out);
/* ========================== *
* Sim event
* ========================== */
enum sim_event_kind {
SIM_EVENT_KIND_NONE,
SIM_EVENT_KIND_CONNECT,
SIM_EVENT_KIND_DISCONNECT,
SIM_EVENT_KIND_SNAPSHOT,
//SIM_EVENT_KIND_ENTITY_UPDATE,
//SIM_EVENT_KIND_ENTITY_CREATE,
//SIM_EVENT_KIND_ENTITY_DESTROY
};
struct sim_event {
u64 tick;
enum sim_event_kind kind;
struct host_channel_id channel_id;
struct string disconnect_reason;
/* SIM_EVENT_KIND_SNAPSHOT */
struct string snapshot_data;
struct sim_event *next;
};
struct sim_event_list {
struct sim_event *first;
struct sim_event *last;
};
struct string sim_string_from_events(struct arena *arena, struct sim_event_list events);
void sim_events_from_host_events(struct arena *arena, struct host_event_array host_events, struct sim_event_list *events_out);
/* ========================== *
* Snapshot
* ========================== */
struct string sim_snapshot_encode(struct arena *arena, struct sim_client *client, struct sim_snapshot *snapshot);
void sim_snapshot_decode(struct string str, struct sim_snapshot *snapshot);
#endif

View File

@ -2,7 +2,7 @@
#include "app.h" #include "app.h"
#include "sim.h" #include "sim.h"
#include "sim_ent.h" #include "sim_ent.h"
#include "sim_msg.h" #include "sim_encode.h"
#include "sim_snapshot.h" #include "sim_snapshot.h"
#include "renderer.h" #include "renderer.h"
#include "font.h" #include "font.h"
@ -40,12 +40,12 @@ GLOBAL struct {
struct atomic_i32 user_thread_shutdown; struct atomic_i32 user_thread_shutdown;
struct sys_thread user_thread; struct sys_thread user_thread;
struct atomic_i32 sim_thread_shutdown; struct atomic_i32 local_sim_thread_shutdown;
struct sys_thread sim_thread; struct sys_thread local_sim_thread;
struct sim_ctx *local_sim_ctx;
struct arena arena; struct arena arena;
struct sys_window *window; struct sys_window *window;
struct sim_ctx *sim_ctx;
struct host *host; struct host *host;
struct string connect_address_str; struct string connect_address_str;
@ -86,9 +86,12 @@ GLOBAL struct {
i64 real_dt_ns; i64 real_dt_ns;
i64 real_time_ns; i64 real_time_ns;
u64 local_sim_last_known_tick;
i64 local_sim_last_known_time_ns;
/* Calculated from <last snapshot receive time + time since packet receive> */ /* Calculated from <last snapshot receive time + time since packet receive> */
i64 sim_time_ns; i64 local_sim_predicted_time_ns;
i64 sim_time_smoothed_ns; i64 local_sim_predicted_time_smoothed_ns;
/* Per-frame */ /* Per-frame */
struct v2 screen_size; struct v2 screen_size;
@ -144,7 +147,7 @@ GLOBAL READONLY enum user_bind_kind g_binds[SYS_BTN_COUNT] = {
INTERNAL APP_EXIT_CALLBACK_FUNC_DEF(user_shutdown); INTERNAL APP_EXIT_CALLBACK_FUNC_DEF(user_shutdown);
INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(user_thread_entry_point, arg); INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(user_thread_entry_point, arg);
INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(user_sim_thread_entry_point, arg); INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(user_local_sim_thread_entry_point, arg);
INTERNAL SYS_WINDOW_EVENT_CALLBACK_FUNC_DEF(window_event_callback, event); INTERNAL SYS_WINDOW_EVENT_CALLBACK_FUNC_DEF(window_event_callback, event);
struct user_startup_receipt user_startup(struct work_startup_receipt *work_sr, struct user_startup_receipt user_startup(struct work_startup_receipt *work_sr,
@ -201,9 +204,9 @@ struct user_startup_receipt user_startup(struct work_startup_receipt *work_sr,
sys_window_register_event_callback(G.window, &window_event_callback); sys_window_register_event_callback(G.window, &window_event_callback);
if (connect_address_str.len == 0) { if (connect_address_str.len == 0) {
G.sim_ctx = sim_ctx_alloc(sprite_sr, phys_sr, host_sr, sim_ent_sr, sim_client_sr, sim_snapshot_sr, 12345); G.local_sim_ctx = sim_ctx_alloc(sprite_sr, phys_sr, host_sr, sim_ent_sr, sim_client_sr, sim_snapshot_sr, 12345);
G.connect_address_str = LIT("127.0.0.1:12345"); G.connect_address_str = LIT("127.0.0.1:12345");
G.sim_thread = sys_thread_alloc(&user_sim_thread_entry_point, G.sim_ctx, LIT("[P2] Sim thread")); G.local_sim_thread = sys_thread_alloc(&user_local_sim_thread_entry_point, G.local_sim_ctx, LIT("[P2] Local sim thread"));
} else { } else {
G.connect_address_str = string_copy(&G.arena, connect_address_str); G.connect_address_str = string_copy(&G.arena, connect_address_str);
} }
@ -222,10 +225,10 @@ INTERNAL APP_EXIT_CALLBACK_FUNC_DEF(user_shutdown)
atomic_i32_eval_exchange(&G.user_thread_shutdown, true); atomic_i32_eval_exchange(&G.user_thread_shutdown, true);
sys_thread_wait_release(&G.user_thread); sys_thread_wait_release(&G.user_thread);
if (G.sim_ctx) { if (G.local_sim_ctx) {
atomic_i32_eval_exchange(&G.sim_thread_shutdown, true); atomic_i32_eval_exchange(&G.local_sim_thread_shutdown, true);
sys_thread_wait_release(&G.sim_thread); sys_thread_wait_release(&G.local_sim_thread);
sim_ctx_release(G.sim_ctx); sim_ctx_release(G.local_sim_ctx);
} }
} }
@ -448,12 +451,12 @@ INTERNAL void user_update(void)
struct string encoded = event->snapshot_data; struct string encoded = event->snapshot_data;
struct sim_snapshot *ss = sim_snapshot_alloc(G.sim_snapshot_store, delta_src, tick); struct sim_snapshot *ss = sim_snapshot_alloc(G.sim_snapshot_store, delta_src, tick);
sim_snapshot_decode(encoded, ss); sim_decode_snapshot(encoded, ss);
ss->received_at_ns = G.real_time_ns; ss->received_at_ns = G.real_time_ns;
} }
#else #else
struct string encoded = event->snapshot_data; struct string encoded = event->snapshot_data;
sim_snapshot_decode(encoded, &G.world, tick); sim_decode_snapshot(encoded, &G.world, tick);
#endif #endif
} break; } break;
@ -468,19 +471,21 @@ INTERNAL void user_update(void)
{ {
struct sim_snapshot *newest_snapshot = sim_snapshot_from_tick(G.sim_snapshot_store, G.sim_snapshot_store->last_tick); struct sim_snapshot *newest_snapshot = sim_snapshot_from_tick(G.sim_snapshot_store, G.sim_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;
/* Calculate sim time based on last received snapshot time, /* Predict local sim time based on last received snapshot time,
* then smooth it out to prevent sudden jumps in rendering due * then smooth it out to prevent sudden jumps in rendering due
* to variance in snapshot receive time. */ * to variance in snapshot receive time. */
/* TODO: Use a value that indicates desired dt to next frame, rather than real dt from last frame? */ /* TODO: Use a value that indicates desired dt to next frame, rather than real dt from last frame? */
f64 sim_time_smoothed_correction_rate = SECONDS_FROM_NS(G.real_dt_ns) / 0.05; f64 sim_time_smoothed_correction_rate = SECONDS_FROM_NS(G.real_dt_ns) / 0.05;
i64 time_since_newest_tick_ns = G.real_time_ns - newest_snapshot->received_at_ns; i64 time_since_newest_tick_ns = G.real_time_ns - newest_snapshot->received_at_ns;
G.sim_time_ns = newest_snapshot->real_time_ns + time_since_newest_tick_ns; G.local_sim_predicted_time_ns = newest_snapshot->real_time_ns + time_since_newest_tick_ns;
G.sim_time_smoothed_ns += G.real_dt_ns; G.local_sim_predicted_time_smoothed_ns += G.real_dt_ns;
G.sim_time_smoothed_ns += (G.sim_time_ns - G.sim_time_smoothed_ns) * sim_time_smoothed_correction_rate; G.local_sim_predicted_time_smoothed_ns += (G.local_sim_predicted_time_ns - G.local_sim_predicted_time_smoothed_ns) * sim_time_smoothed_correction_rate;
#if USER_INTERP_ENABLED #if USER_INTERP_ENABLED
i64 render_time_ns = G.sim_time_smoothed_ns - (USER_INTERP_RATIO * newest_snapshot->real_dt_ns); i64 render_time_ns = G.local_sim_predicted_time_smoothed_ns - (USER_INTERP_RATIO * newest_snapshot->real_dt_ns);
/* Get two snapshots nearest to render time */ /* Get two snapshots nearest to render time */
struct sim_snapshot *left_snapshot = sim_snapshot_nil(); struct sim_snapshot *left_snapshot = sim_snapshot_nil();
@ -1096,8 +1101,8 @@ INTERNAL void user_update(void)
if (sim_ent_has_prop(ent, SIM_ENT_PROP_COLLISION_DEBUG)) { if (sim_ent_has_prop(ent, SIM_ENT_PROP_COLLISION_DEBUG)) {
struct phys_collision_debug *data = &ent->collision_debug_data; struct phys_collision_debug *data = &ent->collision_debug_data;
struct collider_collision_points_result collider_res = data->res; struct collider_collision_points_result collider_res = data->res;
struct sim_ent *e0 = sim_ent_from_handle(store, data->e0); struct sim_ent *e0 = sim_ent_from_handle(G.world->ent_store, data->e0);
struct sim_ent *e1 = sim_ent_from_handle(store, data->e1); struct sim_ent *e1 = sim_ent_from_handle(G.world->ent_store, data->e1);
struct collider_shape e0_collider = e0->local_collider; struct collider_shape e0_collider = e0->local_collider;
struct collider_shape e1_collider = e1->local_collider; struct collider_shape e1_collider = e1->local_collider;
(UNUSED)e0_collider; (UNUSED)e0_collider;
@ -1490,35 +1495,42 @@ INTERNAL void user_update(void)
if (font) { if (font) {
struct temp_arena temp = arena_temp_begin(scratch.arena); struct temp_arena temp = arena_temp_begin(scratch.arena);
draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("sim tick: %F"), FMT_UINT(G.world->tick))); draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("Read from local sim: %F mbit/s"), FMT_FLOAT_P((f64)G.client_bytes_read.last_second * 8 / 1000 / 1000, 2)));
pos.y += spacing; pos.y += spacing;
draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("sim time: %F"), FMT_FLOAT(SECONDS_FROM_NS(G.sim_time_ns)))); draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("Sent to local sim: %F mbit/s"), FMT_FLOAT_P((f64)G.client_bytes_sent.last_second * 8 / 1000 / 1000, 2)));
pos.y += spacing;
pos.y += spacing; pos.y += spacing;
draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("sim time (smoothed): %F"), FMT_FLOAT(SECONDS_FROM_NS(G.sim_time_smoothed_ns)))); draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("user entities: %F/%F"), FMT_UINT(G.world->ent_store->num_allocated), FMT_UINT(G.world->ent_store->num_reserved)));
pos.y += spacing; pos.y += spacing;
draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("world time: %F"), FMT_FLOAT(SECONDS_FROM_NS(G.world->world_time_ns)))); draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("user tick: %F"), FMT_UINT(G.world->tick)));
pos.y += spacing; pos.y += spacing;
draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("user time: %F"), FMT_FLOAT_P(SECONDS_FROM_NS(G.world->real_time_ns), 3)));
pos.y += spacing; pos.y += spacing;
draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("sim entities: %F/%F"), FMT_UINT(G.world->ent_store->num_allocated), FMT_UINT(G.world->ent_store->num_reserved)));
pos.y += spacing; pos.y += spacing;
draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("Client data read: %F mbit/s"), FMT_FLOAT_P((f64)G.client_bytes_read.last_second * 8 / 1000 / 1000, 2))); draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("local sim last known tick: %F"), FMT_UINT(G.local_sim_last_known_tick)));
pos.y += spacing; pos.y += spacing;
draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("Client data sent: %F mbit/s"), FMT_FLOAT_P((f64)G.client_bytes_sent.last_second * 8 / 1000 / 1000, 2))); draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("local sim last known time: %F"), FMT_FLOAT_P(SECONDS_FROM_NS(G.local_sim_last_known_time_ns), 3)));
pos.y += spacing; pos.y += spacing;
draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("local sim predicted time: %F"), FMT_FLOAT_P(SECONDS_FROM_NS(G.local_sim_predicted_time_ns), 3)));
pos.y += spacing; pos.y += spacing;
draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("local sim predicted time (smoothed): %F"), FMT_FLOAT_P(SECONDS_FROM_NS(G.local_sim_predicted_time_smoothed_ns), 3)));
pos.y += spacing;
pos.y += spacing;
draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("Memory usage: %F MiB"), FMT_FLOAT_P((f64)atomic_u64_eval(&app_statistics()->memory_committed) / 1024 / 1024, 2))); draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("Memory usage: %F MiB"), FMT_FLOAT_P((f64)atomic_u64_eval(&app_statistics()->memory_committed) / 1024 / 1024, 2)));
pos.y += spacing; pos.y += spacing;
draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("Virtual memory usage: %F TiB"), FMT_FLOAT_P((f64)atomic_u64_eval(&app_statistics()->memory_reserved) / 1024 / 1024 / 1024 / 1024, 2))); draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("Virtual memory usage: %F TiB"), FMT_FLOAT_P((f64)atomic_u64_eval(&app_statistics()->memory_reserved) / 1024 / 1024 / 1024 / 1024, 2)));
pos.y += spacing; pos.y += spacing;
pos.y += spacing;
#if 0 #if 0
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)));
@ -1726,14 +1738,14 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(user_thread_entry_point, arg)
} }
/* ========================== * /* ========================== *
* Sim thread entry point * Local sim thread entry point
* ========================== */ * ========================== */
INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(user_sim_thread_entry_point, arg) INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(user_local_sim_thread_entry_point, arg)
{ {
struct sim_ctx *ctx = (struct sim_ctx *)arg; struct sim_ctx *ctx = (struct sim_ctx *)arg;
i64 target_dt_ns = NS_FROM_SECONDS(1) / SIM_TICKS_PER_SECOND;; i64 target_dt_ns = NS_FROM_SECONDS(1) / SIM_TICKS_PER_SECOND;;
while (!atomic_i32_eval(&G.sim_thread_shutdown)) { while (!atomic_i32_eval(&G.local_sim_thread_shutdown)) {
sim_update(ctx, target_dt_ns); sim_update(ctx, target_dt_ns);
} }
} }