#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 serialize = [args...] (std::ostream& os, ecs::Component* component) { T* t = static_cast(component); serialize_member(os, t, args...); }; // Deserialize component auto deserialize = [args...] (std::istream& is, ecs::Component* component) { T* t = static_cast(component); deserialize_member(is, t, args...); }; auto create = [] () -> Component* { return new T(); }; internal::functions.insert({ComponentID::id, {serialize, deserialize, create}}); } void register_component_custom(size_t id, std::function serialize, std::function deserialize, std::function create); 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); }