prediction progress
This commit is contained in:
parent
7ab7af81a3
commit
50da5f1bc6
100
src/sim_step.c
100
src/sim_step.c
@ -334,16 +334,21 @@ void sim_step(struct sim_step_ctx *ctx)
|
|||||||
__prof;
|
__prof;
|
||||||
struct temp_arena scratch = scratch_begin_no_conflict();
|
struct temp_arena scratch = scratch_begin_no_conflict();
|
||||||
|
|
||||||
|
b32 is_master = ctx->is_master;
|
||||||
struct sim_snapshot *world = ctx->world;
|
struct sim_snapshot *world = ctx->world;
|
||||||
|
|
||||||
|
struct sim_client_store *client_store = world->client->store;
|
||||||
|
struct sim_client *world_client = world->client;
|
||||||
|
struct sim_client *user_input_client = ctx->user_input_client;
|
||||||
|
struct sim_client *publish_client = ctx->publish_client;
|
||||||
|
struct sim_client *master_client = ctx->master_client;
|
||||||
|
|
||||||
i64 sim_dt_ns = ctx->sim_dt_ns;
|
i64 sim_dt_ns = ctx->sim_dt_ns;
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Begin frame
|
* Begin frame
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
//sys_sleep_precise(rng_rand_f32(0, 0.050));
|
|
||||||
//sys_sleep_precise(0.050);
|
|
||||||
|
|
||||||
world->sim_dt_ns = max_i64(0, sim_dt_ns);
|
world->sim_dt_ns = max_i64(0, sim_dt_ns);
|
||||||
world->sim_time_ns += world->sim_dt_ns;
|
world->sim_time_ns += world->sim_dt_ns;
|
||||||
f32 sim_dt = SECONDS_FROM_NS(world->sim_dt_ns);
|
f32 sim_dt = SECONDS_FROM_NS(world->sim_dt_ns);
|
||||||
@ -352,6 +357,69 @@ void sim_step(struct sim_step_ctx *ctx)
|
|||||||
|
|
||||||
struct sim_ent *root = sim_ent_from_id(world, SIM_ENT_ROOT_ID);
|
struct sim_ent *root = sim_ent_from_id(world, SIM_ENT_ROOT_ID);
|
||||||
|
|
||||||
|
/* ========================== *
|
||||||
|
* Sync remote ents
|
||||||
|
* ========================== */
|
||||||
|
|
||||||
|
{
|
||||||
|
for (u64 client_index = 0; client_index < client_store->num_clients_reserved; ++client_index) {
|
||||||
|
struct sim_client *client = &client_store->clients[client_index];
|
||||||
|
if (client->valid && client != world_client && client != publish_client) {
|
||||||
|
/* Create client ent if necessary */
|
||||||
|
if (is_master) {
|
||||||
|
struct sim_ent *client_ent = sim_ent_from_id(world, client->ent_id);
|
||||||
|
if (!client_ent->valid) {
|
||||||
|
/* FIXME: Client ent never released upon disconnect */
|
||||||
|
client_ent = sim_ent_alloc_sync_src(root);
|
||||||
|
client_ent->client_handle = client->handle;
|
||||||
|
sim_ent_enable_prop(client_ent, SIM_ENT_PROP_CLIENT);
|
||||||
|
sim_ent_enable_prop(client_ent, SIM_ENT_PROP_SYNC_PREDICT);
|
||||||
|
sim_ent_enable_prop(client_ent, SIM_ENT_PROP_ACTIVE);
|
||||||
|
client->ent_id = client_ent->id;
|
||||||
|
if (client == user_input_client) {
|
||||||
|
user_input_client->ent_id = client_ent->id;
|
||||||
|
world_client->ent_id = client_ent->id;
|
||||||
|
world->local_client_ent = client_ent->id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sync ents from client */
|
||||||
|
{
|
||||||
|
struct sim_snapshot *src_ss = sim_snapshot_from_tick(client, world->tick);
|
||||||
|
if (src_ss->valid) {
|
||||||
|
sim_snapshot_sync(world, src_ss);
|
||||||
|
if (client == master_client) {
|
||||||
|
world_client->ent_id = src_ss->local_client_ent;
|
||||||
|
world->local_client_ent = src_ss->local_client_ent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mark incoming cmds with correct client */
|
||||||
|
for (u64 i = 0; i < world->num_ents_reserved; ++i) {
|
||||||
|
struct sim_ent *ent = &world->ents[i];
|
||||||
|
if (ent->valid && sim_ent_has_prop(ent, SIM_ENT_PROP_CMD_CONTROL) && sim_ent_has_prop(ent, SIM_ENT_PROP_SYNC_DST)) {
|
||||||
|
struct sim_client *src_client = sim_client_from_handle(client_store, ent->sync_src_client);
|
||||||
|
ent->cmd_client = src_client->ent_id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mark any locally created CMDs as sync sources */
|
||||||
|
if (!is_master) {
|
||||||
|
for (u64 i = 0; i < world->num_ents_reserved; ++i) {
|
||||||
|
struct sim_ent *ent = &world->ents[i];
|
||||||
|
if (sim_ent_is_valid_and_active(ent) && sim_ent_has_prop(ent, SIM_ENT_PROP_CMD_CONTROL)) {
|
||||||
|
if (!sim_ent_id_eq(ent->cmd_client, SIM_ENT_NIL_ID) && sim_ent_id_eq(ent->cmd_client, world->local_client_ent)) {
|
||||||
|
sim_ent_enable_prop(ent, SIM_ENT_PROP_SYNC_SRC);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Release entities at beginning of frame
|
* Release entities at beginning of frame
|
||||||
* ========================== */
|
* ========================== */
|
||||||
@ -403,7 +471,7 @@ void sim_step(struct sim_step_ctx *ctx)
|
|||||||
if (sim_ent_has_prop(cmd_ent, SIM_ENT_PROP_CMD_CONTROL)) {
|
if (sim_ent_has_prop(cmd_ent, SIM_ENT_PROP_CMD_CONTROL)) {
|
||||||
struct sim_ent *client_ent = sim_ent_from_id(world, cmd_ent->cmd_client);
|
struct sim_ent *client_ent = sim_ent_from_id(world, cmd_ent->cmd_client);
|
||||||
if (sim_ent_should_simulate(client_ent)) {
|
if (sim_ent_should_simulate(client_ent)) {
|
||||||
if (!ctx->is_master && !sim_ent_id_eq(client_ent->id, world->local_client_ent)) {
|
if (!is_master && !sim_ent_id_eq(client_ent->id, world->local_client_ent)) {
|
||||||
/* We are not the master and the command is not our own, skip processing */
|
/* We are not the master and the command is not our own, skip processing */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -468,7 +536,7 @@ void sim_step(struct sim_step_ctx *ctx)
|
|||||||
* Create client player ents
|
* Create client player ents
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
if (ctx->is_master) {
|
if (is_master) {
|
||||||
for (u64 i = 0; i < world->num_ents_reserved; ++i) {
|
for (u64 i = 0; i < world->num_ents_reserved; ++i) {
|
||||||
struct sim_ent *ent = &world->ents[i];
|
struct sim_ent *ent = &world->ents[i];
|
||||||
if (!sim_ent_should_simulate(ent)) continue;
|
if (!sim_ent_should_simulate(ent)) continue;
|
||||||
@ -778,7 +846,7 @@ void sim_step(struct sim_step_ctx *ctx)
|
|||||||
|
|
||||||
if (sim_ent_has_prop(ent, SIM_ENT_PROP_CONTROLLED)) {
|
if (sim_ent_has_prop(ent, SIM_ENT_PROP_CONTROLLED)) {
|
||||||
struct sim_ent *joint_ent = sim_ent_from_id(world, ent->move_joint);
|
struct sim_ent *joint_ent = sim_ent_from_id(world, ent->move_joint);
|
||||||
if (ctx->is_master && !sim_ent_is_valid_and_active(joint_ent)) {
|
if (is_master && !sim_ent_is_valid_and_active(joint_ent)) {
|
||||||
joint_ent = sim_ent_alloc_sync_src(root);
|
joint_ent = sim_ent_alloc_sync_src(root);
|
||||||
joint_ent->mass_unscaled = F32_INFINITY;
|
joint_ent->mass_unscaled = F32_INFINITY;
|
||||||
joint_ent->inertia_unscaled = F32_INFINITY;
|
joint_ent->inertia_unscaled = F32_INFINITY;
|
||||||
@ -821,7 +889,7 @@ void sim_step(struct sim_step_ctx *ctx)
|
|||||||
|
|
||||||
/* Retrieve / create aim joint */
|
/* Retrieve / create aim joint */
|
||||||
struct sim_ent *joint_ent = sim_ent_from_id(world, ent->aim_joint);
|
struct sim_ent *joint_ent = sim_ent_from_id(world, ent->aim_joint);
|
||||||
if (ctx->is_master && !sim_ent_is_valid_and_active(joint_ent)) {
|
if (is_master && !sim_ent_is_valid_and_active(joint_ent)) {
|
||||||
joint_ent = sim_ent_alloc_sync_src(root);
|
joint_ent = sim_ent_alloc_sync_src(root);
|
||||||
joint_ent->mass_unscaled = F32_INFINITY;
|
joint_ent->mass_unscaled = F32_INFINITY;
|
||||||
joint_ent->inertia_unscaled = F32_INFINITY;
|
joint_ent->inertia_unscaled = F32_INFINITY;
|
||||||
@ -925,7 +993,7 @@ void sim_step(struct sim_step_ctx *ctx)
|
|||||||
def.max_force = ent->linear_ground_friction;
|
def.max_force = ent->linear_ground_friction;
|
||||||
def.max_torque = ent->angular_ground_friction;
|
def.max_torque = ent->angular_ground_friction;
|
||||||
if (joint_ent->motor_joint_data.max_force != def.max_force || joint_ent->motor_joint_data.max_torque != def.max_torque) {
|
if (joint_ent->motor_joint_data.max_force != def.max_force || joint_ent->motor_joint_data.max_torque != def.max_torque) {
|
||||||
if (ctx->is_master && !sim_ent_is_valid_and_active(joint_ent)) {
|
if (is_master && !sim_ent_is_valid_and_active(joint_ent)) {
|
||||||
joint_ent = sim_ent_alloc_sync_src(root);
|
joint_ent = sim_ent_alloc_sync_src(root);
|
||||||
sim_ent_enable_prop(joint_ent, SIM_ENT_PROP_MOTOR_JOINT);
|
sim_ent_enable_prop(joint_ent, SIM_ENT_PROP_MOTOR_JOINT);
|
||||||
sim_ent_enable_prop(joint_ent, SIM_ENT_PROP_ACTIVE);
|
sim_ent_enable_prop(joint_ent, SIM_ENT_PROP_ACTIVE);
|
||||||
@ -943,7 +1011,7 @@ void sim_step(struct sim_step_ctx *ctx)
|
|||||||
* Create mouse joints from client debug drag
|
* Create mouse joints from client debug drag
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
if (ctx->is_master) {
|
if (is_master) {
|
||||||
for (u64 i = 0; i < world->num_ents_reserved; ++i) {
|
for (u64 i = 0; i < world->num_ents_reserved; ++i) {
|
||||||
struct sim_ent *client_ent = &world->ents[i];
|
struct sim_ent *client_ent = &world->ents[i];
|
||||||
if (!sim_ent_should_simulate(client_ent)) continue;
|
if (!sim_ent_should_simulate(client_ent)) continue;
|
||||||
@ -1187,6 +1255,20 @@ void sim_step(struct sim_step_ctx *ctx)
|
|||||||
|
|
||||||
sim_ent_release_all_with_prop(world, SIM_ENT_PROP_RELEASE);
|
sim_ent_release_all_with_prop(world, SIM_ENT_PROP_RELEASE);
|
||||||
|
|
||||||
|
/* ========================== *
|
||||||
|
* Sync to publish client
|
||||||
|
* ========================== */
|
||||||
|
|
||||||
|
if (publish_client->valid) {
|
||||||
|
struct sim_snapshot *pub_world = sim_snapshot_from_tick(publish_client, world->tick);
|
||||||
|
if (!pub_world->valid) {
|
||||||
|
struct sim_snapshot *prev_pub_world = sim_snapshot_from_tick(publish_client, publish_client->last_tick);
|
||||||
|
pub_world = sim_snapshot_alloc(publish_client, prev_pub_world, world->tick);
|
||||||
|
pub_world->local_client_ent = world->local_client_ent;
|
||||||
|
sim_snapshot_sync(pub_world, world);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* End frame
|
* End frame
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|||||||
@ -27,8 +27,13 @@ void sim_accel_reset(struct sim_snapshot *ss, struct sim_accel *accel);
|
|||||||
struct sim_step_ctx {
|
struct sim_step_ctx {
|
||||||
b32 is_master;
|
b32 is_master;
|
||||||
struct sim_accel *accel;
|
struct sim_accel *accel;
|
||||||
struct sim_snapshot *world;
|
|
||||||
i64 sim_dt_ns;
|
struct sim_snapshot *world; /* The world to simulate */
|
||||||
|
i64 sim_dt_ns; /* How much sim time should progress */
|
||||||
|
|
||||||
|
struct sim_client *user_input_client; /* The client that contains input from the user thread */
|
||||||
|
struct sim_client *master_client; /* The master client to read snapshots from (nil if world is master) */
|
||||||
|
struct sim_client *publish_client; /* The publish client to write syncable state to (nil if skipping publish) */
|
||||||
};
|
};
|
||||||
|
|
||||||
void sim_step(struct sim_step_ctx *ctx);
|
void sim_step(struct sim_step_ctx *ctx);
|
||||||
|
|||||||
189
src/user.c
189
src/user.c
@ -1896,7 +1896,22 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(user_local_sim_thread_entry_point, arg)
|
|||||||
struct sim_client *master_client = sim_client_nil(); /* Stores snapshots received from master (if relevant) */
|
struct sim_client *master_client = sim_client_nil(); /* Stores snapshots received from master (if relevant) */
|
||||||
b32 initialized_from_master = false;
|
b32 initialized_from_master = false;
|
||||||
|
|
||||||
u64 step_tick = 0;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
@ -1909,7 +1924,6 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(user_local_sim_thread_entry_point, arg)
|
|||||||
sleep_frame(last_tick_ns, compute_dt_ns);
|
sleep_frame(last_tick_ns, compute_dt_ns);
|
||||||
last_tick_ns = sys_time_ns();
|
last_tick_ns = sys_time_ns();
|
||||||
}
|
}
|
||||||
++step_tick;
|
|
||||||
|
|
||||||
/* Read net messages */
|
/* Read net messages */
|
||||||
struct sim_decode_queue queue = ZI;
|
struct sim_decode_queue queue = ZI;
|
||||||
@ -2046,10 +2060,9 @@ 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;
|
//step_tick = master_client->last_tick;
|
||||||
initialized_from_master = true;
|
initialized_from_master = true;
|
||||||
} else {
|
} else {
|
||||||
step_tick = 0;
|
|
||||||
goto skip_step;
|
goto skip_step;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2057,7 +2070,7 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(user_local_sim_thread_entry_point, arg)
|
|||||||
/* Create user input */
|
/* 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 *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, step_tick);
|
struct sim_snapshot *user_input_ss = sim_snapshot_alloc(user_input_client, prev_user_input_ss, local_client->last_tick + ahead + 1);
|
||||||
struct sim_ent *user_input_root = sim_ent_from_id(user_input_ss, SIM_ENT_ROOT_ID);
|
struct sim_ent *user_input_root = sim_ent_from_id(user_input_ss, SIM_ENT_ROOT_ID);
|
||||||
/* Find / create local control cmd ent */
|
/* 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);
|
struct sim_ent *control_cmd_ent = sim_ent_find_first_match_one(user_input_ss, SIM_ENT_PROP_CMD_CONTROL);
|
||||||
@ -2077,61 +2090,15 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(user_local_sim_thread_entry_point, arg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
/* Allocate local snapshot */
|
/* Allocate local snapshot */
|
||||||
struct sim_snapshot *prev_local_ss = sim_snapshot_from_tick(local_client, local_client->last_tick);
|
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);
|
struct sim_snapshot *local_ss = sim_snapshot_alloc(local_client, prev_local_ss, step_tick);
|
||||||
|
for (u64 i = 0; i < ahead; ++i) {
|
||||||
/* Sync remote ents to local */
|
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);
|
||||||
struct sim_ent *local_root = sim_ent_from_id(local_ss, SIM_ENT_ROOT_ID);
|
|
||||||
for (u64 client_index = 0; client_index < store->num_clients_reserved; ++client_index) {
|
|
||||||
struct sim_client *client = &store->clients[client_index];
|
|
||||||
if (client->valid) {
|
|
||||||
/* Create client ent if necessary */
|
|
||||||
if (is_master && client != publish_client && client != local_client && client != master_client) {
|
|
||||||
struct sim_ent *client_ent = sim_ent_from_id(local_ss, client->ent_id);
|
|
||||||
if (!client_ent->valid) {
|
|
||||||
/* FIXME: Client ent never released upon disconnect */
|
|
||||||
client_ent = sim_ent_alloc_sync_src(local_root);
|
|
||||||
client_ent->client_handle = client->handle;
|
|
||||||
sim_ent_enable_prop(client_ent, SIM_ENT_PROP_CLIENT);
|
|
||||||
sim_ent_enable_prop(client_ent, SIM_ENT_PROP_SYNC_PREDICT);
|
|
||||||
sim_ent_enable_prop(client_ent, SIM_ENT_PROP_ACTIVE);
|
|
||||||
client->ent_id = client_ent->id;
|
|
||||||
if (client == user_input_client) {
|
|
||||||
user_input_client->ent_id = client_ent->id;
|
|
||||||
local_client->ent_id = client_ent->id;
|
|
||||||
local_ss->local_client_ent = client_ent->id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Sync w/ client */
|
|
||||||
if (client != publish_client && client != local_client) {
|
|
||||||
struct sim_snapshot *client_ss = sim_snapshot_from_tick(client, step_tick);
|
|
||||||
if (client_ss->valid) {
|
|
||||||
sim_snapshot_sync(local_ss, client_ss);
|
|
||||||
if (!is_master && client == master_client) {
|
|
||||||
user_input_client->ent_id = client_ss->local_client_ent;
|
|
||||||
local_client->ent_id = client_ss->local_client_ent;
|
|
||||||
local_ss->local_client_ent = client_ss->local_client_ent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Point cmds to correct client ents */
|
|
||||||
for (u64 i = 0; i < local_ss->num_ents_reserved; ++i) {
|
|
||||||
struct sim_ent *ent = &local_ss->ents[i];
|
|
||||||
if (ent->valid && sim_ent_has_prop(ent, SIM_ENT_PROP_CMD_CONTROL) && sim_ent_has_prop(ent, SIM_ENT_PROP_SYNC_DST)) {
|
|
||||||
struct sim_client *src_client = sim_client_from_handle(store, ent->sync_src_client);
|
|
||||||
struct sim_ent *client_ent = sim_ent_from_id(local_ss, src_client->ent_id);
|
|
||||||
ent->cmd_client = client_ent->id;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Release unneeded received snapshots */
|
/* Release unneeded received snapshots */
|
||||||
u64 oldest_client_ack = 0;
|
u64 oldest_client_ack = 0;
|
||||||
@ -2139,7 +2106,8 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(user_local_sim_thread_entry_point, arg)
|
|||||||
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) {
|
||||||
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;
|
||||||
sim_snapshot_release_ticks_in_range(client, 0, keep_tick - 1);
|
sim_snapshot_release_ticks_in_range(client, 0, keep_tick - 1);
|
||||||
}
|
}
|
||||||
if (client->ack < oldest_client_ack || oldest_client_ack == 0) {
|
if (client->ack < oldest_client_ack || oldest_client_ack == 0) {
|
||||||
@ -2160,18 +2128,25 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(user_local_sim_thread_entry_point, arg)
|
|||||||
sim_snapshot_release_ticks_in_range(publish_client, 0, keep_tick);
|
sim_snapshot_release_ticks_in_range(publish_client, 0, keep_tick);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Release unneeded user input snapshots */
|
|
||||||
sim_snapshot_release_ticks_in_range(user_input_client, 0, step_tick - 1);
|
|
||||||
|
|
||||||
/* Release old local snapshots */
|
/* Release old local snapshots */
|
||||||
{
|
{
|
||||||
u64 keep_range = 100;
|
u64 keep_range = 500;
|
||||||
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Release unneeded user input snapshots */
|
||||||
|
sim_snapshot_release_ticks_in_range(user_input_client, 0, local_client->last_tick - 1);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -2181,53 +2156,70 @@ 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;
|
struct sim_step_ctx step_ctx = ZI;
|
||||||
step_ctx.is_master = is_master;
|
step_ctx.is_master = is_master;
|
||||||
step_ctx.accel = &accel;
|
|
||||||
step_ctx.world = local_ss;
|
|
||||||
step_ctx.sim_dt_ns = step_dt_ns;
|
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);
|
sim_step(&step_ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Signal any locally created CMDs as sync sources */
|
|
||||||
for (u64 i = 0; i < local_ss->num_ents_reserved; ++i) {
|
|
||||||
struct sim_ent *ent = &local_ss->ents[i];
|
|
||||||
if (sim_ent_is_valid_and_active(ent) && sim_ent_has_prop(ent, SIM_ENT_PROP_CMD_CONTROL)) {
|
|
||||||
if (!sim_ent_id_eq(ent->cmd_client, SIM_ENT_NIL_ID) && sim_ent_id_eq(ent->cmd_client, local_ss->local_client_ent)) {
|
|
||||||
sim_ent_enable_prop(ent, SIM_ENT_PROP_SYNC_SRC);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
#else
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Construct publishable snapshot */
|
|
||||||
{
|
{
|
||||||
struct sim_snapshot *pub_ss;
|
struct sim_step_ctx ctx = ZI;
|
||||||
|
ctx.is_master = is_master;
|
||||||
|
ctx.sim_dt_ns = step_dt_ns;
|
||||||
|
ctx.accel = &accel;
|
||||||
|
|
||||||
|
ctx.user_input_client = user_input_client;
|
||||||
|
ctx.master_client = master_client;
|
||||||
|
ctx.publish_client = publish_client;
|
||||||
|
|
||||||
if (is_master) {
|
if (is_master) {
|
||||||
pub_ss = sim_snapshot_alloc(publish_client, sim_snapshot_from_tick(publish_client, publish_client->last_tick), local_ss->tick);
|
u64 prev_tick = local_client->last_tick;
|
||||||
|
struct sim_snapshot *prev_world = sim_snapshot_from_tick(local_client, prev_tick);
|
||||||
|
ctx.world = sim_snapshot_alloc(local_client, prev_world, prev_tick + 1);
|
||||||
|
sim_step(&ctx);
|
||||||
} else {
|
} else {
|
||||||
pub_ss = sim_snapshot_alloc(publish_client, sim_snapshot_from_tick(publish_client, publish_client->last_tick), local_ss->tick + 5);
|
struct sim_snapshot *master_ss = sim_snapshot_from_tick(master_client, master_client->last_tick);
|
||||||
|
if (master_ss->valid) {
|
||||||
|
struct sim_snapshot *prev_world = sim_snapshot_alloc(local_client, master_ss, master_ss->tick);
|
||||||
|
for (u64 i = 0; i < ahead; ++i) {
|
||||||
|
ctx.world = sim_snapshot_alloc(local_client, prev_world, prev_world->tick + 1);
|
||||||
|
sim_step(&ctx);
|
||||||
|
prev_world = ctx.world;
|
||||||
}
|
}
|
||||||
sim_snapshot_sync(pub_ss, local_ss);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -2282,15 +2274,16 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(user_local_sim_thread_entry_point, arg)
|
|||||||
|
|
||||||
/* Copy local snapshot to user client */
|
/* Copy local snapshot to user client */
|
||||||
{
|
{
|
||||||
|
struct sim_snapshot *local_world = sim_snapshot_from_tick(local_client, local_client->last_tick);
|
||||||
|
|
||||||
/* TODO: Double buffer */
|
/* TODO: Double buffer */
|
||||||
struct sys_lock lock = sys_mutex_lock_e(&G.local_to_user_client_mutex);
|
struct sys_lock lock = sys_mutex_lock_e(&G.local_to_user_client_mutex);
|
||||||
struct sim_snapshot *copy_ss = sim_snapshot_alloc(G.local_to_user_client, local_ss, local_ss->tick);
|
struct sim_snapshot *copy_ss = sim_snapshot_alloc(G.local_to_user_client, local_world, local_world->tick);
|
||||||
copy_ss->local_client_ent = local_ss->local_client_ent;
|
|
||||||
i64 publish_ns = sys_time_ns();
|
i64 publish_ns = sys_time_ns();
|
||||||
copy_ss->publish_dt_ns = publish_ns - last_publish_ns;
|
copy_ss->publish_dt_ns = publish_ns - last_publish_ns;
|
||||||
copy_ss->publish_time_ns = publish_ns;
|
copy_ss->publish_time_ns = publish_ns;
|
||||||
last_publish_ns = publish_ns;
|
last_publish_ns = publish_ns;
|
||||||
sim_snapshot_release_ticks_in_range(G.local_to_user_client, 0, local_ss->tick - 1);
|
sim_snapshot_release_ticks_in_range(G.local_to_user_client, 0, local_world->tick - 1);
|
||||||
sys_mutex_unlock(&lock);
|
sys_mutex_unlock(&lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user