A game engine for top-down 2D RPG games.
rpg game-engine raylib c99

(temp) work on actor serialization

Changed files
+58 -33
include
keraforge
src
+3 -2
include/keraforge/actor.h
··· 2 2 #define __kf_actor__ 3 3 4 4 5 + #include "keraforge/bini.h" 5 6 #include <keraforge/_header.h> 6 7 #include <keraforge/math.h> 7 8 #include <keraforge/world.h> ··· 20 21 { 21 22 int count; 22 23 char *id[KF_MAX_ACTOR_TYPES]; 23 - u8 *(*serialize[KF_MAX_ACTOR_TYPES])(struct kf_actor *self, size_t *plen); 24 - void (*deserialize[KF_MAX_ACTOR_TYPES])(struct kf_actor *self, u8 *data, size_t len); 24 + void (*serialize[KF_MAX_ACTOR_TYPES])(struct kf_actor *self, struct bini_stream *bs); 25 + void (*deserialize[KF_MAX_ACTOR_TYPES])(struct kf_actor *self, struct bini_stream *bs); 25 26 }; 26 27 /* Global actor registry instance. */ 27 28 extern struct kf_actorregistry kf_actorregistry;
+55 -31
src/actor.c
··· 1 - #include "keraforge/fs.h" 1 + #include "keraforge/bini.h" 2 2 #include <keraforge.h> 3 3 #include <stdlib.h> 4 4 #include <raymath.h> ··· 198 198 199 199 int kf_saveactors(void) 200 200 { 201 - // char *outfile = compress ? _KF_ACTORFILE_TMP : _KF_ACTORFILE; 202 - char *outfile = _KF_ACTORFILE; 201 + size_t nactors = 0; 203 202 204 - FILE *fp = fopen(outfile, "wb"); 205 - if (!fp) 206 - KF_THROW("failed to open %s", outfile); 203 + struct bini_stream *bs = bini_new(); 207 204 208 - size_t nactors = 0; 209 - size_t total_bytes = 0; 205 + /* kf_actor_count includes unserialized actors, so we have to manually count. */ 206 + for (struct kf_actor *actor = kf_actors ; actor != NULL ; actor = actor->next) 207 + nactors++; 208 + bini_wlu(bs, nactors); 210 209 211 210 for (struct kf_actor *actor = kf_actors ; actor != NULL ; actor = actor->next) 212 211 { ··· 215 214 int id = kf_actor_getregistryid(actor->id); 216 215 if (id == -1) 217 216 continue; 218 - size_t n = strlen(actor->id); 219 - if (fwrite(actor->id, 1, n, fp) != n) 220 - { 221 - KF_THROWSOFTER("failed to write actor ID: %s", actor->id); 222 - fclose(fp); 223 - return 0; 224 - } 225 - n = 0; 226 - u8 *data = kf_actorregistry.serialize[id](actor, &n); 227 - if (!data) 228 - { 229 - KF_THROWSOFTER("failed to serialize actor of type %s", actor->id); 230 - fclose(fp); 231 - return 0; 232 - } 233 - if (fwrite(data, 1, n, fp) != n) 234 - { 235 - KF_THROWSOFTER("failed to write serialized actor of type %s", actor->id); 236 - fclose(fp); 237 - return 0; 238 - } 217 + bini_wstr(bs, actor->id); 218 + kf_actorregistry.serialize[id](actor, bs); 239 219 nactors++; 240 - total_bytes += n; 241 220 } 242 221 243 - kf_logdbg("serialized %d actors (%lu bytes)", nactors, total_bytes); 222 + kf_logdbg("serialized %d actors (%lu bytes)", nactors, bs->len); 223 + 224 + // char *outfile = compress ? _KF_ACTORFILE_TMP : _KF_ACTORFILE; 225 + char *outfile = _KF_ACTORFILE; 226 + 227 + FILE *fp = fopen(outfile, "wb"); 228 + if (!fp) 229 + KF_THROW("failed to open %s", outfile); 230 + if (fwrite(bs->buffer, bs->len, 1, fp) != bs->len) 231 + KF_THROW("failed to write actors to %s", outfile); 244 232 fclose(fp); 245 233 246 234 return 1; 247 235 } 236 + 237 + int kf_loadactors(void) 238 + { 239 + // char *infile = compress ? _KF_ACTORFILE_TMP : _KF_ACTORFILE; 240 + char *infile = _KF_ACTORFILE; 241 + 242 + size_t len = 0; 243 + struct bini_stream bs = { 244 + .mode = BINI_STREAM, 245 + .buffer = kf_readbin(infile, &len), 246 + }; 247 + if (!bs.buffer) 248 + KF_THROW("failed to read/open %s", infile); 249 + bs.cap = len; 250 + bs.len = len; 251 + kf_logdbg("loaded actors into binary stream: len=%lu", len); 252 + 253 + const size_t nactors = bini_rlu(&bs); 254 + 255 + for (size_t i = 0 ; i < nactors ; i++) 256 + { 257 + char key[4096] = {0}; 258 + bini_rstr(&bs, key); 259 + int id = kf_actor_getregistryid(key); 260 + if (id == -1) 261 + continue; 262 + kf_actorregistry.deserialize[id](actor, &bs); 263 + nactors++; 264 + } 265 + 266 + kf_logdbg("loaded %d actors", nactors); 267 + 268 + free(bs.buffer); 269 + 270 + return 1; 271 + }