From 71bc97a016ce87d941113cd59c1679361fec7796 Mon Sep 17 00:00:00 2001 From: "Zed A. Shaw" Date: Tue, 5 Nov 2024 06:11:50 -0500 Subject: [PATCH] Save system should work better now, just needed to switch to basic map. This would probably a lot better if tser.hpp supported std::any. --- save.cpp | 26 ++++++++++++++------------ save.hpp | 20 ++++++++++++++------ tests/save.cpp | 14 +++++++++----- 3 files changed, 37 insertions(+), 23 deletions(-) diff --git a/save.cpp b/save.cpp index 175a46c..59be989 100644 --- a/save.cpp +++ b/save.cpp @@ -7,10 +7,10 @@ using namespace components; template -inline void extract(DinkyECS::World &world, std::vector &into) { +inline void extract(DinkyECS::World &world, std::map &into) { auto from_world = world.entity_map_for(); for(auto [entity, value] : from_world) { - into.push_back(std::any_cast(value)); + into[entity] = std::any_cast(value); } } @@ -18,7 +18,8 @@ void save::to_file(std::string path, DinkyECS::World &world) { SaveData save_data; tser::BinaryArchive archive; - save_data.player = world.get_the(); + save_data.facts.player = world.get_the(); + extract(world, save_data.position); extract(world, save_data.combat); extract(world, save_data.motion); @@ -31,6 +32,12 @@ void save::to_file(std::string path, DinkyECS::World &world) { out.flush(); } +template +inline void inject(DinkyECS::World &world, std::map &outof) { + for(auto [entity, value] : outof) { + world.set(entity, value); + } +} void save::from_file(std::string path, DinkyECS::World &world_out) { tser::BinaryArchive archive(0); @@ -51,13 +58,8 @@ void save::from_file(std::string path, DinkyECS::World &world_out) { } auto save_data = archive.load(); - - // BUG: need the entities! - world_out.set_the(save_data.player); - - for(auto position : save_data.position) { - auto entity = world_out.entity(); - // BUG: actually do need the entities - world_out.set(entity, position); - } + world_out.set_the(save_data.facts.player); + inject(world_out, save_data.position); + inject(world_out, save_data.combat); + inject(world_out, save_data.motion); } diff --git a/save.hpp b/save.hpp index 6eedef0..93b9d9f 100644 --- a/save.hpp +++ b/save.hpp @@ -4,16 +4,24 @@ #include "dinkyecs.hpp" #include "tser.hpp" #include -#include +#include namespace save { - struct SaveData { + + struct Facts { components::Player player; - std::vector position; - std::vector motion; - std::vector combat; - DEFINE_SERIALIZABLE(SaveData, player, position, motion, combat); + DEFINE_SERIALIZABLE(Facts, player); + }; + + struct SaveData { + Facts facts; + + std::map position; + std::map motion; + std::map combat; + + DEFINE_SERIALIZABLE(SaveData, facts, position, motion, combat); }; void to_file(std::string path, DinkyECS::World &world); diff --git a/tests/save.cpp b/tests/save.cpp index 20c29c3..ade0541 100644 --- a/tests/save.cpp +++ b/tests/save.cpp @@ -70,11 +70,15 @@ TEST_CASE("basic save a world", "[save]") { Position &position1 = world.get(player.entity); Position &position2 = in_world.get(player.entity); - - // BUGGGGGGGG! This doesn't actually work, it's all fake - // The world uses an internal id to increment entities so - // by default player gets the first one, but all data after - // that is wrong. REQUIRE(position1.location.x == position2.location.x); REQUIRE(position1.location.y == position2.location.y); + + Combat &combat1 = in_world.get(player.entity); + Combat &combat2 = in_world.get(player.entity); + REQUIRE(combat1.hp == combat2.hp); + + Motion &motion1 = in_world.get(player.entity); + Motion &motion2 = in_world.get(player.entity); + REQUIRE(motion1.dx == motion2.dx); + REQUIRE(motion1.dy == motion2.dy); }