Same make_obj call allocates the correct type
This commit is contained in:
parent
5d24b34200
commit
d9a90dda16
10 changed files with 53 additions and 17 deletions
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
namespace NetworkingObjects {
|
||||
template <typename T> void register_generic_serialized_class(NetObjManagerTypeList& t) {
|
||||
t.register_class<T, T>({
|
||||
t.register_class<T, T, T, T>({
|
||||
.writeConstructorFuncClient = [](const NetObjPtr<T>& o, cereal::PortableBinaryOutputArchive& a) {
|
||||
a(*o);
|
||||
},
|
||||
|
|
|
|||
|
|
@ -10,6 +10,11 @@ namespace NetworkingObjects {
|
|||
template <typename Archive> void serialize(Archive& a) {
|
||||
a(data[1], data[0]);
|
||||
}
|
||||
std::string to_string() {
|
||||
std::stringstream ss;
|
||||
ss << "[" << data[1] << ", " << data[0] << "]";
|
||||
return ss.str();
|
||||
}
|
||||
NetObjID& operator=(const NetObjID&) = default;
|
||||
bool operator==(const NetObjID&) const = default;
|
||||
static NetObjID random_gen();
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ namespace NetworkingObjects {
|
|||
void set_client(std::shared_ptr<NetClient> initClient, MessageCommandType initUpdateCommandID);
|
||||
void set_server(std::shared_ptr<NetServer> initServer, MessageCommandType initUpdateCommandID);
|
||||
bool is_server() const;
|
||||
|
||||
template <typename T> NetObjPtr<T> read_create_message(cereal::PortableBinaryInputArchive& a, const std::shared_ptr<NetServer::ClientData>& clientReceivedFrom) {
|
||||
NetObjID id;
|
||||
NetTypeIDType typeID;
|
||||
|
|
@ -42,7 +41,15 @@ namespace NetworkingObjects {
|
|||
return NetObjPtr<T>();
|
||||
return NetObjPtr<T>(this, id, std::static_pointer_cast<T>(it->second.p));
|
||||
}
|
||||
template <typename T, typename... Args> NetObjPtr<T> make_obj(Args&&... items) {
|
||||
template <typename T> NetObjPtr<T> make_obj() {
|
||||
auto sharedPtr = std::static_pointer_cast<T>(isServer ? typeList->typeIndexDataServer[std::type_index(typeid(T*))].allocatorFunc() : typeList->typeIndexDataClient[std::type_index(typeid(T*))].allocatorFunc());
|
||||
NetObjID newID = NetObjID::random_gen();
|
||||
if(!objectData.emplace(newID, 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, newID, sharedPtr);
|
||||
}
|
||||
// Don't use this function unless you're sure that class T isn't a base class
|
||||
template <typename T, typename... Args> NetObjPtr<T> make_obj_direct(Args&&... items) {
|
||||
auto sharedPtr = std::make_shared<T>(items...);
|
||||
NetObjID newID = NetObjID::random_gen();
|
||||
if(!objectData.emplace(newID, 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)
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ class NetObjManagerTypeList {
|
|||
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>&)> readUpdateFuncServer;
|
||||
};
|
||||
template <typename ClientT, typename ServerT> void register_class(const ServerClientClassFunctions<ClientT, ServerT>& funcs) {
|
||||
template <typename ClientT, typename ServerT, typename ClientAllocatedType, typename ServerAllocatedType> void register_class(const ServerClientClassFunctions<ClientT, ServerT>& funcs) {
|
||||
netTypeIDData[nextNetTypeID] = NetTypeIDContainer {
|
||||
.readConstructorFuncClient = funcs.readConstructorFuncClient,
|
||||
.readUpdateFuncClient = [f = funcs.readUpdateFuncClient](const NetObjPtr<void>& obj, cereal::PortableBinaryInputArchive& message, const std::shared_ptr<NetServer::ClientData>& c) {
|
||||
|
|
@ -35,12 +35,14 @@ class NetObjManagerTypeList {
|
|||
.writeConstructorFunc = [f = funcs.writeConstructorFuncClient](const NetObjPtr<void>& obj, cereal::PortableBinaryOutputArchive& message) {
|
||||
f(obj.cast<ClientT>(), message);
|
||||
},
|
||||
.allocatorFunc = []() { return std::make_shared<ClientAllocatedType>(); }
|
||||
};
|
||||
typeIndexDataServer[std::type_index(typeid(ServerT*))] = TypeIndexContainer{
|
||||
.netTypeID = nextNetTypeID,
|
||||
.writeConstructorFunc = [f = funcs.writeConstructorFuncServer](const NetObjPtr<void>& obj, cereal::PortableBinaryOutputArchive& message) {
|
||||
f(obj.cast<ServerT>(), message);
|
||||
},
|
||||
.allocatorFunc = []() { return std::make_shared<ServerAllocatedType>(); }
|
||||
};
|
||||
nextNetTypeID++;
|
||||
}
|
||||
|
|
@ -51,6 +53,7 @@ class NetObjManagerTypeList {
|
|||
struct TypeIndexContainer {
|
||||
NetTypeIDType netTypeID;
|
||||
std::function<void(const NetObjPtr<void>&, cereal::PortableBinaryOutputArchive&)> writeConstructorFunc;
|
||||
std::function<std::shared_ptr<void>()> allocatorFunc;
|
||||
};
|
||||
|
||||
// std::type_index in this case is the typeinfo for the POINTER of the type in question. This ensures that we get a mapping for the exact type that was registered, not for a child of the type in case of inheritance
|
||||
|
|
|
|||
|
|
@ -45,9 +45,11 @@ namespace NetworkingObjects {
|
|||
|
||||
template <typename T> class NetObjOrderedList {
|
||||
public:
|
||||
template <typename... Args> static NetObjPtr<T> emplace_back(const NetObjPtr<NetObjOrderedList<T>>& l, Args&&... args) {
|
||||
NetObjPtr<T> newObj = l.get_obj_man()->template make_obj<T>(args...);
|
||||
return push_back_and_send_create(l, newObj);
|
||||
// Don't use this function unless you're sure that class T isn't a base class
|
||||
template <typename ...Args> NetObjPtr<T> emplace_back_direct(const NetObjPtr<NetObjOrderedList<T>>& l, Args&&... items) {
|
||||
NetObjPtr<T> newObj = l.get_obj_man()->template make_obj_direct<T>(items...);
|
||||
l->push_back(l, newObj);
|
||||
return newObj;
|
||||
}
|
||||
static NetObjPtr<T> push_back_and_send_create(const NetObjPtr<NetObjOrderedList<T>>& l, const NetObjPtr<T>& newObj) {
|
||||
l->push_back(l, newObj);
|
||||
|
|
@ -65,6 +67,7 @@ namespace NetworkingObjects {
|
|||
}
|
||||
virtual uint32_t size() const = 0;
|
||||
virtual const std::vector<NetObjOrderedListObjectInfoPtr<T>>& get_data() const = 0;
|
||||
virtual ~NetObjOrderedList() {}
|
||||
protected:
|
||||
virtual void push_back(const NetObjPtr<NetObjOrderedList<T>>& l, const NetObjPtr<T>& newObj) = 0;
|
||||
virtual void insert(const NetObjPtr<NetObjOrderedList<T>>& l, uint32_t posToInsertAt, const NetObjPtr<T>& newObj) = 0;
|
||||
|
|
@ -86,6 +89,7 @@ namespace NetworkingObjects {
|
|||
|
||||
template <typename T> class NetObjOrderedListServer : public NetObjOrderedList<T> {
|
||||
public:
|
||||
NetObjOrderedListServer() {}
|
||||
virtual uint32_t size() const override {
|
||||
return data.size();
|
||||
}
|
||||
|
|
@ -166,6 +170,7 @@ namespace NetworkingObjects {
|
|||
|
||||
template <typename T> class NetObjOrderedListClient : public NetObjOrderedList<T> {
|
||||
public:
|
||||
NetObjOrderedListClient() {}
|
||||
virtual uint32_t size() const override {
|
||||
return clientData.size();
|
||||
}
|
||||
|
|
@ -241,13 +246,13 @@ namespace NetworkingObjects {
|
|||
};
|
||||
|
||||
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.is_server() ? objMan.make_obj<NetObjOrderedListServer<T>>().template cast<NetObjOrderedList<T>>() : objMan.make_obj<NetObjOrderedListClient<T>>().template cast<NetObjOrderedList<T>>();
|
||||
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>>({
|
||||
t.register_class<NetObjOrderedList<S>, NetObjOrderedList<S>, NetObjOrderedListClient<S>, NetObjOrderedListServer<S>>({
|
||||
.writeConstructorFuncClient = NetObjOrderedList<S>::write_constructor_func,
|
||||
.readConstructorFuncClient = NetObjOrderedList<S>::read_constructor_func,
|
||||
.readUpdateFuncClient = NetObjOrderedList<S>::read_update_func,
|
||||
|
|
|
|||
|
|
@ -18,8 +18,8 @@ class ConnectionManager {
|
|||
bool client_exists();
|
||||
std::unordered_map<ServerClientID, NetLibrary::DownloadProgress> server_get_resource_retrieval_progress();
|
||||
NetLibrary::DownloadProgress client_get_resource_retrieval_progress();
|
||||
std::unique_ptr<MainServer> localServer;
|
||||
private:
|
||||
std::shared_ptr<NetClient> client;
|
||||
std::unique_ptr<MainServer> localServer;
|
||||
std::chrono::steady_clock::time_point lastKeepAliveTime;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#include "MainProgram.hpp"
|
||||
#include "DrawingProgram/DrawingProgramToolBase.hpp"
|
||||
#include "Helpers/NetworkingObjects/NetObjManagerTypeList.hpp"
|
||||
#include "VersionConstants.hpp"
|
||||
#include "cereal/archives/portable_binary.hpp"
|
||||
#include "cereal/details/helpers.hpp"
|
||||
|
|
@ -37,19 +38,16 @@
|
|||
#endif
|
||||
|
||||
#include <Helpers/Logger.hpp>
|
||||
#include <Helpers/Networking/NetLibrary.hpp>
|
||||
#include <Helpers/NetworkingObjects/NetObjOrderedList.hpp>
|
||||
#include <Helpers/NetworkingObjects/NetObjManager.hpp>
|
||||
#include <Helpers/NetworkingObjects/NetObjGenericSerializedClass.hpp>
|
||||
|
||||
MainProgram::MainProgram():
|
||||
fonts(std::make_shared<FontData>()),
|
||||
toolbar(*this)
|
||||
{
|
||||
auto typeList = std::make_shared<NetworkingObjects::NetObjManagerTypeList>();
|
||||
NetworkingObjects::register_generic_serialized_class<std::string>(*typeList);
|
||||
NetworkingObjects::register_ordered_list_class<std::string>(*typeList);
|
||||
auto nObjMan = std::make_shared<NetworkingObjects::NetObjManager>(typeList, false);
|
||||
netObjectTypeList = std::make_shared<NetworkingObjects::NetObjManagerTypeList>();
|
||||
NetworkingObjects::register_generic_serialized_class<std::string>(*netObjectTypeList);
|
||||
NetworkingObjects::register_ordered_list_class<std::string>(*netObjectTypeList);
|
||||
|
||||
displayName = Random::get().alphanumeric_str(10);
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
#include "SharedTypes.hpp"
|
||||
#include <Eigen/Dense>
|
||||
#include <include/core/SkSurfaceProps.h>
|
||||
#include <Helpers/NetworkingObjects/NetObjManagerTypeList.hpp>
|
||||
#include "Toolbar.hpp"
|
||||
#include "World.hpp"
|
||||
|
||||
|
|
@ -115,6 +116,8 @@ class MainProgram {
|
|||
|
||||
std::string displayName;
|
||||
|
||||
std::shared_ptr<NetworkingObjects::NetObjManagerTypeList> netObjectTypeList;
|
||||
|
||||
~MainProgram();
|
||||
private:
|
||||
void new_tab_open();
|
||||
|
|
|
|||
|
|
@ -30,7 +30,8 @@ World::World(MainProgram& initMain, OpenWorldInfo& worldInfo):
|
|||
rMan(*this),
|
||||
drawProg(*this),
|
||||
bMan(*this),
|
||||
gridMan(*this)
|
||||
gridMan(*this),
|
||||
netObjMan(initMain.netObjectTypeList, worldInfo.conType != CONNECTIONTYPE_CLIENT)
|
||||
{
|
||||
set_canvas_background_color(main.defaultCanvasBackgroundColor);
|
||||
displayName = main.displayName;
|
||||
|
|
@ -68,6 +69,14 @@ World::World(MainProgram& initMain, OpenWorldInfo& worldInfo):
|
|||
gridMan.init_client_callbacks();
|
||||
init_client_callbacks();
|
||||
con.client_send_items_to_server(RELIABLE_COMMAND_CHANNEL, SERVER_INITIAL_DATA, displayName, false);
|
||||
|
||||
using namespace NetworkingObjects;
|
||||
stringListTest = netObjMan.make_obj<NetObjOrderedList<std::string>>();
|
||||
stringListTest->emplace_back_direct(stringListTest, "Hello");
|
||||
stringListTest->emplace_back_direct(stringListTest, "World");
|
||||
stringListTest->emplace_back_direct(stringListTest, "Test");
|
||||
for(const NetObjOrderedListObjectInfoPtr<std::string>& 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() {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#pragma once
|
||||
#include "Helpers/NetworkingObjects/NetObjOrderedList.hpp"
|
||||
#include "UndoManager.hpp"
|
||||
#include "BookmarkManager.hpp"
|
||||
#include "ResourceManager.hpp"
|
||||
|
|
@ -7,6 +8,7 @@
|
|||
#include "Toolbar.hpp"
|
||||
#include "SharedTypes.hpp"
|
||||
#include "GridManager.hpp"
|
||||
#include <Helpers/NetworkingObjects/NetObjManager.hpp>
|
||||
#include <filesystem>
|
||||
|
||||
class MainProgram;
|
||||
|
|
@ -45,6 +47,7 @@ class World {
|
|||
BookmarkManager bMan;
|
||||
ConnectionManager con;
|
||||
GridManager gridMan;
|
||||
NetworkingObjects::NetObjManager netObjMan;
|
||||
|
||||
std::deque<Toolbar::ChatMessage> chatMessages;
|
||||
|
||||
|
|
@ -88,6 +91,8 @@ class World {
|
|||
std::string name;
|
||||
std::unordered_map<ServerPortionID, ClientData> clients;
|
||||
|
||||
NetworkingObjects::NetObjPtr<NetworkingObjects::NetObjOrderedList<std::string>> stringListTest;
|
||||
|
||||
void set_canvas_background_color(const Vector3f& newBackColor, bool sendChangeOverNetwork = true);
|
||||
|
||||
struct CanvasTheme {
|
||||
|
|
@ -100,6 +105,7 @@ class World {
|
|||
|
||||
uint64_t canvasScale = 0;
|
||||
private:
|
||||
|
||||
ClientPortionID get_max_id(ServerPortionID serverID);
|
||||
|
||||
void init_client_callbacks();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue