int worker_manager(void *data) { for(;;) { int i,j,k; waiter_wait(&manager_monitor); SDL_LockMutex(finished_gen.mutex); while (finished_gen.head != finished_gen.tail) { int h = finished_gen.head; end_procgen(gen_queue[h].world_x, gen_queue[h].world_y); put_chunk_in_cache(gen_queue[h].world_x, gen_queue[h].world_y, gen_queue[h].gc); finished_gen.head = (h+1) % finished_gen.length; } SDL_UnlockMutex(finished_gen.mutex); SDL_LockMutex(requested_mesh_mutex); for (i=0; i < MAX_BUILT_MESHES; ++i) { requested_mesh *rm = &renderer_requested_meshes[i]; if (rm->state == RMS_requested) { int valid_chunks=0; for (k=0; k < 4; ++k) { for (j=0; j < 4; ++j) { if (!rm->chunk_set_valid[k][j]) { int cx = rm->x + j * GEN_CHUNK_SIZE_X, cy = rm->y + k * GEN_CHUNK_SIZE_Y; gen_chunk_cache *gcc = get_gen_chunk_cache_for_coord(cx, cy); if (gcc) { rm->cs.chunk[k][j] = gcc->chunk; } else if (is_in_progress(cx, cy)) { // it's already in progress, so do nothing } else if (can_start_procgen(cx, cy)) { task t; start_procgen(cx,cy); t.world_x = cx; t.world_y = cy; t.task_type = JOB_generate_terrain; add_task(&t); } } else { ++valid_chunks; } } } if (valid_chunks == 16) { task t; t.cs = rm->cs; assert(rm->state == RMS_requested); rm->state = RMS_chunks_completed_waiting_for_meshing; t.task_type = JOB_build_mesh; t.world_x = rm->x; t.world_y = rm->y; add_task(&t); } } } SDL_UnlockMutex(requested_mesh_mutex); } }
gen_chunk *get_gen_chunk_for_coord(int x, int y) { gen_chunk_cache *gcc = get_gen_chunk_cache_for_coord(x,y); if (gcc == NULL) { gcc = put_chunk_in_cache(x, y, generate_chunk(x, y)); } assert(gcc->chunk_x*GEN_CHUNK_SIZE_X == x && gcc->chunk_y*GEN_CHUNK_SIZE_Y == y); return gcc->chunk; }