#include "./message_serializer.hpp" #include #include #include #include #include static Contact3 findContactByID(Contact3Registry& cr, const std::vector& id) { // TODO: id lookup table, this is very inefficent for (const auto& [c_it, id_it] : cr.view().each()) { if (id == id_it.data) { return c_it; } } return entt::null; } template<> bool MessageSerializerCallbacks::component_get_json(MessageSerializerCallbacks& msc, const Handle h, nlohmann::json& j) { const Contact3 c = h.get().c; if (!msc.cr.valid(c)) { // while this is invalid registry state, it is valid serialization j = nullptr; std::cerr << "MSC warning: encountered invalid contact\n"; return true; } if (!msc.cr.all_of(c)) { // unlucky, this contact is purely ephemeral j = nullptr; std::cerr << "MSC warning: encountered contact without ID\n"; return true; } j = nlohmann::json::binary(msc.cr.get(c).data); return true; } template<> bool MessageSerializerCallbacks::component_emplace_or_replace_json(MessageSerializerCallbacks& msc, Handle h, const nlohmann::json& j) { if (j.is_null()) { std::cerr << "MSC warning: encountered null contact\n"; h.emplace_or_replace(); return true; } std::vector id; if (j.is_binary()) { id = j.get_binary(); } else { j["bytes"].get_to(id); } Contact3 other_c = findContactByID(msc.cr, id); if (!msc.cr.valid(other_c)) { // create sparse contact with id only other_c = msc.cr.create(); msc.cr.emplace_or_replace(other_c, id); } h.emplace_or_replace(other_c); // TODO: should we return false if the contact is unknown?? return true; } template<> bool MessageSerializerCallbacks::component_get_json(MessageSerializerCallbacks& msc, const Handle h, nlohmann::json& j) { const Contact3 c = h.get().c; if (!msc.cr.valid(c)) { // while this is invalid registry state, it is valid serialization j = nullptr; std::cerr << "MSC warning: encountered invalid contact\n"; return true; } if (!msc.cr.all_of(c)) { // unlucky, this contact is purely ephemeral j = nullptr; std::cerr << "MSC warning: encountered contact without ID\n"; return true; } j = nlohmann::json::binary(msc.cr.get(c).data); return true; } template<> bool MessageSerializerCallbacks::component_emplace_or_replace_json(MessageSerializerCallbacks& msc, Handle h, const nlohmann::json& j) { if (j.is_null()) { std::cerr << "MSC warning: encountered null contact\n"; h.emplace_or_replace(); return true; } std::vector id; if (j.is_binary()) { id = j.get_binary(); } else { j["bytes"].get_to(id); } Contact3 other_c = findContactByID(msc.cr, id); if (!msc.cr.valid(other_c)) { // create sparse contact with id only other_c = msc.cr.create(); msc.cr.emplace_or_replace(other_c, id); } h.emplace_or_replace(other_c); // TODO: should we return false if the contact is unknown?? return true; }