prediction progress
This commit is contained in:
parent
79b32b187a
commit
a364f311d1
12
src/host.c
12
src/host.c
@ -75,6 +75,8 @@ struct host_channel {
|
|||||||
struct host_msg_assembler *least_recent_msg_assembler;
|
struct host_msg_assembler *least_recent_msg_assembler;
|
||||||
struct host_msg_assembler *most_recent_msg_assembler;
|
struct host_msg_assembler *most_recent_msg_assembler;
|
||||||
|
|
||||||
|
i64 rtt_ns;
|
||||||
|
|
||||||
u64 last_sent_msg_id;
|
u64 last_sent_msg_id;
|
||||||
u64 their_acked_seq;
|
u64 their_acked_seq;
|
||||||
u64 our_acked_seq;
|
u64 our_acked_seq;
|
||||||
@ -616,6 +618,16 @@ void host_queue_write(struct host *host, struct host_channel_id channel_id, stru
|
|||||||
cmd->write_reliable = flags & HOST_WRITE_FLAG_RELIABLE;
|
cmd->write_reliable = flags & HOST_WRITE_FLAG_RELIABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ========================== *
|
||||||
|
* Info
|
||||||
|
* ========================== */
|
||||||
|
|
||||||
|
i64 host_get_channel_rtt_ns(struct host *host, struct host_channel_id channel_id)
|
||||||
|
{
|
||||||
|
struct host_channel *channel = host_single_channel_from_id(host, channel_id);
|
||||||
|
return channel->rtt_ns;
|
||||||
|
}
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Update
|
* Update
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|||||||
@ -124,6 +124,12 @@ void host_queue_disconnect(struct host *host, struct host_channel_id channel_id)
|
|||||||
|
|
||||||
void host_queue_write(struct host *host, struct host_channel_id channel_id, struct string msg, u32 flags);
|
void host_queue_write(struct host *host, struct host_channel_id channel_id, struct string msg, u32 flags);
|
||||||
|
|
||||||
|
/* ========================== *
|
||||||
|
* Info
|
||||||
|
* ========================== */
|
||||||
|
|
||||||
|
i64 host_get_channel_rtt_ns(struct host *host, struct host_channel_id channel_id);
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Update
|
* Update
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|||||||
@ -72,6 +72,7 @@ struct sim_client {
|
|||||||
|
|
||||||
struct arena snapshots_arena;
|
struct arena snapshots_arena;
|
||||||
|
|
||||||
|
i64 rtt_ns; /* Round trip time of the client (if networked) */
|
||||||
struct host_channel_id channel_id;
|
struct host_channel_id channel_id;
|
||||||
u64 channel_hash;
|
u64 channel_hash;
|
||||||
|
|
||||||
|
|||||||
122
src/user.c
122
src/user.c
@ -1895,7 +1895,7 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(user_local_sim_thread_entry_point, arg)
|
|||||||
struct sim_accel accel = sim_accel_alloc();
|
struct sim_accel accel = sim_accel_alloc();
|
||||||
|
|
||||||
struct sim_client_store *store = sim_client_store_alloc();
|
struct sim_client_store *store = sim_client_store_alloc();
|
||||||
struct sim_client *user_input_client = sim_client_alloc(store); /* Stores snapshots containing commands to be published to both local & master clients */
|
struct sim_client *user_input_client = sim_client_alloc(store); /* Stores snapshots containing commands to be published to local client */
|
||||||
struct sim_client *local_client = sim_client_alloc(store); /* Stores snapshots produced locally */
|
struct sim_client *local_client = sim_client_alloc(store); /* Stores snapshots produced locally */
|
||||||
struct sim_client *publish_client = sim_client_alloc(store); /* Stores versions of local snapshots that will be published to remote sims */
|
struct sim_client *publish_client = sim_client_alloc(store); /* Stores versions of local snapshots that will be published to remote sims */
|
||||||
|
|
||||||
@ -1906,18 +1906,6 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(user_local_sim_thread_entry_point, arg)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
u64 ahead = 0;
|
|
||||||
if (!is_master) {
|
|
||||||
ahead = 50;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
i64 last_publish_ns = 0;
|
i64 last_publish_ns = 0;
|
||||||
i64 last_tick_ns = 0;
|
i64 last_tick_ns = 0;
|
||||||
i64 step_dt_ns = NS_FROM_SECONDS(1) / SIM_TICKS_PER_SECOND;
|
i64 step_dt_ns = NS_FROM_SECONDS(1) / SIM_TICKS_PER_SECOND;
|
||||||
@ -2068,52 +2056,19 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(user_local_sim_thread_entry_point, arg)
|
|||||||
|
|
||||||
if (!is_master && !initialized_from_master) {
|
if (!is_master && !initialized_from_master) {
|
||||||
if (master_client->valid && master_client->last_tick > 0) {
|
if (master_client->valid && master_client->last_tick > 0) {
|
||||||
//step_tick = master_client->last_tick;
|
|
||||||
initialized_from_master = true;
|
initialized_from_master = true;
|
||||||
} else {
|
} else {
|
||||||
goto skip_step;
|
goto skip_step;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create user input */
|
/* Update networked clients */
|
||||||
{
|
|
||||||
struct sim_snapshot *prev_user_input_ss = sim_snapshot_from_tick(user_input_client, user_input_client->last_tick);
|
|
||||||
struct sim_snapshot *user_input_ss = sim_snapshot_alloc(user_input_client, prev_user_input_ss, local_client->last_tick + 1);
|
|
||||||
struct sim_ent *user_input_root = sim_ent_from_id(user_input_ss, SIM_ENT_ROOT_ID);
|
|
||||||
/* Find / create local control cmd ent */
|
|
||||||
struct sim_ent *control_cmd_ent = sim_ent_find_first_match_one(user_input_ss, SIM_ENT_PROP_CMD_CONTROL);
|
|
||||||
if (!control_cmd_ent->valid) {
|
|
||||||
control_cmd_ent = sim_ent_alloc_sync_src(user_input_root);
|
|
||||||
control_cmd_ent->predictor = user_input_ss->local_client_ent;
|
|
||||||
sim_ent_enable_prop(control_cmd_ent, SIM_ENT_PROP_CMD_CONTROL);
|
|
||||||
control_cmd_ent->predictor = user_input_client->ent_id;
|
|
||||||
sim_ent_activate(control_cmd_ent, user_input_ss->tick);
|
|
||||||
}
|
|
||||||
/* Update local control cmd ent */
|
|
||||||
{
|
|
||||||
struct sys_lock lock = sys_mutex_lock_e(&G.user_sim_cmd_mutex);
|
|
||||||
control_cmd_ent->cmd_control = G.user_sim_cmd_control;
|
|
||||||
control_cmd_ent->cmd_hovered_ent = G.user_hovered_ent;
|
|
||||||
++G.user_sim_cmd_gen;
|
|
||||||
sys_mutex_unlock(&lock);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
/* Allocate local snapshot */
|
|
||||||
struct sim_snapshot *prev_local_ss = sim_snapshot_from_tick(local_client, local_client->last_tick);
|
|
||||||
struct sim_snapshot *local_ss = sim_snapshot_alloc(local_client, prev_local_ss, step_tick);
|
|
||||||
for (u64 i = 0; i < ahead; ++i) {
|
|
||||||
struct sim_snapshot *prev_predict_ss = sim_snapshot_from_tick(local_client, local_ss->tick + i);
|
|
||||||
sim_snapshot_alloc(local_client, prev_predict_ss, prev_predict_ss->tick + 1);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Release unneeded received snapshots */
|
|
||||||
u64 oldest_client_ack = 0;
|
u64 oldest_client_ack = 0;
|
||||||
for (u64 i = 0; i < store->num_clients_reserved; ++i) {
|
for (u64 i = 0; i < store->num_clients_reserved; ++i) {
|
||||||
struct sim_client *client = &store->clients[i];
|
struct sim_client *client = &store->clients[i];
|
||||||
if (client->valid && client != local_client && client != publish_client && client != user_input_client) {
|
if (client->valid && client != local_client && client != publish_client && client != user_input_client) {
|
||||||
|
client->rtt_ns = host_get_channel_rtt_ns(host, client->channel_id);
|
||||||
|
/* Release unneeded received snapshots */
|
||||||
if (client->double_ack > 0) {
|
if (client->double_ack > 0) {
|
||||||
//u64 keep_tick = max_u64(min_u64(client->double_ack, step_tick), 1);
|
//u64 keep_tick = max_u64(min_u64(client->double_ack, step_tick), 1);
|
||||||
u64 keep_tick = 1;
|
u64 keep_tick = 1;
|
||||||
@ -2139,7 +2094,7 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(user_local_sim_thread_entry_point, arg)
|
|||||||
|
|
||||||
/* Release old local snapshots */
|
/* Release old local snapshots */
|
||||||
{
|
{
|
||||||
u64 keep_range = 500;
|
u64 keep_range = 250;
|
||||||
if (local_client->last_tick > keep_range) {
|
if (local_client->last_tick > keep_range) {
|
||||||
u64 keep_tick = local_client->last_tick - keep_range;
|
u64 keep_tick = local_client->last_tick - keep_range;
|
||||||
sim_snapshot_release_ticks_in_range(local_client, 0, keep_tick);
|
sim_snapshot_release_ticks_in_range(local_client, 0, keep_tick);
|
||||||
@ -2152,6 +2107,45 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(user_local_sim_thread_entry_point, arg)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Determine step tick */
|
||||||
|
u64 desired_step_tick = 0;
|
||||||
|
if (is_master) {
|
||||||
|
desired_step_tick = local_client->last_tick + 1;
|
||||||
|
} else {
|
||||||
|
i64 half_rtt_ns = master_client->rtt_ns / 2;
|
||||||
|
i64 num_predict_ticks = (half_rtt_ns + (step_dt_ns - 1)) / step_dt_ns; /* Half rtt in ticks */
|
||||||
|
num_predict_ticks += 2; /* Jitter buffer */
|
||||||
|
desired_step_tick = master_client->last_tick + num_predict_ticks;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Create user input */
|
||||||
|
{
|
||||||
|
struct sim_snapshot *prev_user_input_ss = sim_snapshot_from_tick(user_input_client, user_input_client->last_tick);
|
||||||
|
struct sim_snapshot *user_input_ss = sim_snapshot_alloc(user_input_client, prev_user_input_ss, local_client->last_tick + 1);
|
||||||
|
struct sim_ent *user_input_root = sim_ent_from_id(user_input_ss, SIM_ENT_ROOT_ID);
|
||||||
|
/* Find / create local control cmd ent */
|
||||||
|
struct sim_ent *control_cmd_ent = sim_ent_find_first_match_one(user_input_ss, SIM_ENT_PROP_CMD_CONTROL);
|
||||||
|
if (!control_cmd_ent->valid) {
|
||||||
|
control_cmd_ent = sim_ent_alloc_sync_src(user_input_root);
|
||||||
|
control_cmd_ent->predictor = user_input_ss->local_client_ent;
|
||||||
|
sim_ent_enable_prop(control_cmd_ent, SIM_ENT_PROP_CMD_CONTROL);
|
||||||
|
control_cmd_ent->predictor = user_input_client->ent_id;
|
||||||
|
sim_ent_activate(control_cmd_ent, user_input_ss->tick);
|
||||||
|
}
|
||||||
|
/* Update local control cmd ent */
|
||||||
|
{
|
||||||
|
struct sys_lock lock = sys_mutex_lock_e(&G.user_sim_cmd_mutex);
|
||||||
|
control_cmd_ent->cmd_control = G.user_sim_cmd_control;
|
||||||
|
control_cmd_ent->cmd_hovered_ent = G.user_hovered_ent;
|
||||||
|
++G.user_sim_cmd_gen;
|
||||||
|
sys_mutex_unlock(&lock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -2165,28 +2159,6 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(user_local_sim_thread_entry_point, arg)
|
|||||||
|
|
||||||
|
|
||||||
/* Step */
|
/* Step */
|
||||||
#if 0
|
|
||||||
{
|
|
||||||
struct sim_step_ctx step_ctx = ZI;
|
|
||||||
step_ctx.is_master = is_master;
|
|
||||||
step_ctx.sim_dt_ns = step_dt_ns;
|
|
||||||
step_ctx.accel = &accel;
|
|
||||||
|
|
||||||
step_ctx.user_input_client = user_input_client;
|
|
||||||
step_ctx.master_client = master_client;
|
|
||||||
step_ctx.publish_client = publish_client;
|
|
||||||
|
|
||||||
if (is_master) {
|
|
||||||
ctx.prev_world = sim_snapshot_from_tick(local_client, local_client->last_tick);
|
|
||||||
sim_step(&step_ctx);
|
|
||||||
} else {
|
|
||||||
for (u64 i = 0; i < ahead; ++i) {
|
|
||||||
ctx.prev_world = sim_snapshot_from_tick(local_client, master_client->last_tick + i);
|
|
||||||
sim_step(&step_ctx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
{
|
{
|
||||||
struct sim_step_ctx ctx = ZI;
|
struct sim_step_ctx ctx = ZI;
|
||||||
ctx.is_master = is_master;
|
ctx.is_master = is_master;
|
||||||
@ -2208,9 +2180,10 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(user_local_sim_thread_entry_point, arg)
|
|||||||
local_client->ent_id = master_ss->local_client_ent;
|
local_client->ent_id = master_ss->local_client_ent;
|
||||||
user_input_client->ent_id = master_ss->local_client_ent;
|
user_input_client->ent_id = master_ss->local_client_ent;
|
||||||
|
|
||||||
|
|
||||||
struct sim_snapshot *prev_world = sim_snapshot_alloc(local_client, master_ss, master_ss->tick);
|
struct sim_snapshot *prev_world = sim_snapshot_alloc(local_client, master_ss, master_ss->tick);
|
||||||
for (u64 i = 0; i < ahead; ++i) {
|
/* FIXME: Don't take use desired_step_tick at face value. Dilate compute_dt to work towards it. */
|
||||||
|
i64 num_predict_ticks = desired_step_tick - master_ss->tick;
|
||||||
|
for (i64 i = 0; i < num_predict_ticks; ++i) {
|
||||||
ctx.world = sim_snapshot_alloc(local_client, prev_world, prev_world->tick + 1);
|
ctx.world = sim_snapshot_alloc(local_client, prev_world, prev_world->tick + 1);
|
||||||
sim_step(&ctx);
|
sim_step(&ctx);
|
||||||
prev_world = ctx.world;
|
prev_world = ctx.world;
|
||||||
@ -2218,7 +2191,6 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(user_local_sim_thread_entry_point, arg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user