diff --git a/common/include/entity/registry.h b/common/include/entity/registry.h index 55972bb..6a885b4 100644 --- a/common/include/entity/registry.h +++ b/common/include/entity/registry.h @@ -3,6 +3,8 @@ #include +#include + #include "error.h" struct entity_registrant_t { @@ -27,6 +29,16 @@ struct entity_registry_t { enum error_t entity_registry_init(struct entity_registry_t *); void entity_registry_free(struct entity_registry_t *); +enum error_t entity_registry_serialise( + struct entity_registry_t const *, + struct json_t ** +); + +enum error_t entity_registry_deserialise( + struct entity_registry_t *, + struct json_t * +); + enum error_t entity_registry_append( struct entity_registry_t *, struct entity_registrant_t const * diff --git a/common/src/entity/registry.c b/common/src/entity/registry.c index 9f3733e..fc31e11 100644 --- a/common/src/entity/registry.c +++ b/common/src/entity/registry.c @@ -9,6 +9,10 @@ #define MAX_NAME_LENGTH 32 +static char const* const ENTITY_REGISTRANT_JSON_FMT = "{ss,si}"; +static char const* const ENTITY_REGISTRY_JSON_FMT = "{so,sI}"; + + enum error_t entity_registrant_init( struct entity_registrant_t *self, char const *name, char tile @@ -36,6 +40,40 @@ void entity_registrant_free(struct entity_registrant_t *self) { } +static enum error_t registrant_serialise( + struct entity_registrant_t const *self, + struct json_t **json +) { + assert(self != NULL); + assert(json != NULL); + + struct json_t *maybe_json = json_pack(ENTITY_REGISTRANT_JSON_FMT, + "name", self->name, + "tile", self->tile + ); + if (maybe_json == NULL) return ERR_JSON_SERIALISE; + + *json = maybe_json; + return ERR_OK; +} + +static enum error_t registrant_deserialise( + struct entity_registrant_t *self, + struct json_t *json +) { + assert(self != NULL); + assert(json != NULL); + + int err = json_unpack(json, ENTITY_REGISTRANT_JSON_FMT, + "name", &self->name, + "tile", &self->tile + ); + if (err < 0) return ERR_JSON_DESERIALISE; + + return ERR_OK; +} + + enum error_t entity_registry_init(struct entity_registry_t *self) { assert(self != NULL); @@ -62,6 +100,79 @@ void entity_registry_free(struct entity_registry_t *self) { } +enum error_t entity_registry_serialise( + struct entity_registry_t const *self, + struct json_t **json +) { + assert(self != NULL); + assert(json != NULL); + + enum error_t err = ERR_OK; + + struct json_t *entities_json = json_array(); + for (size_t i = 0; i < self->size; i++) { + struct json_t *maybe_entity_json; + err = registrant_serialise(&self->entities[i], &maybe_entity_json); + if (err != ERR_OK) goto error_cleanup_array; + + int json_err = json_array_append_new(entities_json, maybe_entity_json); + if (json_err < 0) goto error_cleanup_array; + } + assert(json_array_size(entities_json) == self->size); + + struct json_t *maybe_json = json_pack(ENTITY_REGISTRY_JSON_FMT, + "entities", entities_json, + "size", self->size + ); + if (maybe_json == NULL) goto error_cleanup_array; + + *json = maybe_json; + return ERR_OK; + +error_cleanup_array: + json_array_clear(entities_json); + return err; +} + + +enum error_t entity_registry_deserialise( + struct entity_registry_t *self, + struct json_t *json +) { + assert(self != NULL); + assert(json != NULL); + + enum error_t err = ERR_OK; + + struct json_t *entities_json = NULL; + int json_err = json_unpack(json, ENTITY_REGISTRY_JSON_FMT, + "entities", &entities_json, + "size", &self->size + ); + if (json_err < 0) return ERR_JSON_DESERIALISE; + + struct entity_registrant_t *entities = calloc( + self->size, sizeof(struct entity_registrant_t) + ); + if (entities == NULL) goto error_cleanup_entities; + + for (size_t i = 0; i < json_array_size(entities_json); i++) { + struct json_t *entity_json = json_array_get(entities_json, i); + if (entity_json == NULL) goto error_cleanup_entities; + + err = registrant_deserialise(&entities[i], entity_json); + if (err != ERR_OK) goto error_cleanup_entities; + } + + self->entities = entities; + return ERR_OK; + +error_cleanup_entities: + free(entities); + return ERR_JSON_DESERIALISE; +} + + enum error_t entity_registry_append( struct entity_registry_t *self, struct entity_registrant_t const *registrant diff --git a/common/src/world.c b/common/src/world.c index 13eeb75..ee702d6 100644 --- a/common/src/world.c +++ b/common/src/world.c @@ -5,6 +5,8 @@ #include "world.h" +static char const *const JSON_FMT = "{so, sI, sI}"; + enum error_t world_init(struct world_t *self, size_t height, size_t width) { assert(self != NULL); @@ -42,11 +44,20 @@ void world_free(struct world_t *self) { static enum error_t serialise(struct world_t *self, struct json_t **json) { assert(self != NULL); + assert(json != NULL); // TODO: (de)serialise the following: // struct entity_t entities[MAX_ENTITIES]; // struct entity_registry_t registered_entities; - struct json_t *maybe_json = json_pack("{s:I,s:I}", + struct json_t *registered_entities_json; + enum error_t err = entity_registry_serialise( + &self->registered_entities, + ®istered_entities_json + ); + if (err != ERR_OK) return err; + + struct json_t *maybe_json = json_pack(JSON_FMT, + "registered_entities", registered_entities_json, "height", self->height, "width", self->width ); @@ -57,6 +68,28 @@ static enum error_t serialise(struct world_t *self, struct json_t **json) { } +static enum error_t deserialise(struct world_t *self, struct json_t *json) { + assert(self != NULL); + assert(json != NULL); + + struct json_t *registered_entities_json; + int json_err = json_unpack(json, JSON_FMT, + "registered_entities", ®istered_entities_json, + "height", &self->height, + "width", &self->width + ); + if (json_err < 0) return ERR_JSON_DESERIALISE; + + enum error_t err = entity_registry_deserialise( + &self->registered_entities, + registered_entities_json + ); + if (err != ERR_OK) return err; + + return ERR_OK; +} + + enum error_t world_serialise_str(struct world_t *self, char const **strptr) { assert(self != NULL); assert(strptr != NULL); @@ -73,20 +106,6 @@ enum error_t world_serialise_str(struct world_t *self, char const **strptr) { } -static enum error_t deserialise(struct world_t *self, struct json_t *json) { - assert(self != NULL); - assert(json != NULL); - - int err = json_unpack(json, "{s:I,s:I}", - "height", &self->height, - "width", &self->width - ); - if (err < 0) return ERR_JSON_DESERIALISE; - - return ERR_OK; -} - - enum error_t world_serialise_buf(struct world_t *self, char *buf, size_t len) { assert(self != NULL); assert(buf != NULL); diff --git a/server/src/main.c b/server/src/main.c index 1acdbdc..66138e5 100644 --- a/server/src/main.c +++ b/server/src/main.c @@ -34,14 +34,10 @@ enum error_t game_loop(struct data_t *data) { char ibuf[1024] = { 0 }; read(data->socket_accept, ibuf, 1024); - struct world_t old_world = data->world; err = world_deserialise(&data->world, ibuf); - if (err != ERR_OK) return ERR_OK; + if (err != ERR_OK) return err; - printf("SERVER: (%zu %zu) -> (%zu %zu)\n", - old_world.height, old_world.width, - data->world.height, data->world.width - ); + printf("SERVER: \"%s\" -> \"%s\"\n", obuf, ibuf); return ERR_OK; }