diff --git a/include/Helpers/NetworkingObjects/NetObjGenericSerializedClass.hpp b/include/Helpers/NetworkingObjects/NetObjGenericSerializedClass.hpp index 4a591db..e570d17 100644 --- a/include/Helpers/NetworkingObjects/NetObjGenericSerializedClass.hpp +++ b/include/Helpers/NetworkingObjects/NetObjGenericSerializedClass.hpp @@ -7,10 +7,8 @@ namespace NetworkingObjects { .writeConstructorFuncClient = [](const NetObjPtr& o, cereal::PortableBinaryOutputArchive& a) { a(*o); }, - .readConstructorFuncClient = [](NetObjManager& m, cereal::PortableBinaryInputArchive& a, const std::shared_ptr&) { - NetObjPtr o = m.make_obj(); + .readConstructorFuncClient = [](const NetObjPtr& o, cereal::PortableBinaryInputArchive& a, const std::shared_ptr&) { a(*o); - return o.template cast(); }, .readUpdateFuncClient = [](const NetObjPtr& o, cereal::PortableBinaryInputArchive& a, const std::shared_ptr&) { a(*o); @@ -18,10 +16,8 @@ namespace NetworkingObjects { .writeConstructorFuncServer = [](const NetObjPtr& o, cereal::PortableBinaryOutputArchive& a) { a(*o); }, - .readConstructorFuncServer = [](NetObjManager& m, cereal::PortableBinaryInputArchive& a, const std::shared_ptr&) { - NetObjPtr o = m.make_obj(); + .readConstructorFuncServer = [](const NetObjPtr& o, cereal::PortableBinaryInputArchive& a, const std::shared_ptr&) { a(*o); - return o.template cast(); }, .readUpdateFuncServer = [](const NetObjPtr& o, cereal::PortableBinaryInputArchive& a, const std::shared_ptr&) { a(*o); diff --git a/include/Helpers/NetworkingObjects/NetObjManager.hpp b/include/Helpers/NetworkingObjects/NetObjManager.hpp index fbac8f2..e7baa29 100644 --- a/include/Helpers/NetworkingObjects/NetObjManager.hpp +++ b/include/Helpers/NetworkingObjects/NetObjManager.hpp @@ -28,10 +28,12 @@ namespace NetworkingObjects { NetTypeIDType typeID; a(id, typeID); auto& netTypeIDData = typeList->netTypeIDData[typeID]; + NetObjPtr newPtr = make_obj_with_id(id); if(isServer) - return netTypeIDData.readConstructorFuncServer(*this, a, clientReceivedFrom).cast(); + netTypeIDData.readConstructorFuncServer(newPtr.template cast(), a, clientReceivedFrom); else - return netTypeIDData.readConstructorFuncClient(*this, a, clientReceivedFrom).cast(); + netTypeIDData.readConstructorFuncClient(newPtr.template cast(), a, clientReceivedFrom); + return newPtr; } template NetObjPtr read_get_obj_from_message(cereal::PortableBinaryInputArchive& a) { NetObjID id; @@ -70,6 +72,13 @@ namespace NetworkingObjects { return NetObjPtr(this, id, std::static_pointer_cast(it->second.p)); } private: + template NetObjPtr make_obj_with_id(NetObjID id) { + auto sharedPtr = std::static_pointer_cast(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(sharedPtr)}).second) + throw std::runtime_error("[NetObjManager::make_obj] ID Collision"); + return NetObjPtr(this, id, sharedPtr); + } + template friend class NetObjPtr; struct SingleObjectData { diff --git a/include/Helpers/NetworkingObjects/NetObjManagerTypeList.hpp b/include/Helpers/NetworkingObjects/NetObjManagerTypeList.hpp index 0a2dcb5..1de7213 100644 --- a/include/Helpers/NetworkingObjects/NetObjManagerTypeList.hpp +++ b/include/Helpers/NetworkingObjects/NetObjManagerTypeList.hpp @@ -10,21 +10,27 @@ class NetObjManagerTypeList { public: template struct ServerClientClassFunctions { std::function&, cereal::PortableBinaryOutputArchive&)> writeConstructorFuncClient; - std::function(NetObjManager&, cereal::PortableBinaryInputArchive&, const std::shared_ptr&)> readConstructorFuncClient; + std::function&, cereal::PortableBinaryInputArchive&, const std::shared_ptr&)> readConstructorFuncClient; std::function&, cereal::PortableBinaryInputArchive&, const std::shared_ptr&)> readUpdateFuncClient; std::function&, cereal::PortableBinaryOutputArchive&)> writeConstructorFuncServer; - std::function(NetObjManager&, cereal::PortableBinaryInputArchive&, const std::shared_ptr&)> readConstructorFuncServer; + std::function&, cereal::PortableBinaryInputArchive&, const std::shared_ptr&)> readConstructorFuncServer; std::function&, cereal::PortableBinaryInputArchive&, const std::shared_ptr&)> readUpdateFuncServer; }; template void register_class(const ServerClientClassFunctions& funcs) { netTypeIDData[nextNetTypeID] = NetTypeIDContainer { - .readConstructorFuncClient = funcs.readConstructorFuncClient, + .readConstructorFuncClient = [f = funcs.readConstructorFuncClient](const NetObjPtr& obj, cereal::PortableBinaryInputArchive& message, const std::shared_ptr& c) { + if(f) + f(obj.cast(), message, c); + }, .readUpdateFuncClient = [f = funcs.readUpdateFuncClient](const NetObjPtr& obj, cereal::PortableBinaryInputArchive& message, const std::shared_ptr& c) { if(f) f(obj.cast(), message, c); }, - .readConstructorFuncServer = funcs.readConstructorFuncServer, + .readConstructorFuncServer = [f = funcs.readConstructorFuncServer](const NetObjPtr& obj, cereal::PortableBinaryInputArchive& message, const std::shared_ptr& c) { + if(f) + f(obj.cast(), message, c); + }, .readUpdateFuncServer = [f = funcs.readUpdateFuncServer](const NetObjPtr& obj, cereal::PortableBinaryInputArchive& message, const std::shared_ptr& c) { if(f) f(obj.cast(), message, c); @@ -61,10 +67,10 @@ class NetObjManagerTypeList { std::unordered_map typeIndexDataServer; struct NetTypeIDContainer { - std::function(NetObjManager&, cereal::PortableBinaryInputArchive&, const std::shared_ptr&)> readConstructorFuncClient; + std::function&, cereal::PortableBinaryInputArchive&, const std::shared_ptr&)> readConstructorFuncClient; std::function&, cereal::PortableBinaryInputArchive&, const std::shared_ptr&)> readUpdateFuncClient; - std::function(NetObjManager&, cereal::PortableBinaryInputArchive&, const std::shared_ptr&)> readConstructorFuncServer; + std::function&, cereal::PortableBinaryInputArchive&, const std::shared_ptr&)> readConstructorFuncServer; std::function&, cereal::PortableBinaryInputArchive&, const std::shared_ptr&)> readUpdateFuncServer; }; std::unordered_map netTypeIDData; diff --git a/include/Helpers/NetworkingObjects/NetObjOrderedList.hpp b/include/Helpers/NetworkingObjects/NetObjOrderedList.hpp index 5040ccd..8d7cbf6 100644 --- a/include/Helpers/NetworkingObjects/NetObjOrderedList.hpp +++ b/include/Helpers/NetworkingObjects/NetObjOrderedList.hpp @@ -75,13 +75,15 @@ namespace NetworkingObjects { virtual void erase_by_ptr(const NetObjPtr>& l, const NetObjOrderedListObjectInfoPtr& p) = 0; virtual void write_constructor(const NetObjPtr>& l, cereal::PortableBinaryOutputArchive& a) = 0; virtual void read_update(const NetObjPtr>& l, cereal::PortableBinaryInputArchive& a, const std::shared_ptr&) = 0; - virtual void read_constructor_post_allocation(const NetObjPtr>& l, cereal::PortableBinaryInputArchive& a, const std::shared_ptr&) = 0; + virtual void read_constructor(const NetObjPtr>& l, cereal::PortableBinaryInputArchive& a, const std::shared_ptr&) = 0; private: template friend void register_ordered_list_class(NetObjManagerTypeList& t); static void write_constructor_func(const NetObjPtr>& l, cereal::PortableBinaryOutputArchive& a) { l->write_constructor(l, a); } - static NetObjPtr read_constructor_func(NetObjManager& objMan, cereal::PortableBinaryInputArchive& a, const std::shared_ptr& c); + static void read_constructor_func(const NetObjPtr>& l, cereal::PortableBinaryInputArchive& a, const std::shared_ptr& c) { + l->read_constructor(l, a, c); + } static void read_update_func(const NetObjPtr>& l, cereal::PortableBinaryInputArchive& a, const std::shared_ptr& 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>& l, cereal::PortableBinaryInputArchive& a, const std::shared_ptr& c) override { + virtual void read_constructor(const NetObjPtr>& l, cereal::PortableBinaryInputArchive& a, const std::shared_ptr& 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>& l, cereal::PortableBinaryInputArchive& a, const std::shared_ptr&) override { + virtual void read_constructor(const NetObjPtr>& l, cereal::PortableBinaryInputArchive& a, const std::shared_ptr&) override { uint32_t constructedSize; a(constructedSize); clientData.clear(); @@ -245,12 +247,6 @@ namespace NetworkingObjects { std::vector> clientData; }; - template NetObjPtr NetObjOrderedList::read_constructor_func(NetObjManager& objMan, cereal::PortableBinaryInputArchive& a, const std::shared_ptr& c) { - NetObjPtr> allocatedPtr = objMan.make_obj>(); - allocatedPtr->read_constructor_post_allocation(allocatedPtr, a, c); - return allocatedPtr.template cast(); - } - template void register_ordered_list_class(NetObjManagerTypeList& t) { t.register_class, NetObjOrderedList, NetObjOrderedListClient, NetObjOrderedListServer>({ .writeConstructorFuncClient = NetObjOrderedList::write_constructor_func, diff --git a/src/Server/MainServer.cpp b/src/Server/MainServer.cpp index 412d4e1..b5bffc9 100644 --- a/src/Server/MainServer.cpp +++ b/src/Server/MainServer.cpp @@ -69,7 +69,13 @@ MainServer::MainServer(World& initWorld, const std::string& serverLocalID): if(isDirectConnect) netServer->send_items_to_client(client, RELIABLE_COMMAND_CHANNEL, CLIENT_INITIAL_DATA, isDirectConnect, newClient.serverID, newClient.cursorColor); else { - netServer->send_items_to_client(client, RELIABLE_COMMAND_CHANNEL, CLIENT_INITIAL_DATA, isDirectConnect, newClient.serverID, newClient.cursorColor, newClient.displayName, newClient.camCoords, newClient.windowSize, fileDisplayName, clients, data); + auto ss(std::make_shared()); + { + cereal::PortableBinaryOutputArchive a(*ss); + a(CLIENT_INITIAL_DATA, isDirectConnect, newClient.serverID, newClient.cursorColor, newClient.displayName, newClient.camCoords, newClient.windowSize, fileDisplayName, clients, data); + world.stringListTest.write_create_message(a); + } + netServer->send_string_stream_to_client(client, RELIABLE_COMMAND_CHANNEL, ss); for(auto& [id, rData] : data.resources) { netServer->send_items_to_client(client, RESOURCE_COMMAND_CHANNEL, CLIENT_NEW_RESOURCE_ID, id); netServer->send_items_to_client(client, RESOURCE_COMMAND_CHANNEL, CLIENT_NEW_RESOURCE_DATA, rData); diff --git a/src/World.cpp b/src/World.cpp index 576de7f..cbb542c 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -3,6 +3,7 @@ #include "Helpers/HsvRgb.hpp" #include "Helpers/MathExtras.hpp" #include "Helpers/Networking/ByteStream.hpp" +#include "Helpers/NetworkingObjects/NetObjManager.hpp" #include "Helpers/VersionNumber.hpp" #include "Server/CommandList.hpp" #include "MainProgram.hpp" @@ -71,12 +72,14 @@ World::World(MainProgram& initMain, OpenWorldInfo& worldInfo): con.client_send_items_to_server(RELIABLE_COMMAND_CHANNEL, SERVER_INITIAL_DATA, displayName, false); using namespace NetworkingObjects; - stringListTest = netObjMan.make_obj>(); - stringListTest->emplace_back_direct(stringListTest, "Hello"); - stringListTest->emplace_back_direct(stringListTest, "World"); - stringListTest->emplace_back_direct(stringListTest, "Test"); - for(const NetObjOrderedListObjectInfoPtr& o : stringListTest->get_data()) - std::cout << "At position: " << o->get_pos() << " we have string: \"" << *o->get_obj() << "\" with object id " << o->get_obj().get_net_id().to_string() << std::endl; + if(netObjMan.is_server()) { + stringListTest = netObjMan.make_obj>(); + stringListTest->emplace_back_direct(stringListTest, "Hello"); + stringListTest->emplace_back_direct(stringListTest, "World"); + stringListTest->emplace_back_direct(stringListTest, "Test"); + for(const NetObjOrderedListObjectInfoPtr& o : stringListTest->get_data()) + std::cout << "At position: " << o->get_pos() << " we have string: \"" << *o->get_obj() << "\" with object id " << o->get_obj().get_net_id().to_string() << std::endl; + } } void World::init_client_callbacks() { @@ -96,6 +99,10 @@ void World::init_client_callbacks() { message(canvasScale); drawProg.initialize_draw_data(message); message(bMan, gridMan); + stringListTest = netObjMan.read_create_message>(message, nullptr); + std::cout << "Client print: " << std::endl; + for(const NetworkingObjects::NetObjOrderedListObjectInfoPtr& o : stringListTest->get_data()) + std::cout << "At position: " << o->get_pos() << " we have string: \"" << *o->get_obj() << "\" with object id " << o->get_obj().get_net_id().to_string() << std::endl; } nextClientID = get_max_id(ownID); clientStillConnecting = false;