From aab6b41d181c0220c66eb01b046bb48817143171 Mon Sep 17 00:00:00 2001 From: snit Date: Fri, 11 Oct 2024 00:08:47 -0500 Subject: [PATCH] more efficient entity array serialisation --- common/src/world.c | 20 ++++++++++++++------ server/src/main.c | 6 ++++++ 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/common/src/world.c b/common/src/world.c index dd35f07..cc4335d 100644 --- a/common/src/world.c +++ b/common/src/world.c @@ -5,7 +5,7 @@ #include "world.h" -static char const *const JSON_FMT = "{so, so, sI, sI}"; +static char const *const WORLD_JSON_FMT = "{so, so, sI, sI}"; enum error_t world_init(struct world_t *self, size_t height, size_t width) { assert(self != NULL); @@ -45,13 +45,13 @@ 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]; enum error_t err = ERR_OK; struct json_t *entities_json = json_array(); for (size_t i = 0; i < MAX_ENTITIES; i++) { + if (self->entities[i].id == 0) continue; + struct json_t *maybe_entity_json; err = entity_serialise(&self->entities[i], &maybe_entity_json); if (err != ERR_OK) goto error_cleanup_array; @@ -62,7 +62,6 @@ static enum error_t serialise(struct world_t *self, struct json_t **json) { goto error_cleanup_array; } } - assert(json_array_size(entities_json) == MAX_ENTITIES); struct json_t *registered_entities_json; err = entity_registry_serialise( @@ -71,7 +70,7 @@ static enum error_t serialise(struct world_t *self, struct json_t **json) { ); if (err != ERR_OK) return err; - struct json_t *maybe_json = json_pack(JSON_FMT, + struct json_t *maybe_json = json_pack(WORLD_JSON_FMT, "entities", entities_json, "registered_entities", registered_entities_json, "height", self->height, @@ -94,7 +93,7 @@ static enum error_t deserialise(struct world_t *self, struct json_t *json) { struct json_t *entities_json; struct json_t *registered_entities_json; - int json_err = json_unpack(json, JSON_FMT, + int json_err = json_unpack(json, WORLD_JSON_FMT, "entities", &entities_json, "registered_entities", ®istered_entities_json, "height", &self->height, @@ -103,6 +102,14 @@ static enum error_t deserialise(struct world_t *self, struct json_t *json) { if (json_err < 0) return ERR_JSON_DESERIALISE; for (size_t i = 0; i < MAX_ENTITIES; i++) { + // The entity array can have gaps, but the serialisation process shifts + // all entities forwards to fill them; this zeroes out the empty space + // at the end, to ensure no "ghost" entities remain + if (i >= json_array_size(entities_json)) { + self->entities[i].id = 0; + continue; + } + struct json_t *entity_json = json_array_get(entities_json, i); if (entity_json == NULL) return ERR_JSON_DESERIALISE; @@ -156,6 +163,7 @@ 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; diff --git a/server/src/main.c b/server/src/main.c index 1d7f75f..5e70365 100644 --- a/server/src/main.c +++ b/server/src/main.c @@ -71,6 +71,12 @@ int main(int argc, char **argv) { err = world_place_entity(&data.world, 1, 3, 7); if (err) goto handle_error_world; + err = world_register_entity(&data.world, "gilbert", 'g'); + if (err) goto handle_error_world; + + entity_init(&data.world.entities[26], 2, 2, 6); + // Make a gap in the entity array to see if "ghost" entities remain + // Socket handling and run gameloop err = sock_loop(&data, game_loop); if (err) goto handle_error;