213 lines
7.4 KiB
C
213 lines
7.4 KiB
C
#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 = ®istry->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);
|
|
}
|
|
|