Objects are sent with correct IDs over network

This commit is contained in:
Yousef Khadadeh 2025-12-08 22:21:07 +03:00
parent d9a90dda16
commit c51b7e7eb1
6 changed files with 51 additions and 31 deletions

View file

@ -7,10 +7,8 @@ namespace NetworkingObjects {
.writeConstructorFuncClient = [](const NetObjPtr<T>& o, cereal::PortableBinaryOutputArchive& a) {
a(*o);
},
.readConstructorFuncClient = [](NetObjManager& m, cereal::PortableBinaryInputArchive& a, const std::shared_ptr<NetServer::ClientData>&) {
NetObjPtr<T> o = m.make_obj<T>();
.readConstructorFuncClient = [](const NetObjPtr<T>& o, cereal::PortableBinaryInputArchive& a, const std::shared_ptr<NetServer::ClientData>&) {
a(*o);
return o.template cast<void>();
},
.readUpdateFuncClient = [](const NetObjPtr<T>& o, cereal::PortableBinaryInputArchive& a, const std::shared_ptr<NetServer::ClientData>&) {
a(*o);
@ -18,10 +16,8 @@ namespace NetworkingObjects {
.writeConstructorFuncServer = [](const NetObjPtr<T>& o, cereal::PortableBinaryOutputArchive& a) {
a(*o);
},
.readConstructorFuncServer = [](NetObjManager& m, cereal::PortableBinaryInputArchive& a, const std::shared_ptr<NetServer::ClientData>&) {
NetObjPtr<T> o = m.make_obj<T>();
.readConstructorFuncServer = [](const NetObjPtr<T>& o, cereal::PortableBinaryInputArchive& a, const std::shared_ptr<NetServer::ClientData>&) {
a(*o);
return o.template cast<void>();
},
.readUpdateFuncServer = [](const NetObjPtr<T>& o, cereal::PortableBinaryInputArchive& a, const std::shared_ptr<NetServer::ClientData>&) {
a(*o);

View file

@ -28,10 +28,12 @@ namespace NetworkingObjects {
NetTypeIDType typeID;
a(id, typeID);
auto& netTypeIDData = typeList->netTypeIDData[typeID];
NetObjPtr<T> newPtr = make_obj_with_id<T>(id);
if(isServer)
return netTypeIDData.readConstructorFuncServer(*this, a, clientReceivedFrom).cast<T>();
netTypeIDData.readConstructorFuncServer(newPtr.template cast<void>(), a, clientReceivedFrom);
else
return netTypeIDData.readConstructorFuncClient(*this, a, clientReceivedFrom).cast<T>();
netTypeIDData.readConstructorFuncClient(newPtr.template cast<void>(), a, clientReceivedFrom);
return newPtr;
}
template <typename T> NetObjPtr<T> read_get_obj_from_message(cereal::PortableBinaryInputArchive& a) {
NetObjID id;
@ -70,6 +72,13 @@ namespace NetworkingObjects {
return NetObjPtr<T>(this, id, std::static_pointer_cast<T>(it->second.p));
}
private:
template <typename T> NetObjPtr<T> make_obj_with_id(NetObjID id) {
auto sharedPtr = std::static_pointer_cast<T>(isServer ? typeList->typeIndexDataServer[std::type_index(typeid(T*))].allocatorFunc() : typeList->typeIndexDataClient[std::type_index(typeid(T*))].allocatorFunc());
if(!objectData.emplace(id, SingleObjectData{.netTypeID = isServer ? typeList->typeIndexDataServer[std::type_index(typeid(T*))].netTypeID : typeList->typeIndexDataClient[std::type_index(typeid(T*))].netTypeID, .p = std::static_pointer_cast<void>(sharedPtr)}).second)
throw std::runtime_error("[NetObjManager::make_obj] ID Collision");
return NetObjPtr<T>(this, id, sharedPtr);
}
template <typename T> friend class NetObjPtr;
struct SingleObjectData {

View file

@ -10,21 +10,27 @@ class NetObjManagerTypeList {
public:
template <typename ClientT, typename ServerT> struct ServerClientClassFunctions {
std::function<void(const NetObjPtr<ClientT>&, cereal::PortableBinaryOutputArchive&)> writeConstructorFuncClient;
std::function<NetObjPtr<void>(NetObjManager&, cereal::PortableBinaryInputArchive&, const std::shared_ptr<NetServer::ClientData>&)> readConstructorFuncClient;
std::function<void(const NetObjPtr<ClientT>&, cereal::PortableBinaryInputArchive&, const std::shared_ptr<NetServer::ClientData>&)> readConstructorFuncClient;
std::function<void(const NetObjPtr<ClientT>&, cereal::PortableBinaryInputArchive&, const std::shared_ptr<NetServer::ClientData>&)> readUpdateFuncClient;
std::function<void(const NetObjPtr<ServerT>&, cereal::PortableBinaryOutputArchive&)> writeConstructorFuncServer;
std::function<NetObjPtr<void>(NetObjManager&, cereal::PortableBinaryInputArchive&, const std::shared_ptr<NetServer::ClientData>&)> readConstructorFuncServer;
std::function<void(const NetObjPtr<ServerT>&, cereal::PortableBinaryInputArchive&, const std::shared_ptr<NetServer::ClientData>&)> readConstructorFuncServer;
std::function<void(const NetObjPtr<ServerT>&, cereal::PortableBinaryInputArchive&, const std::shared_ptr<NetServer::ClientData>&)> readUpdateFuncServer;
};
template <typename ClientT, typename ServerT, typename ClientAllocatedType, typename ServerAllocatedType> void register_class(const ServerClientClassFunctions<ClientT, ServerT>& funcs) {
netTypeIDData[nextNetTypeID] = NetTypeIDContainer {
.readConstructorFuncClient = funcs.readConstructorFuncClient,
.readConstructorFuncClient = [f = funcs.readConstructorFuncClient](const NetObjPtr<void>& obj, cereal::PortableBinaryInputArchive& message, const std::shared_ptr<NetServer::ClientData>& c) {
if(f)
f(obj.cast<ClientT>(), message, c);
},
.readUpdateFuncClient = [f = funcs.readUpdateFuncClient](const NetObjPtr<void>& obj, cereal::PortableBinaryInputArchive& message, const std::shared_ptr<NetServer::ClientData>& c) {
if(f)
f(obj.cast<ClientT>(), message, c);
},
.readConstructorFuncServer = funcs.readConstructorFuncServer,
.readConstructorFuncServer = [f = funcs.readConstructorFuncServer](const NetObjPtr<void>& obj, cereal::PortableBinaryInputArchive& message, const std::shared_ptr<NetServer::ClientData>& c) {
if(f)
f(obj.cast<ServerT>(), message, c);
},
.readUpdateFuncServer = [f = funcs.readUpdateFuncServer](const NetObjPtr<void>& obj, cereal::PortableBinaryInputArchive& message, const std::shared_ptr<NetServer::ClientData>& c) {
if(f)
f(obj.cast<ServerT>(), message, c);
@ -61,10 +67,10 @@ class NetObjManagerTypeList {
std::unordered_map<std::type_index, TypeIndexContainer> typeIndexDataServer;
struct NetTypeIDContainer {
std::function<NetObjPtr<void>(NetObjManager&, cereal::PortableBinaryInputArchive&, const std::shared_ptr<NetServer::ClientData>&)> readConstructorFuncClient;
std::function<void(const NetObjPtr<void>&, cereal::PortableBinaryInputArchive&, const std::shared_ptr<NetServer::ClientData>&)> readConstructorFuncClient;
std::function<void(const NetObjPtr<void>&, cereal::PortableBinaryInputArchive&, const std::shared_ptr<NetServer::ClientData>&)> readUpdateFuncClient;
std::function<NetObjPtr<void>(NetObjManager&, cereal::PortableBinaryInputArchive&, const std::shared_ptr<NetServer::ClientData>&)> readConstructorFuncServer;
std::function<void(const NetObjPtr<void>&, cereal::PortableBinaryInputArchive&, const std::shared_ptr<NetServer::ClientData>&)> readConstructorFuncServer;
std::function<void(const NetObjPtr<void>&, cereal::PortableBinaryInputArchive&, const std::shared_ptr<NetServer::ClientData>&)> readUpdateFuncServer;
};
std::unordered_map<NetTypeIDType, NetTypeIDContainer> netTypeIDData;

View file

@ -75,13 +75,15 @@ namespace NetworkingObjects {
virtual void erase_by_ptr(const NetObjPtr<NetObjOrderedList<T>>& l, const NetObjOrderedListObjectInfoPtr<T>& p) = 0;
virtual void write_constructor(const NetObjPtr<NetObjOrderedList<T>>& l, cereal::PortableBinaryOutputArchive& a) = 0;
virtual void read_update(const NetObjPtr<NetObjOrderedList<T>>& l, cereal::PortableBinaryInputArchive& a, const std::shared_ptr<NetServer::ClientData>&) = 0;
virtual void read_constructor_post_allocation(const NetObjPtr<NetObjOrderedList<T>>& l, cereal::PortableBinaryInputArchive& a, const std::shared_ptr<NetServer::ClientData>&) = 0;
virtual void read_constructor(const NetObjPtr<NetObjOrderedList<T>>& l, cereal::PortableBinaryInputArchive& a, const std::shared_ptr<NetServer::ClientData>&) = 0;
private:
template <typename S> friend void register_ordered_list_class(NetObjManagerTypeList& t);
static void write_constructor_func(const NetObjPtr<NetObjOrderedList<T>>& l, cereal::PortableBinaryOutputArchive& a) {
l->write_constructor(l, a);
}
static NetObjPtr<void> read_constructor_func(NetObjManager& objMan, cereal::PortableBinaryInputArchive& a, const std::shared_ptr<NetServer::ClientData>& c);
static void read_constructor_func(const NetObjPtr<NetObjOrderedList<T>>& l, cereal::PortableBinaryInputArchive& a, const std::shared_ptr<NetServer::ClientData>& c) {
l->read_constructor(l, a, c);
}
static void read_update_func(const NetObjPtr<NetObjOrderedList<T>>& l, cereal::PortableBinaryInputArchive& a, const std::shared_ptr<NetServer::ClientData>& c) {
l->read_update(l, a, c);
}
@ -133,7 +135,7 @@ namespace NetworkingObjects {
for(size_t i = 0; i < data.size(); i++)
data[i]->obj.write_create_message(a);
}
virtual void read_constructor_post_allocation(const NetObjPtr<NetObjOrderedList<T>>& l, cereal::PortableBinaryInputArchive& a, const std::shared_ptr<NetServer::ClientData>& c) override {
virtual void read_constructor(const NetObjPtr<NetObjOrderedList<T>>& l, cereal::PortableBinaryInputArchive& a, const std::shared_ptr<NetServer::ClientData>& c) override {
uint32_t constructedSize;
a(constructedSize);
data.clear();
@ -215,7 +217,7 @@ namespace NetworkingObjects {
for(size_t i = 0; i < clientData.size(); i++)
clientData[i]->obj.write_create_message(a);
}
virtual void read_constructor_post_allocation(const NetObjPtr<NetObjOrderedList<T>>& l, cereal::PortableBinaryInputArchive& a, const std::shared_ptr<NetServer::ClientData>&) override {
virtual void read_constructor(const NetObjPtr<NetObjOrderedList<T>>& l, cereal::PortableBinaryInputArchive& a, const std::shared_ptr<NetServer::ClientData>&) override {
uint32_t constructedSize;
a(constructedSize);
clientData.clear();
@ -245,12 +247,6 @@ namespace NetworkingObjects {
std::vector<NetObjOrderedListObjectInfoPtr<T>> clientData;
};
template <typename T> NetObjPtr<void> NetObjOrderedList<T>::read_constructor_func(NetObjManager& objMan, cereal::PortableBinaryInputArchive& a, const std::shared_ptr<NetServer::ClientData>& c) {
NetObjPtr<NetObjOrderedList<T>> allocatedPtr = objMan.make_obj<NetObjOrderedList<T>>();
allocatedPtr->read_constructor_post_allocation(allocatedPtr, a, c);
return allocatedPtr.template cast<void>();
}
template <typename S> void register_ordered_list_class(NetObjManagerTypeList& t) {
t.register_class<NetObjOrderedList<S>, NetObjOrderedList<S>, NetObjOrderedListClient<S>, NetObjOrderedListServer<S>>({
.writeConstructorFuncClient = NetObjOrderedList<S>::write_constructor_func,