entity registr{ant,y} (de)serialisation

This commit is contained in:
snit 2024-10-10 23:07:43 -05:00
parent 3efa5479f2
commit 9ec7f392c7
4 changed files with 159 additions and 21 deletions

View File

@ -3,6 +3,8 @@
#include <stdlib.h> #include <stdlib.h>
#include <jansson.h>
#include "error.h" #include "error.h"
struct entity_registrant_t { struct entity_registrant_t {
@ -27,6 +29,16 @@ struct entity_registry_t {
enum error_t entity_registry_init(struct entity_registry_t *); enum error_t entity_registry_init(struct entity_registry_t *);
void entity_registry_free(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( enum error_t entity_registry_append(
struct entity_registry_t *, struct entity_registry_t *,
struct entity_registrant_t const * struct entity_registrant_t const *

View File

@ -9,6 +9,10 @@
#define MAX_NAME_LENGTH 32 #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( enum error_t entity_registrant_init(
struct entity_registrant_t *self, struct entity_registrant_t *self,
char const *name, char tile 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) { enum error_t entity_registry_init(struct entity_registry_t *self) {
assert(self != NULL); 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( enum error_t entity_registry_append(
struct entity_registry_t *self, struct entity_registry_t *self,
struct entity_registrant_t const *registrant struct entity_registrant_t const *registrant

View File

@ -5,6 +5,8 @@
#include "world.h" #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) { enum error_t world_init(struct world_t *self, size_t height, size_t width) {
assert(self != NULL); 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) { static enum error_t serialise(struct world_t *self, struct json_t **json) {
assert(self != NULL); assert(self != NULL);
assert(json != NULL);
// TODO: (de)serialise the following: // TODO: (de)serialise the following:
// struct entity_t entities[MAX_ENTITIES]; // struct entity_t entities[MAX_ENTITIES];
// struct entity_registry_t registered_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,
&registered_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, "height", self->height,
"width", self->width "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", &registered_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) { enum error_t world_serialise_str(struct world_t *self, char const **strptr) {
assert(self != NULL); assert(self != NULL);
assert(strptr != 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) { enum error_t world_serialise_buf(struct world_t *self, char *buf, size_t len) {
assert(self != NULL); assert(self != NULL);
assert(buf != NULL); assert(buf != NULL);

View File

@ -34,14 +34,10 @@ enum error_t game_loop(struct data_t *data) {
char ibuf[1024] = { 0 }; char ibuf[1024] = { 0 };
read(data->socket_accept, ibuf, 1024); read(data->socket_accept, ibuf, 1024);
struct world_t old_world = data->world;
err = world_deserialise(&data->world, ibuf); 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", printf("SERVER: \"%s\" -> \"%s\"\n", obuf, ibuf);
old_world.height, old_world.width,
data->world.height, data->world.width
);
return ERR_OK; return ERR_OK;
} }