diff --git a/common/include/error.h b/common/include/error.h index 7a231a1..3201608 100644 --- a/common/include/error.h +++ b/common/include/error.h @@ -1,6 +1,10 @@ #ifndef ERROR_H #define ERROR_H +// TODO: Most of these aren't even errors used in this library. +// I should trim this down to only the ones belonging to the library, and make +// new enums for the client and server. Perhaps I can leverage __ERR_COUNT to +// have the client/server-specific enums start where this one ends enum error_t { ERR_OK, ERR_INPUT, @@ -14,6 +18,7 @@ enum error_t { ERR_INVALID_REQUEST, ERR_REQUEST_FAILED, ERR_THREAD, + ERR_MUTEX, __ERR_COUNT, }; diff --git a/common/src/error.c b/common/src/error.c index 988768d..5a77a82 100644 --- a/common/src/error.c +++ b/common/src/error.c @@ -14,7 +14,8 @@ char const *const ERROR_STRS[] = { "JSON DESERIALISATION", "INVALID REQUEST", "REQUEST FAILED", - "THREAD INITIALISATION" + "THREAD INITIALISATION", + "MUTEX ERROR", }; diff --git a/server/src/main.c b/server/src/main.c index 8cd5ad0..db985ba 100644 --- a/server/src/main.c +++ b/server/src/main.c @@ -1,5 +1,6 @@ // main.c +#include #include #include #include @@ -23,6 +24,34 @@ static void handle_signal(int signal_no) { } +static enum error_t simulation_thread_body(struct game_data_t *data) { + assert(data != NULL); + + // TODO: An actual game loop lol + printf("Hello, world!\n"); + + return ERR_OK; +} + + + +static enum error_t simulation_thread( + pthread_t *pthread, + struct game_data_t *data +) { + assert(pthread != NULL); + assert(data != NULL); + + int err = pthread_create( + pthread, NULL, + (void *(*)(void *))simulation_thread_body, data + ); + if (err != 0) return ERR_THREAD; + + return ERR_OK; +} + + int main(int argc, char **argv) { // Set up variables enum error_t err = ERR_OK; @@ -60,11 +89,18 @@ int main(int argc, char **argv) { entity_init(&data.world.entities[26], 2, 2, 6); // Make a gap in the entity array to see if "ghost" entities remain - // Socket handling + // Socket handler thread pthread_t pthread_socket; err = socket_thread(&pthread_socket, &data); if (err) goto handle_error; + // Simulation thread + pthread_t pthread_simulation; + err = simulation_thread(&pthread_simulation, &data); + if (err) goto handle_error; + + // Join threads + // TODO: A way to shut down the program properly pthread_join(pthread_socket, (void **)&err); // No way this is correct lol if (err) goto handle_error; diff --git a/server/src/request.c b/server/src/request.c index d0f1c08..c5865a6 100644 --- a/server/src/request.c +++ b/server/src/request.c @@ -4,10 +4,18 @@ #include "request.h" +static struct response_t response_failure( + struct request_t const *request +) { + assert(request != NULL); + + return (struct response_t){ request->type, false, NULL }; +} + static void handle_request_get_world_data( struct response_t *response, struct request_t const *request, - struct game_data_t const *ctx + struct game_data_t *ctx ) { assert(response != NULL); assert(request != NULL); @@ -16,11 +24,24 @@ static void handle_request_get_world_data( // TODO: World creation isn't set up yet, so the world-id parameter isn't // useful right now, but make sure to use it later when it is set up - struct response_body_get_world_data_t *body = response->body; + struct response_body_get_world_data_t *body = + malloc(sizeof(struct response_body_get_world_data_t)); + if (body == NULL) goto error; + + response->body = body; + + if (pthread_mutex_lock(&ctx->world_lock) != 0) goto error; body->world = ctx->world; + if (pthread_mutex_unlock(&ctx->world_lock) != 0) goto error; response->type = request->type; response->success = true; + + return; + +error: + free(body); + *response = response_failure(request); } @@ -35,14 +56,10 @@ struct response_t handle_request( switch (request->type) { case REQUEST_GET_WORLD_DATA: - response.body = malloc(sizeof(struct response_body_get_world_data_t)); - if (response.body == NULL) - return (struct response_t){ request->type, false, NULL }; - handle_request_get_world_data(&response, request, ctx); return response; default: - return (struct response_t){ 0 }; + return response_failure(request); } } diff --git a/server/src/socket.c b/server/src/socket.c index e35d98b..4f19476 100644 --- a/server/src/socket.c +++ b/server/src/socket.c @@ -67,14 +67,12 @@ static enum error_t socket_handle(struct game_data_t *data) { } -static void *socket_thread_body(void *data_void) { - assert(data_void != NULL); - - struct game_data_t *data = (struct game_data_t *)data_void; +static enum error_t socket_thread_body(struct game_data_t *data) { + assert(data != NULL); enum error_t err = ERR_OK; - if ((err = socket_init(&data->socket))) return (void *)err; + if ((err = socket_init(&data->socket))) return err; for (int sock_accept;;) { if ((sock_accept = accept(data->socket, NULL, NULL)) < 0) { @@ -95,12 +93,19 @@ error_pre: error: socket_free(&data->socket); - return (void *)err; + return err; } enum error_t socket_thread(pthread_t *pthread, struct game_data_t *data) { - int err = pthread_create(pthread, NULL, socket_thread_body, data); + assert(pthread != NULL); + assert(data != NULL); + + int err = pthread_create( + pthread, NULL, + (void *(*)(void *))socket_thread_body, // I want to cry tf is this + data + ); if (err != 0) return ERR_THREAD; return ERR_OK;