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.
This commit is contained in:
parent
d113dba42f
commit
71bc97a016
3 changed files with 38 additions and 24 deletions
26
save.cpp
26
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
22
save.hpp
22
save.hpp
|
@ -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 {
|
|
||||||
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);
|
struct Facts {
|
||||||
|
components::Player player;
|
||||||
|
|
||||||
|
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…
Add table
Add a link
Reference in a new issue