Techneck/code/source-c/world/update/world_update.c

213 lines
7.4 KiB
C
Raw Normal View History

2023-10-17 20:13:54 +00:00
#include <world/update/world_update.h>
#include <world/update/internal.h>
typedef struct tc_world_registry
{
u32_t worlds_capacity;
u32_t num_worlds;
tc_world_s *worlds;
} tc_world_registry_s;
typedef struct tc_world_updater
{
bool_t running;
tc_world_updater_queue_s queue;
tc_world_registry_s world_registry;
SDL_Thread *sdl_thread;
} tc_world_updater_s;
tc_world_updater_s *tc_world_updater_g = NULL;
#define TICKS_PER_SECOND 2
#define WORLD_UPDATES_PER_SECOND 0.5
void tc_update_all_worlds(tc_world_registry_s *registry)
{
for(u32_t world_index = 0; world_index < registry->num_worlds; ++world_index)
{
tc_world_s *world = &registry->worlds[world_index];
tc_update_world(world);
}
}
void tc_world_updater_run(void *data)
{
u64_t tick_at_start = 0;
u64_t world_update_count = 0;
tc_world_updater_s *updater = data;
updater->running = TRUE;
while(updater->running)
{
tick_at_start = SDL_GetTicks();
if((tick_at_start / WORLD_UPDATES_PER_SECOND) == world_update_count)
{
++world_update_count;
}
if(tc_world_updater_g->queue.in_action)
{
while(tc_world_updater_g->queue.in_action) continue;
}
tc_world_updater_command_s command =
tc_world_updater_query_next_command(&tc_world_updater_g->queue);
switch(command.type)
{
case TC_WORLD_UPDATER_COMMAND_UNKNOWN: break;
case TC_WORLD_UPDATER_COMMAND_MOVE_CHUNKLOADER: tc_worldupdater_execute_move_chunkloader(command);
case TC_WORLD_UPDATER_COMMAND_PLACE_BLOCK: tc_worldupdater_execute_place_block(command);
case TC_WORLD_UPDATER_COMMAND_STOP: tc_worldupdater_execute_stop(command);
case TC_WORLD_UPDATER_COMMAND_ADD_WORLD: tc_worldupdater_execute_add_world(command);
case TC_WORLD_UPDATER_COMMAND_ADD_CHUNKLOADER: tc_worldupdater_execute_add_chunkloader(command);
case TC_WORLD_UPDATER_COMMAND_DELETE_CHUNKLOADER: tc_worldupdater_execute_delete_chunkloader(command);
case TC_WORLD_UPDATER_COMMAND_GET_WORLD: tc_worldupdater_execute_get_world(command);
case TC_WORLD_UPDATER_COMMAND_GET_CHUNKLOADER: tc_worldupdater_execute_get_chunkloader(command);
case TC_WORLD_UPDATER_COMMAND_GET_CHUNKLIST: tc_worldupdater_execute_get_chunklist(command);
}
u64_t tick_at_end = SDL_GetTicks();
SDL_Delay((1000 / TICKS_PER_SECOND) - (tick_at_end - tick_at_start));
}
}
tc_world_registry_s tc_new_world_registry()
{
tc_world_registry_s registry;
registry.num_worlds = 0;
registry.worlds_capacity = 64;
registry.worlds = calloc(sizeof(tc_world_s), registry.worlds_capacity);
return registry;
}
void tc_start_world_updater()
{
tc_worldupdate_initialize_promises(4096);
tc_world_updater_g = malloc(sizeof(tc_world_updater_s));
tc_world_updater_g->world_registry = tc_new_world_registry();
tc_world_updater_g->sdl_thread = SDL_CreateThread((SDL_ThreadFunction) &tc_world_updater_run, "w_update", &tc_world_updater_g);
tc_world_updater_g->queue = tc_new_world_updater_queue(4096);
SDL_DetachThread(tc_world_updater_g->sdl_thread);
}
tc_promise_s tc_worldupdate_register_world()
{
tc_promise_s promise = tc_worldupdate_reserve_world_promise();
return promise;
}
tc_promise_s tc_worldupdate_add_chunkloader()
{
tc_promise_s promise = tc_worldupdate_reserve_chunkloader_promise();
tc_world_updater_command_s command;
command.type = TC_WORLD_UPDATER_COMMAND_ADD_CHUNKLOADER;
tc_issue_world_updater_command(&tc_world_updater_g->queue, command);
return promise;
}
void tc_worldupdate_delete_chunkloader(u32_t loader_id)
{
tc_world_updater_command_s command;
command.type = TC_WORLD_UPDATER_COMMAND_DELETE_CHUNKLOADER;
command.specific.get_item.index = loader_id;
tc_issue_world_updater_command(&tc_world_updater_g->queue, command);
}
u32_t tc_worldupdate_get_chunkloader_count_of_world(u32_t world_id)
{
return 0; // TODO
}
u32_t tc_worldupdate_get_world_count()
{
return 0; // TODO
}
tc_promise_s tc_worldupdate_get_world(u32_t index)
{
tc_promise_s promise = tc_worldupdate_reserve_world_promise();
tc_world_updater_command_s command;
command.type = TC_WORLD_UPDATER_COMMAND_GET_WORLD;
command.specific.get_item.index = index;
command.specific.get_item.promise = promise.identifier;
tc_issue_world_updater_command(&tc_world_updater_g->queue, command);
return promise;
}
tc_promise_s tc_worldupdate_get_chunkloader_of_world(u32_t world_id, u32_t index)
{
tc_promise_s promise = tc_worldupdate_reserve_chunkloader_promise();
tc_world_updater_command_s command;
command.type = TC_WORLD_UPDATER_COMMAND_GET_CHUNKLOADER;
command.specific.get_item.index = index;
command.specific.get_item.promise = promise.identifier;
tc_issue_world_updater_command(&tc_world_updater_g->queue, command);
return promise;
}
tc_promise_s tc_worldupdate_get_chunks_of_chunkloader(u32_t loader_id)
{
tc_promise_s promise = tc_worldupdate_reserve_chunklist_promise();
tc_world_updater_command_s command;
command.type = TC_WORLD_UPDATER_COMMAND_GET_CHUNKLIST;
command.specific.get_item.index = loader_id;
command.specific.get_item.promise = promise.identifier;
tc_issue_world_updater_command(&tc_world_updater_g->queue, command);
return promise;
}
void tc_worldupdate_move_chunkloader_to(u32_t loader_id, tc_chunk_location_s location)
{
tc_world_updater_command_s command;
command.type = TC_WORLD_UPDATER_COMMAND_MOVE_CHUNKLOADER;
command.specific.move_chunkloader.loader_id = loader_id;
command.specific.move_chunkloader.new_location = location;
tc_issue_world_updater_command(&tc_world_updater_g->queue, command);
}
void tc_worldupdate_place_block(tc_block_location_s location, tc_block_s block)
{
tc_world_updater_command_s command;
command.type = TC_WORLD_UPDATER_COMMAND_PLACE_BLOCK;
command.specific.place_block.location = location;
command.specific.place_block.block = block;
tc_issue_world_updater_command(&tc_world_updater_g->queue, command);
}
void tc_worldupdate_stop()
{
tc_world_updater_command_s command;
command.type = TC_WORLD_UPDATER_COMMAND_STOP;
tc_issue_world_updater_command(&tc_world_updater_g->queue, command);
}