diff --git a/client/src/main.c b/client/src/main.c index 37c6b71..5334883 100644 --- a/client/src/main.c +++ b/client/src/main.c @@ -16,29 +16,28 @@ int main(void) { if (err) goto handle_error; char ibuf[1024] = { 0 }; - char obuf[1024] = { 0 }; - - // TODO: I skipped out on most error handling here read(sock, ibuf, 1024); - struct json_error_t json_err; - struct json_t *json = json_loads(ibuf, 0, &json_err); - struct world_t world = { 0 }; - world_deserialise(&world, json); + err = world_deserialise(&world, ibuf); + if (err != ERR_OK) goto handle_error_sock; - printf("CLIENT: (%zu %zu)\n", world.height, world.width); + printf("CLIENT: (%zu %zu) ->", world.height++, world.width ++); + printf(" (%zu %zu)\n", world.height, world.width); - struct json_t *new_json; - world_serialise(&world, &new_json); + char obuf[1024] = { 0 }; + err = world_serialise_buf(&world, obuf, 1024); + if (err != ERR_OK) goto handle_error_sock; - json_dumpb(new_json, obuf, 1024, 0); write(sock, obuf, 1024); close(sock); return ERR_OK; +handle_error_sock: + close(sock); + handle_error: - printf("ERROR: %s\n", ERROR_STRS[err]); + printf("CLIENT ERROR: %s\n", ERROR_STRS[err]); return err; } diff --git a/common/include/world.h b/common/include/world.h index 7d2222b..70847d1 100644 --- a/common/include/world.h +++ b/common/include/world.h @@ -22,19 +22,11 @@ struct world_t { enum error_t world_init(struct world_t *, size_t, size_t); void world_free(struct world_t *); -// json_t doesn't store the json data itself; the value of the pointer is -// apparently needed for jansson to use the data, so I need a double pointer -// -// TODO -// Right now, to serialise and deserialise again you have to call: -// 1. world_serialise() | world_t -> json_t -// 2. json_dumpX() | json_t -> char * -// 3. json_loadX() | char * -> json_t -// 4. world_deserialise() | json_t -> world_t -// -// Perhaps these two functions should go directly between world_t and char * -enum error_t world_serialise(struct world_t *, struct json_t **); -enum error_t world_deserialise(struct world_t *, struct json_t *); +// world_*_str() allocates a string that the caller must free() +// world_*_buf() uses a pre-existing buffer; results are not zero-terminated +enum error_t world_serialise_str(struct world_t *, char const **); +enum error_t world_serialise_buf(struct world_t *, char *, size_t); +enum error_t world_deserialise(struct world_t *, char const *); enum error_t world_register_entity(struct world_t *, char const *, char); enum error_t world_place_entity(struct world_t *, size_t, size_t, size_t); diff --git a/common/src/world.c b/common/src/world.c index 2880279..13eeb75 100644 --- a/common/src/world.c +++ b/common/src/world.c @@ -40,7 +40,7 @@ void world_free(struct world_t *self) { } -enum error_t world_serialise(struct world_t *self, struct json_t **json) { +static enum error_t serialise(struct world_t *self, struct json_t **json) { assert(self != NULL); // TODO: (de)serialise the following: // struct entity_t entities[MAX_ENTITIES]; @@ -57,7 +57,23 @@ enum error_t world_serialise(struct world_t *self, struct json_t **json) { } -enum error_t world_deserialise(struct world_t *self, struct json_t *json) { +enum error_t world_serialise_str(struct world_t *self, char const **strptr) { + assert(self != NULL); + assert(strptr != NULL); + + struct json_t *json; + enum error_t err = serialise(self, &json); + if (err != ERR_OK) return ERR_JSON_SERIALISE; + + const char *str = json_dumps(json, 0); + if (str == NULL) return ERR_JSON_SERIALISE; + + *strptr = str; + return ERR_OK; +} + + +static enum error_t deserialise(struct world_t *self, struct json_t *json) { assert(self != NULL); assert(json != NULL); @@ -71,6 +87,36 @@ enum error_t world_deserialise(struct world_t *self, struct json_t *json) { } +enum error_t world_serialise_buf(struct world_t *self, char *buf, size_t len) { + assert(self != NULL); + assert(buf != NULL); + assert(len > 0); + + struct json_t *json; + enum error_t err = serialise(self, &json); + if (err != ERR_OK) return ERR_JSON_SERIALISE; + + size_t bytes_written = json_dumpb(json, buf, len, 0); + if (bytes_written == 0) return ERR_JSON_SERIALISE; + + return ERR_OK; +} + + +enum error_t world_deserialise(struct world_t *self, char const *str) { + assert(self != NULL); + assert(str != NULL); + + struct json_t *json = json_loads(str, 0, NULL); + if (json == NULL) return ERR_JSON_DESERIALISE; + + enum error_t err = deserialise(self, json); + if (err != ERR_OK) return ERR_JSON_DESERIALISE; + + return ERR_OK; +} + + enum error_t world_register_entity( struct world_t *self, char const *name, char tile diff --git a/run.sh b/run.sh new file mode 100755 index 0000000..ab5a5ef --- /dev/null +++ b/run.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +./build.sh + +echo "### DAEMON ###" +./build/server/simworld-daemon & +sleep 1 + +echo "### CLIENT 1 ###" +./build/client/simworld-client + +echo "### CLIENT 2 ###" +./build/client/simworld-client + +killall simworld-daemon diff --git a/server/src/main.c b/server/src/main.c index c6c8c87..1acdbdc 100644 --- a/server/src/main.c +++ b/server/src/main.c @@ -22,33 +22,25 @@ static void handle_signal(int signal_no) { } -#define LOGMSG(options, fmt, ...) \ - ((options)->daemonise ? \ - syslog(LOG_NOTICE, (fmt), __VA_ARGS__) : \ - (void)printf((fmt), __VA_ARGS__)) - - enum error_t game_loop(struct data_t *data) { enum error_t err = ERR_OK; - char obuf[1024] = { 0 }; - char ibuf[1024] = { 0 }; - // TODO: I skipped out on most error handling here - struct json_t *json; - err = world_serialise(&data->world, &json); + char obuf[1024] = { 0 }; + err = world_serialise_buf(&data->world, obuf, 1024); if (err != ERR_OK) return err; - json_dumpb(json, obuf, 1024, 0); write(data->socket_accept, obuf, 1024); + char ibuf[1024] = { 0 }; read(data->socket_accept, ibuf, 1024); - json = json_loads(ibuf, 0, NULL); - struct world_t returned_world; - world_deserialise(&returned_world, json); - LOGMSG(&data->options, "SERVER: (%zu %zu) -> (%zu %zu)\n", - data->world.height, data->world.width, - returned_world.height, returned_world.width + struct world_t old_world = data->world; + err = world_deserialise(&data->world, ibuf); + if (err != ERR_OK) return ERR_OK; + + printf("SERVER: (%zu %zu) -> (%zu %zu)\n", + old_world.height, old_world.width, + data->world.height, data->world.width ); return ERR_OK; @@ -100,6 +92,6 @@ handle_error: opts_free(&data.options); handle_error_pre_opts: - printf("ERROR: %s\n", ERROR_STRS[err]); + printf("SERVER ERROR: %s\n", ERROR_STRS[err]); return err; }