more efficient entity array serialisation

This commit is contained in:
snit 2024-10-11 00:08:47 -05:00
parent 578f4446b4
commit aab6b41d18
2 changed files with 20 additions and 6 deletions

View File

@ -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", &registered_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;

View File

@ -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;