load chunks on threads too
parent
93261dd412
commit
9d8ac0b1b2
7
src/db.c
7
src/db.c
|
@ -22,6 +22,7 @@ static Ring ring;
|
|||
static thrd_t thrd;
|
||||
static mtx_t mtx;
|
||||
static cnd_t cnd;
|
||||
static mtx_t load_mtx;
|
||||
|
||||
void db_enable() {
|
||||
db_enabled = 1;
|
||||
|
@ -404,6 +405,7 @@ void db_load_blocks(Map *map, int p, int q) {
|
|||
if (!db_enabled) {
|
||||
return;
|
||||
}
|
||||
mtx_lock(&load_mtx);
|
||||
sqlite3_reset(load_blocks_stmt);
|
||||
sqlite3_bind_int(load_blocks_stmt, 1, p);
|
||||
sqlite3_bind_int(load_blocks_stmt, 2, q);
|
||||
|
@ -414,12 +416,14 @@ void db_load_blocks(Map *map, int p, int q) {
|
|||
int w = sqlite3_column_int(load_blocks_stmt, 3);
|
||||
map_set(map, x, y, z, w);
|
||||
}
|
||||
mtx_unlock(&load_mtx);
|
||||
}
|
||||
|
||||
void db_load_lights(Map *map, int p, int q) {
|
||||
if (!db_enabled) {
|
||||
return;
|
||||
}
|
||||
mtx_lock(&load_mtx);
|
||||
sqlite3_reset(load_lights_stmt);
|
||||
sqlite3_bind_int(load_lights_stmt, 1, p);
|
||||
sqlite3_bind_int(load_lights_stmt, 2, q);
|
||||
|
@ -430,6 +434,7 @@ void db_load_lights(Map *map, int p, int q) {
|
|||
int w = sqlite3_column_int(load_lights_stmt, 3);
|
||||
map_set(map, x, y, z, w);
|
||||
}
|
||||
mtx_unlock(&load_mtx);
|
||||
}
|
||||
|
||||
void db_load_signs(SignList *list, int p, int q) {
|
||||
|
@ -487,6 +492,7 @@ void db_worker_start(char *path) {
|
|||
}
|
||||
ring_alloc(&ring, 1024);
|
||||
mtx_init(&mtx, mtx_plain);
|
||||
mtx_init(&load_mtx, mtx_plain);
|
||||
cnd_init(&cnd);
|
||||
thrd_create(&thrd, db_worker_run, path);
|
||||
}
|
||||
|
@ -501,6 +507,7 @@ void db_worker_stop() {
|
|||
mtx_unlock(&mtx);
|
||||
thrd_join(thrd, NULL);
|
||||
cnd_destroy(&cnd);
|
||||
mtx_destroy(&load_mtx);
|
||||
mtx_destroy(&mtx);
|
||||
ring_free(&ring);
|
||||
}
|
||||
|
|
111
src/main.c
111
src/main.c
|
@ -36,10 +36,8 @@
|
|||
#define MODE_ONLINE 1
|
||||
|
||||
#define WORKER_IDLE 0
|
||||
#define WORKER_CREATE 1
|
||||
#define WORKER_CREATED 2
|
||||
#define WORKER_UPDATE 3
|
||||
#define WORKER_UPDATED 4
|
||||
#define WORKER_BUSY 1
|
||||
#define WORKER_DONE 2
|
||||
|
||||
typedef struct {
|
||||
Map map;
|
||||
|
@ -59,20 +57,14 @@ typedef struct {
|
|||
typedef struct {
|
||||
int p;
|
||||
int q;
|
||||
Map *block_map;
|
||||
Map *light_map;
|
||||
} CreateItem;
|
||||
|
||||
typedef struct {
|
||||
int p;
|
||||
int q;
|
||||
int load;
|
||||
Map *block_maps[3][3];
|
||||
Map *light_maps[3][3];
|
||||
int miny;
|
||||
int maxy;
|
||||
int faces;
|
||||
GLfloat *data;
|
||||
} UpdateItem;
|
||||
} WorkerItem;
|
||||
|
||||
typedef struct {
|
||||
int index;
|
||||
|
@ -80,8 +72,7 @@ typedef struct {
|
|||
thrd_t thrd;
|
||||
mtx_t mtx;
|
||||
cnd_t cnd;
|
||||
CreateItem create_item;
|
||||
UpdateItem update_item;
|
||||
WorkerItem item;
|
||||
} Worker;
|
||||
|
||||
typedef struct {
|
||||
|
@ -964,7 +955,7 @@ void light_fill(
|
|||
light_fill(opaque, light, x, y, z + 1, w, 0);
|
||||
}
|
||||
|
||||
void compute_chunk(UpdateItem *item) {
|
||||
void compute_chunk(WorkerItem *item) {
|
||||
char *opaque = (char *)calloc(XZ_SIZE * XZ_SIZE * Y_SIZE, sizeof(char));
|
||||
char *light = (char *)calloc(XZ_SIZE * XZ_SIZE * Y_SIZE, sizeof(char));
|
||||
char *highest = (char *)calloc(XZ_SIZE * XZ_SIZE, sizeof(char));
|
||||
|
@ -1142,7 +1133,7 @@ void compute_chunk(UpdateItem *item) {
|
|||
item->data = data;
|
||||
}
|
||||
|
||||
void generate_chunk(Chunk *chunk, UpdateItem *item) {
|
||||
void generate_chunk(Chunk *chunk, WorkerItem *item) {
|
||||
chunk->miny = item->miny;
|
||||
chunk->maxy = item->maxy;
|
||||
chunk->faces = item->faces;
|
||||
|
@ -1152,8 +1143,8 @@ void generate_chunk(Chunk *chunk, UpdateItem *item) {
|
|||
}
|
||||
|
||||
void gen_chunk_buffer(Chunk *chunk) {
|
||||
UpdateItem _item;
|
||||
UpdateItem *item = &_item;
|
||||
WorkerItem _item;
|
||||
WorkerItem *item = &_item;
|
||||
item->p = chunk->p;
|
||||
item->q = chunk->q;
|
||||
for (int dp = -1; dp <= 1; dp++) {
|
||||
|
@ -1182,7 +1173,22 @@ void map_set_func(int x, int y, int z, int w, void *arg) {
|
|||
map_set(map, x, y, z, w);
|
||||
}
|
||||
|
||||
void create_chunk(Chunk *chunk, int p, int q) {
|
||||
void load_chunk(WorkerItem *item) {
|
||||
int p = item->p;
|
||||
int q = item->q;
|
||||
Map *block_map = item->block_maps[1][1];
|
||||
Map *light_map = item->light_maps[1][1];
|
||||
create_world(p, q, map_set_func, block_map);
|
||||
db_load_blocks(block_map, p, q);
|
||||
db_load_lights(light_map, p, q);
|
||||
}
|
||||
|
||||
void request_chunk(int p, int q) {
|
||||
int key = db_get_key(p, q);
|
||||
client_chunk(p, q, key);
|
||||
}
|
||||
|
||||
void init_chunk(Chunk *chunk, int p, int q) {
|
||||
chunk->p = p;
|
||||
chunk->q = q;
|
||||
chunk->faces = 0;
|
||||
|
@ -1190,19 +1196,27 @@ void create_chunk(Chunk *chunk, int p, int q) {
|
|||
chunk->buffer = 0;
|
||||
chunk->sign_buffer = 0;
|
||||
dirty_chunk(chunk);
|
||||
//
|
||||
Map *map = &chunk->map;
|
||||
Map *lights = &chunk->lights;
|
||||
SignList *signs = &chunk->signs;
|
||||
map_alloc(map, 0x7fff);
|
||||
map_alloc(lights, 0xf);
|
||||
sign_list_alloc(signs, 16);
|
||||
create_world(p, q, map_set_func, map);
|
||||
db_load_blocks(map, p, q);
|
||||
db_load_lights(lights, p, q);
|
||||
db_load_signs(signs, p, q);
|
||||
int key = db_get_key(p, q);
|
||||
client_chunk(p, q, key);
|
||||
Map *block_map = &chunk->map;
|
||||
Map *light_map = &chunk->lights;
|
||||
map_alloc(block_map, 0x7fff);
|
||||
map_alloc(light_map, 0xf);
|
||||
}
|
||||
|
||||
void create_chunk(Chunk *chunk, int p, int q) {
|
||||
init_chunk(chunk, p, q);
|
||||
|
||||
WorkerItem _item;
|
||||
WorkerItem *item = &_item;
|
||||
item->p = chunk->p;
|
||||
item->q = chunk->q;
|
||||
item->block_maps[1][1] = &chunk->map;
|
||||
item->light_maps[1][1] = &chunk->lights;
|
||||
load_chunk(item);
|
||||
|
||||
request_chunk(p, q);
|
||||
}
|
||||
|
||||
void delete_chunks() {
|
||||
|
@ -1252,8 +1266,21 @@ void check_workers() {
|
|||
for (int i = 0; i < WORKERS; i++) {
|
||||
Worker *worker = g->workers + i;
|
||||
mtx_lock(&worker->mtx);
|
||||
if (worker->state == WORKER_UPDATED) {
|
||||
UpdateItem *item = &worker->update_item;
|
||||
if (worker->state == WORKER_DONE) {
|
||||
WorkerItem *item = &worker->item;
|
||||
Chunk *chunk = find_chunk(item->p, item->q);
|
||||
if (chunk) {
|
||||
if (item->load) {
|
||||
Map *block_map = item->block_maps[1][1];
|
||||
Map *light_map = item->light_maps[1][1];
|
||||
map_free(&chunk->map);
|
||||
map_free(&chunk->lights);
|
||||
map_copy(&chunk->map, block_map);
|
||||
map_copy(&chunk->lights, light_map);
|
||||
request_chunk(item->p, item->q);
|
||||
}
|
||||
generate_chunk(chunk, item);
|
||||
}
|
||||
for (int a = 0; a < 3; a++) {
|
||||
for (int b = 0; b < 3; b++) {
|
||||
Map *block_map = item->block_maps[a][b];
|
||||
|
@ -1268,10 +1295,6 @@ void check_workers() {
|
|||
}
|
||||
}
|
||||
}
|
||||
Chunk *chunk = find_chunk(item->p, item->q);
|
||||
if (chunk) {
|
||||
generate_chunk(chunk, item);
|
||||
}
|
||||
worker->state = WORKER_IDLE;
|
||||
}
|
||||
mtx_unlock(&worker->mtx);
|
||||
|
@ -1348,19 +1371,22 @@ void ensure_chunks_worker(Player *player, Worker *worker) {
|
|||
}
|
||||
int a = best_a;
|
||||
int b = best_b;
|
||||
int load = 0;
|
||||
Chunk *chunk = find_chunk(a, b);
|
||||
if (!chunk) {
|
||||
load = 1;
|
||||
if (g->chunk_count < MAX_CHUNKS) {
|
||||
chunk = g->chunks + g->chunk_count++;
|
||||
create_chunk(chunk, a, b);
|
||||
init_chunk(chunk, a, b);
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
UpdateItem *item = &worker->update_item;
|
||||
WorkerItem *item = &worker->item;
|
||||
item->p = chunk->p;
|
||||
item->q = chunk->q;
|
||||
item->load = load;
|
||||
for (int dp = -1; dp <= 1; dp++) {
|
||||
for (int dq = -1; dq <= 1; dq++) {
|
||||
Chunk *other = chunk;
|
||||
|
@ -1382,7 +1408,7 @@ void ensure_chunks_worker(Player *player, Worker *worker) {
|
|||
}
|
||||
}
|
||||
chunk->dirty = 0;
|
||||
worker->state = WORKER_UPDATE;
|
||||
worker->state = WORKER_BUSY;
|
||||
cnd_signal(&worker->cnd);
|
||||
}
|
||||
|
||||
|
@ -1404,14 +1430,17 @@ int worker_run(void *arg) {
|
|||
int running = 1;
|
||||
while (running) {
|
||||
mtx_lock(&worker->mtx);
|
||||
while (worker->state != WORKER_UPDATE) {
|
||||
while (worker->state != WORKER_BUSY) {
|
||||
cnd_wait(&worker->cnd, &worker->mtx);
|
||||
}
|
||||
mtx_unlock(&worker->mtx);
|
||||
UpdateItem *item = &worker->update_item;
|
||||
WorkerItem *item = &worker->item;
|
||||
if (item->load) {
|
||||
load_chunk(item);
|
||||
}
|
||||
compute_chunk(item);
|
||||
mtx_lock(&worker->mtx);
|
||||
worker->state = WORKER_UPDATED;
|
||||
worker->state = WORKER_DONE;
|
||||
mtx_unlock(&worker->mtx);
|
||||
}
|
||||
return 0;
|
||||
|
|
Loading…
Reference in New Issue