#ifndef SIM_SNAPSHOT_H #define SIM_SNAPSHOT_H #include "sim_ent.h" #include "sim_client.h" /* TODO: Remove this */ struct space; struct sim_snapshot_store { b32 valid; struct arena arena; /* Snapshots sorted by tick (low to high) */ u64 first_tick; u64 last_tick; u64 num_ticks; struct sim_snapshot *first_free_snapshot; /* Tick -> snapshot lookup */ u64 num_lookup_buckets; struct sim_snapshot_lookup_bucket *lookup_buckets; }; struct sim_snapshot { b32 valid; u64 tick; struct sim_snapshot_store *store; struct sim_snapshot *next_free; struct sim_snapshot *next_in_bucket; struct sim_snapshot *prev_in_bucket; u64 prev_tick; u64 next_tick; struct arena arena; /* Real time (increases with clock assuming no lag) */ i64 real_dt_ns; i64 real_time_ns; /* World time (affected by timescale) */ f64 world_timescale; 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; /* The last physics iteration (used for tracking contact lifetime) */ u64 phys_iteration; /* Which client in the client store represents the local host in the original snapshot */ struct sim_client_handle local_client; /* Client lookup */ struct sim_client_lookup_bucket *client_lookup_buckets; u64 num_client_lookup_buckets; /* Clients */ struct arena clients_arena; struct sim_client *clients; struct sim_client_handle first_free_client; u64 num_clients_allocated; u64 num_clients_reserved; /* Entities */ struct arena ents_arena; struct sim_ent *ents; struct sim_ent_handle first_free_ent; u64 num_ents_allocated; u64 num_ents_reserved; }; /* ========================== * * Startup * ========================== */ struct sim_snapshot_startup_receipt { i32 _; }; struct sim_snapshot_startup_receipt sim_snapshot_startup(void); /* ========================== * * Store * ========================== */ struct sim_snapshot_store *sim_snapshot_store_alloc(void); void sim_snapshot_store_release(struct sim_snapshot_store *store); void sim_snapshot_store_release_ticks_in_range(struct sim_snapshot_store *store, u64 start, u64 end); /* ========================== * * Nil * ========================== */ INLINE struct sim_snapshot *sim_snapshot_nil(void) { extern READONLY struct sim_snapshot **_g_sim_snapshot_nil; return *_g_sim_snapshot_nil; } INLINE struct sim_snapshot_store *sim_snapshot_store_nil(void) { extern READONLY struct sim_snapshot_store **_g_sim_snapshot_store_nil; return *_g_sim_snapshot_store_nil; } /* ========================== * * Snapshot * ========================== */ struct bitbuff_writer; struct bitbuff_reader; /* Alloc */ struct sim_snapshot *sim_snapshot_alloc(struct sim_snapshot_store *store, struct sim_snapshot *src, u64 tick); void sim_snapshot_release(struct sim_snapshot *sim_snapshot); /* Lookup */ struct sim_snapshot *sim_snapshot_from_tick(struct sim_snapshot_store *store, u64 tick); /* Lerp */ struct sim_snapshot *sim_snapshot_alloc_from_lerp(struct sim_snapshot_store *store, struct sim_snapshot *ss0, struct sim_snapshot *ss1, f64 blend); /* Encode / decode */ void sim_snapshot_encode(struct bitbuff_writer *bw, struct sim_snapshot *ss0, struct sim_snapshot *ss1, struct sim_client *client); void sim_snapshot_decode(struct bitbuff_reader *br, struct sim_snapshot *ss); #endif