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.

main
Zed A. Shaw 2 weeks ago
parent d113dba42f
commit 71bc97a016
  1. 26
      save.cpp
  2. 20
      save.hpp
  3. 14
      tests/save.cpp

@ -7,10 +7,10 @@ using namespace components;
template<typename CompT> template<typename CompT>
inline void extract(DinkyECS::World &world, std::vector<CompT> &into) { inline void extract(DinkyECS::World &world, std::map<DinkyECS::Entity, CompT> &into) {
auto from_world = world.entity_map_for<CompT>(); auto from_world = world.entity_map_for<CompT>();
for(auto [entity, value] : from_world) { for(auto [entity, value] : from_world) {
into.push_back(std::any_cast<CompT>(value)); into[entity] = std::any_cast<CompT>(value);
} }
} }
@ -18,7 +18,8 @@ void save::to_file(std::string path, DinkyECS::World &world) {
SaveData save_data; SaveData save_data;
tser::BinaryArchive archive; tser::BinaryArchive archive;
save_data.player = world.get_the<Player>(); save_data.facts.player = world.get_the<Player>();
extract<Position>(world, save_data.position); extract<Position>(world, save_data.position);
extract<Combat>(world, save_data.combat); extract<Combat>(world, save_data.combat);
extract<Motion>(world, save_data.motion); extract<Motion>(world, save_data.motion);
@ -31,6 +32,12 @@ void save::to_file(std::string path, DinkyECS::World &world) {
out.flush(); out.flush();
} }
template<typename CompT>
inline void inject(DinkyECS::World &world, std::map<DinkyECS::Entity, CompT> &outof) {
for(auto [entity, value] : outof) {
world.set<CompT>(entity, value);
}
}
void save::from_file(std::string path, DinkyECS::World &world_out) { void save::from_file(std::string path, DinkyECS::World &world_out) {
tser::BinaryArchive archive(0); tser::BinaryArchive archive(0);
@ -51,13 +58,8 @@ void save::from_file(std::string path, DinkyECS::World &world_out) {
} }
auto save_data = archive.load<SaveData>(); auto save_data = archive.load<SaveData>();
world_out.set_the<Player>(save_data.facts.player);
// BUG: need the entities! inject<Position>(world_out, save_data.position);
world_out.set_the<Player>(save_data.player); inject<Combat>(world_out, save_data.combat);
inject<Motion>(world_out, save_data.motion);
for(auto position : save_data.position) {
auto entity = world_out.entity();
// BUG: actually do need the entities
world_out.set<Position>(entity, position);
}
} }

@ -4,16 +4,24 @@
#include "dinkyecs.hpp" #include "dinkyecs.hpp"
#include "tser.hpp" #include "tser.hpp"
#include <string> #include <string>
#include <vector> #include <map>
namespace save { namespace save {
struct SaveData {
struct Facts {
components::Player player; components::Player player;
std::vector<components::Position> position;
std::vector<components::Motion> motion;
std::vector<components::Combat> combat;
DEFINE_SERIALIZABLE(SaveData, player, position, motion, combat); DEFINE_SERIALIZABLE(Facts, player);
};
struct SaveData {
Facts facts;
std::map<DinkyECS::Entity, components::Position> position;
std::map<DinkyECS::Entity, components::Motion> motion;
std::map<DinkyECS::Entity, components::Combat> combat;
DEFINE_SERIALIZABLE(SaveData, facts, position, motion, combat);
}; };
void to_file(std::string path, DinkyECS::World &world); void to_file(std::string path, DinkyECS::World &world);

@ -70,11 +70,15 @@ TEST_CASE("basic save a world", "[save]") {
Position &position1 = world.get<Position>(player.entity); Position &position1 = world.get<Position>(player.entity);
Position &position2 = in_world.get<Position>(player.entity); Position &position2 = in_world.get<Position>(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.x == position2.location.x);
REQUIRE(position1.location.y == position2.location.y); REQUIRE(position1.location.y == position2.location.y);
Combat &combat1 = in_world.get<Combat>(player.entity);
Combat &combat2 = in_world.get<Combat>(player.entity);
REQUIRE(combat1.hp == combat2.hp);
Motion &motion1 = in_world.get<Motion>(player.entity);
Motion &motion2 = in_world.get<Motion>(player.entity);
REQUIRE(motion1.dx == motion2.dx);
REQUIRE(motion1.dy == motion2.dy);
} }

Loading…
Cancel
Save