refactor message serializer to allow access to eg contacts
This commit is contained in:
parent
73d1d65142
commit
1bfd04680e
@ -19,6 +19,8 @@ target_link_libraries(fragment_store PUBLIC
|
|||||||
########################################
|
########################################
|
||||||
|
|
||||||
add_library(message_fragment_store
|
add_library(message_fragment_store
|
||||||
|
./fragment_store/message_serializer.hpp
|
||||||
|
./fragment_store/message_serializer.cpp
|
||||||
./fragment_store/message_fragment_store.hpp
|
./fragment_store/message_fragment_store.hpp
|
||||||
./fragment_store/message_fragment_store.cpp
|
./fragment_store/message_fragment_store.cpp
|
||||||
)
|
)
|
||||||
|
@ -209,7 +209,7 @@ MessageFragmentStore::MessageFragmentStore(
|
|||||||
Contact3Registry& cr,
|
Contact3Registry& cr,
|
||||||
RegistryMessageModel& rmm,
|
RegistryMessageModel& rmm,
|
||||||
FragmentStore& fs
|
FragmentStore& fs
|
||||||
) : _cr(cr), _rmm(rmm), _fs(fs) {
|
) : _cr(cr), _rmm(rmm), _fs(fs), _sc{_cr, {}, {}} {
|
||||||
_rmm.subscribe(this, RegistryMessageModel_Event::message_construct);
|
_rmm.subscribe(this, RegistryMessageModel_Event::message_construct);
|
||||||
_rmm.subscribe(this, RegistryMessageModel_Event::message_updated);
|
_rmm.subscribe(this, RegistryMessageModel_Event::message_updated);
|
||||||
_rmm.subscribe(this, RegistryMessageModel_Event::message_destroy);
|
_rmm.subscribe(this, RegistryMessageModel_Event::message_destroy);
|
||||||
@ -292,7 +292,7 @@ float MessageFragmentStore::tick(float time_delta) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
s_cb_it->second({*reg, m}, j_entry[storage.type().name()]);
|
s_cb_it->second(_sc, {*reg, m}, j_entry[storage.type().name()]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
#include "./fragment_store_i.hpp"
|
#include "./fragment_store_i.hpp"
|
||||||
#include "./fragment_store.hpp"
|
#include "./fragment_store.hpp"
|
||||||
|
|
||||||
|
#include "./message_serializer.hpp"
|
||||||
|
|
||||||
#include <entt/entity/registry.hpp>
|
#include <entt/entity/registry.hpp>
|
||||||
#include <entt/container/dense_map.hpp>
|
#include <entt/container/dense_map.hpp>
|
||||||
|
|
||||||
@ -36,10 +38,6 @@ namespace Fragment::Components {
|
|||||||
};
|
};
|
||||||
} // Fragment::Components
|
} // Fragment::Components
|
||||||
|
|
||||||
struct MessageSerializerCallbacks : public SerializerCallbacks<Message3> {
|
|
||||||
// TODO: add contact and message reg, so entities can be looked up and be converted to fragment uids OR persistent ids
|
|
||||||
};
|
|
||||||
|
|
||||||
// handles fragments for messages
|
// handles fragments for messages
|
||||||
// on new message: assign fuid
|
// on new message: assign fuid
|
||||||
// on new and update: mark as fragment dirty
|
// on new and update: mark as fragment dirty
|
||||||
|
94
src/fragment_store/message_serializer.cpp
Normal file
94
src/fragment_store/message_serializer.cpp
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
#include "./message_serializer.hpp"
|
||||||
|
|
||||||
|
#include <solanaceae/message3/components.hpp>
|
||||||
|
#include <solanaceae/contact/components.hpp>
|
||||||
|
|
||||||
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
template<>
|
||||||
|
bool MessageSerializerCallbacks::component_get_json<Message::Components::ContactFrom>(MessageSerializerCallbacks& msc, const Handle h, nlohmann::json& j) {
|
||||||
|
const Contact3 c = h.get<Message::Components::ContactFrom>().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<Contact::Components::ID>(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<Contact::Components::ID>(c).data);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
template<>
|
||||||
|
bool MessageSerializerCallbacks::component_emplace_or_replace_json<Message::Components::ContactFrom>(MessageSerializerCallbacks& msc, Handle h, const nlohmann::json& j) {
|
||||||
|
if (j.is_null()) {
|
||||||
|
std::cerr << "MSC warning: encountered null contact\n";
|
||||||
|
h.emplace_or_replace<Message::Components::ContactFrom>();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto id = static_cast<std::vector<uint8_t>>(j);
|
||||||
|
|
||||||
|
// TODO: id lookup table, this is very inefficent
|
||||||
|
for (const auto& [c_it, id_it] : msc.cr.view<Contact::Components::ID>().each()) {
|
||||||
|
if (id == id_it.data) {
|
||||||
|
h.emplace_or_replace<Message::Components::ContactFrom>(c_it);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: should we really return false if the contact is unknown??
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
bool MessageSerializerCallbacks::component_get_json<Message::Components::ContactTo>(MessageSerializerCallbacks& msc, const Handle h, nlohmann::json& j) {
|
||||||
|
const Contact3 c = h.get<Message::Components::ContactTo>().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<Contact::Components::ID>(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<Contact::Components::ID>(c).data);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
template<>
|
||||||
|
bool MessageSerializerCallbacks::component_emplace_or_replace_json<Message::Components::ContactTo>(MessageSerializerCallbacks& msc, Handle h, const nlohmann::json& j) {
|
||||||
|
if (j.is_null()) {
|
||||||
|
std::cerr << "MSC warning: encountered null contact\n";
|
||||||
|
h.emplace_or_replace<Message::Components::ContactTo>();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto id = static_cast<std::vector<uint8_t>>(j);
|
||||||
|
|
||||||
|
// TODO: id lookup table, this is very inefficent
|
||||||
|
for (const auto& [c_it, id_it] : msc.cr.view<Contact::Components::ID>().each()) {
|
||||||
|
if (id == id_it.data) {
|
||||||
|
h.emplace_or_replace<Message::Components::ContactTo>(c_it);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: should we really return false if the contact is unknown??
|
||||||
|
return false;
|
||||||
|
}
|
85
src/fragment_store/message_serializer.hpp
Normal file
85
src/fragment_store/message_serializer.hpp
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <entt/core/type_info.hpp>
|
||||||
|
#include <entt/container/dense_map.hpp>
|
||||||
|
|
||||||
|
#include <solanaceae/message3/registry_message_model.hpp>
|
||||||
|
|
||||||
|
#include <nlohmann/json_fwd.hpp>
|
||||||
|
|
||||||
|
struct MessageSerializerCallbacks {
|
||||||
|
using Registry = Message3Registry;
|
||||||
|
using Handle = Message3Handle;
|
||||||
|
|
||||||
|
Contact3Registry& cr;
|
||||||
|
|
||||||
|
// nlohmann
|
||||||
|
// json/msgpack
|
||||||
|
using serialize_json_fn = bool(*)(MessageSerializerCallbacks& msc, const Handle h, nlohmann::json& out);
|
||||||
|
entt::dense_map<entt::id_type, serialize_json_fn> _serl_json;
|
||||||
|
|
||||||
|
using deserialize_json_fn = bool(*)(MessageSerializerCallbacks& msc, Handle h, const nlohmann::json& in);
|
||||||
|
entt::dense_map<entt::id_type, deserialize_json_fn> _deserl_json;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static bool component_get_json(MessageSerializerCallbacks&, const Handle h, nlohmann::json& j) {
|
||||||
|
if (h.template all_of<T>()) {
|
||||||
|
if constexpr (!std::is_empty_v<T>) {
|
||||||
|
j = h.template get<T>();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static bool component_emplace_or_replace_json(MessageSerializerCallbacks&, Handle h, const nlohmann::json& j) {
|
||||||
|
if constexpr (std::is_empty_v<T>) {
|
||||||
|
h.template emplace_or_replace<T>(); // assert empty json?
|
||||||
|
} else {
|
||||||
|
h.template emplace_or_replace<T>(static_cast<T>(j));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void registerSerializerJson(serialize_json_fn fn, const entt::type_info& type_info) {
|
||||||
|
_serl_json[type_info.hash()] = fn;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename CompType>
|
||||||
|
void registerSerializerJson(
|
||||||
|
serialize_json_fn fn = component_get_json<CompType>,
|
||||||
|
const entt::type_info& type_info = entt::type_id<CompType>()
|
||||||
|
) {
|
||||||
|
registerSerializerJson(fn, type_info);
|
||||||
|
}
|
||||||
|
|
||||||
|
void registerDeSerializerJson(deserialize_json_fn fn, const entt::type_info& type_info) {
|
||||||
|
_deserl_json[type_info.hash()] = fn;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename CompType>
|
||||||
|
void registerDeSerializerJson(
|
||||||
|
deserialize_json_fn fn = component_emplace_or_replace_json<CompType>,
|
||||||
|
const entt::type_info& type_info = entt::type_id<CompType>()
|
||||||
|
) {
|
||||||
|
registerDeSerializerJson(fn, type_info);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// fwd
|
||||||
|
namespace Message::Components {
|
||||||
|
struct ContactFrom;
|
||||||
|
struct ContactTo;
|
||||||
|
}
|
||||||
|
|
||||||
|
// make specializations known
|
||||||
|
template<>
|
||||||
|
bool MessageSerializerCallbacks::component_get_json<Message::Components::ContactFrom>(MessageSerializerCallbacks& msc, const Handle h, nlohmann::json& j);
|
||||||
|
template<>
|
||||||
|
bool MessageSerializerCallbacks::component_emplace_or_replace_json<Message::Components::ContactFrom>(MessageSerializerCallbacks& msc, Handle h, const nlohmann::json& j);
|
||||||
|
template<>
|
||||||
|
bool MessageSerializerCallbacks::component_get_json<Message::Components::ContactTo>(MessageSerializerCallbacks& msc, const Handle h, nlohmann::json& j);
|
||||||
|
template<>
|
||||||
|
bool MessageSerializerCallbacks::component_emplace_or_replace_json<Message::Components::ContactTo>(MessageSerializerCallbacks& msc, Handle h, const nlohmann::json& j);
|
Loading…
Reference in New Issue
Block a user