#ifndef _CLIENT_TERRAIN_H_
#define _CLIENT_TERRAIN_H_
+#include <stdatomic.h>
#include <stdbool.h>
#include "client/model.h"
#include "terrain.h"
#include "types.h"
+#define CHUNK_MODE_NOCREATE 2
+
typedef enum {
- CHUNK_RECIEVING, // currently deserializing
- CHUNK_FRESH, // first deserialisation finished, not processed by sync thread yet
- CHUNK_READY, // ready to use and processed by sync thread
+ CHUNK_STATE_INIT,
+ CHUNK_STATE_RECV,
+ CHUNK_STATE_DEPS,
+ CHUNK_STATE_DIRTY,
+ CHUNK_STATE_CLEAN,
} TerrainChunkState;
typedef struct {
- TerrainChunkState state; // keep track of the deserialisation and sync processing state
- bool queue; // whether the chunk is in meshgen queue
- u64 sync; // keep track of when a chunk was synced the last time (used to detect when a chunk got out of and then back into load distance)
- Model *model; // generated by terrain_gfx
- bool empty; // whether the chunk is all air
- bool has_model; // whether the chunk got a model before
- bool depends[6]; // neighbours it depends on
+ bool queue;
+ TerrainChunkState state;
+ pthread_rwlock_t lock_state;
+
+ // accessed only by recv thread
+ TerrainChunk *neighbors[6];
+ unsigned int num_neighbors;
+
+ // write is protected by mtx_model, read is atomic
+ atomic_bool depends[6];
+
+ bool has_model;
+ Model *model;
+ pthread_mutex_t mtx_model;
+
+ // protected by chunk data lock
+ bool empty;
+
+ // accessed only by sync thread
+ u64 sync;
} TerrainChunkMeta;
extern Terrain *client_terrain;
u32 client_terrain_get_load_distance(); // return load distance
void client_terrain_start(); // start meshgen and sync threads
void client_terrain_stop(); // stop meshgen and sync threads
-void client_terrain_chunk_received(TerrainChunk *chunk); // called when a chunk was recieved from server
void client_terrain_meshgen_task(TerrainChunk *chunk, bool changed); // enqueue chunk to mesh update queue
+void client_terrain_receive_chunk(void *peer, ToClientChunk *pkt); // callback to deserialize chunk from network
#endif