#include #include #pragma once #include "ecs.h" #include "io/write.h" #include "io/read.h" #include namespace ecs::serial { namespace internal { extern std::unordered_map, std::function, std::function>> functions; } template void serialize_member(std::ostream&, T*) { // We reached the end } template void serialize_member(std::ostream& os, T* t, M T::*m, Args... args) { io::write(os, t->*m); serialize_member(os, t, args...); } template void deserialize_member(std::istream&, T*) { // We reached the end } template void deserialize_member(std::istream& is, T* t, M T::*m, Args... args) { t->*m = io::read(is); deserialize_member(is, t, args...); } // @todo Allow for custom serializers and deserializers (maybe for this we do need a difference between update and new) template void register_component(Args... args) { // Serialize component auto func1 = [args...] (std::ostream& os, ecs::Component* component) { T* t = (T*)component; serialize_member(os, t, args...); }; // Deserialize component auto func2 = [args...] (std::istream& is, ecs::Component* component) { T* t = (T*)component; deserialize_member(is, t, args...); }; auto func3 = [] () -> Component* { return new T(); }; internal::functions.insert({ComponentID::id, {func1, func2, func3}}); } template void register_component_custom(std::function func1, std::function func2) { auto func3 = [] () -> Component* { return new T(); }; internal::functions.insert({ComponentID::id, {func1, func2, func3}}); } void serialize(std::ostream& os, Entity* entity); void deserialize(std::istream& is, Manager& manager); void serialize_ids(std::ostream& os); void deserialize_ids(std::istream& is); }