Added all canvas component classes

This commit is contained in:
Yousef Khadadeh 2025-12-13 13:03:27 +03:00
parent cfd6f4b4e0
commit 228469c33d
32 changed files with 1369 additions and 143 deletions

View file

@ -7,40 +7,47 @@
namespace NetworkingObjects {
class DelayUpdateSerializedClassManager {
public:
template <typename T> void register_class(NetObjManagerTypeList& t) {
t.register_class<T, T, T, T>({
.writeConstructorFuncClient = [&](const NetObjTemporaryPtr<T>& o, cereal::PortableBinaryOutputArchive& a){client_write_func<T>(std::nullopt, o, a);},
.readConstructorFuncClient = [&](const NetObjTemporaryPtr<T>& o, cereal::PortableBinaryInputArchive& a, const std::shared_ptr<NetServer::ClientData>&){delay_read_func_constructor<T>(o, a);},
.readUpdateFuncClient = [&](const NetObjTemporaryPtr<T>& o, cereal::PortableBinaryInputArchive& a, const std::shared_ptr<NetServer::ClientData>&){delay_read_func<T>(o, a);},
.writeConstructorFuncServer = [&](const NetObjTemporaryPtr<T>& o, cereal::PortableBinaryOutputArchive& a){server_write_func<T>(o, a);},
.readConstructorFuncServer = [&](const NetObjTemporaryPtr<T>& o, cereal::PortableBinaryInputArchive& a, const std::shared_ptr<NetServer::ClientData>&){delay_read_func_constructor<T>(o, a);},
template <typename T> void register_class(NetObjManager& objMan) {
objMan.register_class<T, T, T, T>({
.writeConstructorFuncClient = [&](const NetObjTemporaryPtr<T>& o, cereal::PortableBinaryOutputArchive& a){write_constructor_func<T>(o, a);},
.readConstructorFuncClient = [&](const NetObjTemporaryPtr<T>& o, cereal::PortableBinaryInputArchive& a, const std::shared_ptr<NetServer::ClientData>&){read_constructor_func<T>(o, a);},
.readUpdateFuncClient = [&](const NetObjTemporaryPtr<T>& o, cereal::PortableBinaryInputArchive& a, const std::shared_ptr<NetServer::ClientData>&){client_read_update_func<T>(o, a);},
.writeConstructorFuncServer = [&](const NetObjTemporaryPtr<T>& o, cereal::PortableBinaryOutputArchive& a){write_constructor_func<T>(o, a);},
.readConstructorFuncServer = [&](const NetObjTemporaryPtr<T>& o, cereal::PortableBinaryInputArchive& a, const std::shared_ptr<NetServer::ClientData>&){read_constructor_func<T>(o, a);},
.readUpdateFuncServer = [&](const NetObjTemporaryPtr<T>& o, cereal::PortableBinaryInputArchive& a, const std::shared_ptr<NetServer::ClientData>&){server_read_update_func<T>(o, a);}
});
}
template <typename T> void send_update_to_all(const NetworkingObjects::NetObjTemporaryPtr<T>& o, bool finalUpdate) {
template <typename T> void send_update_to_all(const NetworkingObjects::NetObjTemporaryPtr<T>& o, const std::function<void(T&)>& postAssignmentFunc, bool finalUpdate) {
o.send_update_to_all(finalUpdate ? RELIABLE_COMMAND_CHANNEL : UNRELIABLE_COMMAND_CHANNEL, [&](const NetObjTemporaryPtr<T>& o, cereal::PortableBinaryOutputArchive& a) {
if(o.get_obj_man()->is_server())
server_write_func(o, a);
server_write_func(o, a, postAssignmentFunc);
else
client_write_func(finalUpdate, o, a);
client_write_update_func(o, a, postAssignmentFunc, finalUpdate);
});
}
void update();
private:
template <typename T> void client_write_func(std::optional<bool> finalUpdate, const NetObjTemporaryPtr<T>& o, cereal::PortableBinaryOutputArchive& a) {
if(finalUpdate.has_value())
a(finalUpdate.value());
template <typename T> void write_constructor_func(const NetObjTemporaryPtr<T>& o, cereal::PortableBinaryOutputArchive& a) {
a(*o);
}
template <typename T> void client_write_update_func(const NetObjTemporaryPtr<T>& o, cereal::PortableBinaryOutputArchive& a, const std::function<void(T&)>& postAssignmentFunc, bool finalUpdate) {
a(finalUpdate);
a(*o);
auto it = updatingObjs.find(o.get_net_id());
if(it == updatingObjs.end()) {
UpdatingObject toAdd;
toAdd.objToUpdateCurrentData = std::static_pointer_cast<void>(std::make_shared<T>(*o));
toAdd.doLastAssignment = std::make_shared<bool>(true);
toAdd.lastUpdateTimePoint = std::chrono::steady_clock::now();
toAdd.setDataAfterTimeout = [oWeak = NetObjWeakPtr<T>(o), currentData = toAdd.objToUpdateCurrentData, doLastAssignment = toAdd.doLastAssignment]() {
toAdd.setDataAfterTimeout = [postAssignmentFunc, oWeak = NetObjWeakPtr<T>(o), currentData = toAdd.objToUpdateCurrentData, doLastAssignment = toAdd.doLastAssignment]() {
NetObjTemporaryPtr<T> oLock = oWeak.lock();
if(oLock && *doLastAssignment)
if(oLock && *doLastAssignment) {
*oLock = *std::static_pointer_cast<T>(currentData);
if(postAssignmentFunc)
postAssignmentFunc(*oLock);
}
};
updatingObjs.emplace(o.get_net_id(), toAdd);
}
@ -50,11 +57,11 @@ namespace NetworkingObjects {
}
}
template <typename T> void delay_read_func_constructor(const NetObjTemporaryPtr<T>& o, cereal::PortableBinaryInputArchive& a) {
template <typename T> void read_constructor_func(const NetObjTemporaryPtr<T>& o, cereal::PortableBinaryInputArchive& a) {
a(*o);
}
template <typename T> void delay_read_func(const NetObjTemporaryPtr<T>& o, cereal::PortableBinaryInputArchive& a) {
template <typename T> void client_read_update_func(const NetObjTemporaryPtr<T>& o, cereal::PortableBinaryInputArchive& a) {
auto it = updatingObjs.find(o.get_net_id());
if(it == updatingObjs.end())
a(*o);
@ -65,18 +72,21 @@ namespace NetworkingObjects {
}
}
template <typename T> void server_write_func(const NetObjTemporaryPtr<T>& o, cereal::PortableBinaryOutputArchive& a) {
template <typename T> void server_write_func(const NetObjTemporaryPtr<T>& o, cereal::PortableBinaryOutputArchive& a, const std::function<void(T&)>& postAssignmentFunc) {
a(*o);
auto it = updatingObjs.find(o.get_net_id());
if(it == updatingObjs.end()) {
UpdatingObject toAdd;
toAdd.objToUpdateCurrentData = std::static_pointer_cast<void>(std::make_shared<T>(*o));
toAdd.lastUpdateTimePoint = std::chrono::steady_clock::now();
toAdd.doLastAssignment = std::make_shared<bool>(false);
toAdd.setDataAfterTimeout = [oWeak = NetObjWeakPtr<T>(o), currentData = toAdd.objToUpdateCurrentData, doLastAssignment = toAdd.doLastAssignment]() {
toAdd.setDataAfterTimeout = [postAssignmentFunc, oWeak = NetObjWeakPtr<T>(o), currentData = toAdd.objToUpdateCurrentData, doLastAssignment = toAdd.doLastAssignment]() {
NetObjTemporaryPtr<T> oLock = oWeak.lock();
if(oLock && *doLastAssignment) {
*oLock = *std::static_pointer_cast<T>(currentData);
if(postAssignmentFunc)
postAssignmentFunc(*oLock);
oLock.send_server_update_to_all_clients(RELIABLE_COMMAND_CHANNEL, [](const NetObjTemporaryPtr<T>& o, cereal::PortableBinaryOutputArchive& a) {
a(*o);
});

View file

@ -16,8 +16,8 @@ namespace NetworkingObjects {
a(*o);
}
template <typename T> void register_generic_serialized_class(NetObjManagerTypeList& t) {
t.register_class<T, T, T, T>({
template <typename T> void register_generic_serialized_class(NetObjManager& objMan) {
objMan.register_class<T, T, T, T>({
.writeConstructorFuncClient = default_serialize_write_func<T>,
.readConstructorFuncClient = default_serialize_read_constructor_func<T>,
.readUpdateFuncClient = default_serialize_read_func_client<T>,

View file

@ -2,9 +2,8 @@
#include "NetObjTemporaryPtr.hpp"
namespace NetworkingObjects {
NetObjManager::NetObjManager(std::shared_ptr<NetObjManagerTypeList> initTypeList, bool initIsServer):
NetObjManager::NetObjManager(bool initIsServer):
isServer(initIsServer),
typeList(initTypeList),
nextTypeID(0)
{}
bool NetObjManager::is_server() const {
@ -16,7 +15,7 @@ namespace NetworkingObjects {
auto it = objectData.find(id);
if(it == objectData.end())
return;
typeList->get_net_type_data(isServer, it->second.netTypeID).readUpdateFunc(NetObjTemporaryPtr<void>(this, id, it->second.p), a, clientReceivedFrom);
typeList.get_net_type_data(isServer, it->second.netTypeID).readUpdateFunc(NetObjTemporaryPtr<void>(this, id, it->second.p), a, clientReceivedFrom);
}
void NetObjManager::set_client(std::shared_ptr<NetClient> initClient, MessageCommandType initUpdateCommandID) {
client = initClient;

View file

@ -19,7 +19,7 @@
namespace NetworkingObjects {
class NetObjManager {
public:
NetObjManager(std::shared_ptr<NetObjManagerTypeList> initTypeList, bool initIsServer);
NetObjManager(bool initIsServer);
void read_update_message(cereal::PortableBinaryInputArchive& a, const std::shared_ptr<NetServer::ClientData>& clientReceivedFrom);
void set_client(std::shared_ptr<NetClient> initClient, MessageCommandType initUpdateCommandID);
void set_server(std::shared_ptr<NetServer> initServer, MessageCommandType initUpdateCommandID);
@ -30,8 +30,8 @@ namespace NetworkingObjects {
auto it = objectData.find(id);
if(it != objectData.end())
throw std::runtime_error("[NetObjManager::read_create_message] Attempted to create an object with a used ID");
NetObjOwnerPtr<T> newPtr = emplace_raw_ptr(id, static_cast<T*>(typeList->get_type_index_data<T>(isServer).allocatorFunc()));
typeList->get_type_index_data<T>(isServer).readConstructorFunc(NetObjTemporaryPtr(newPtr).template cast<void>(), a, clientReceivedFrom);
NetObjOwnerPtr<T> newPtr = emplace_raw_ptr(id, static_cast<T*>(typeList.get_type_index_data<T>(isServer).allocatorFunc()));
typeList.get_type_index_data<T>(isServer).readConstructorFunc(NetObjTemporaryPtr(newPtr).template cast<void>(), a, clientReceivedFrom);
return newPtr;
}
template <typename T> NetObjTemporaryPtr<T> read_get_obj_ref_from_message(cereal::PortableBinaryInputArchive& a) {
@ -43,7 +43,7 @@ namespace NetworkingObjects {
return NetObjTemporaryPtr<T>(this, id, std::static_pointer_cast<T>(it->second.p));
}
template <typename T> NetObjOwnerPtr<T> make_obj() {
return emplace_raw_ptr<T>(NetObjID::random_gen(), static_cast<T*>(typeList->get_type_index_data<T>(isServer).allocatorFunc()));
return emplace_raw_ptr<T>(NetObjID::random_gen(), static_cast<T*>(typeList.get_type_index_data<T>(isServer).allocatorFunc()));
}
// Don't use this function unless you're sure that class T isn't a base class
template <typename T, typename... Args> NetObjOwnerPtr<T> make_obj_direct(Args&&... items) {
@ -58,9 +58,12 @@ namespace NetworkingObjects {
throw std::runtime_error("[NetObjManager::get_obj_from_id] ID doesn't exist");
return NetObjOwnerPtr<T>(this, id, static_cast<T*>(it->second.p));
}
template <typename ClientT, typename ServerT, typename ClientAllocatedType, typename ServerAllocatedType> void register_class(const NetObjManagerTypeList::ServerClientClassFunctions<ClientT, ServerT>& funcs) {
typeList.register_class<ClientT, ServerT, ClientAllocatedType, ServerAllocatedType>(funcs);
}
private:
template <typename T> NetObjOwnerPtr<T> emplace_raw_ptr(NetObjID id, T* rawPtr) {
if(!objectData.emplace(id, SingleObjectData{.netTypeID = typeList->get_type_index_data<T>(isServer).netTypeID, .p = rawPtr}).second)
if(!objectData.emplace(id, SingleObjectData{.netTypeID = typeList.get_type_index_data<T>(isServer).netTypeID, .p = rawPtr}).second)
throw std::runtime_error("[NetObjManager::emplace_raw_ptr] ID Collision");
return NetObjOwnerPtr<T>(this, id, rawPtr);
}
@ -122,7 +125,7 @@ namespace NetworkingObjects {
template <typename T> static void write_create_message(const NetObjTemporaryPtr<T>& ptr, cereal::PortableBinaryOutputArchive& a) {
a(ptr.get_net_id());
ptr.get_obj_man()->typeList->template get_type_index_data<T>(ptr.get_obj_man()->isServer).writeConstructorFunc(ptr.template cast<void>(), a);
ptr.get_obj_man()->typeList.template get_type_index_data<T>(ptr.get_obj_man()->isServer).writeConstructorFunc(ptr.template cast<void>(), a);
}
template <typename T> friend class NetObjOwnerPtr;
@ -139,7 +142,7 @@ namespace NetworkingObjects {
std::shared_ptr<NetServer> server;
MessageCommandType updateCommandID;
std::unordered_map<NetObjID, SingleObjectData> objectData;
std::shared_ptr<NetObjManagerTypeList> typeList;
NetObjManagerTypeList typeList;
NetTypeIDType nextTypeID;
};
}

View file

@ -20,8 +20,7 @@ class NetObjManagerTypeList {
template <typename ClientT, typename ServerT, typename ClientAllocatedType, typename ServerAllocatedType> void register_class(const ServerClientClassFunctions<ClientT, ServerT>& funcs) {
typeIndexFunctionsClient[std::type_index(typeid(ClientT*))] = TypeIndexFunctions {
.readConstructorFunc = [f = funcs.readConstructorFuncClient](const NetObjTemporaryPtr<void>& obj, cereal::PortableBinaryInputArchive& message, const std::shared_ptr<NetServer::ClientData>& c) {
if(f)
f(obj.cast<ClientT>(), message, c);
f(obj.cast<ClientT>(), message, c);
},
.writeConstructorFunc = [f = funcs.writeConstructorFuncClient](const NetObjTemporaryPtr<void>& obj, cereal::PortableBinaryOutputArchive& message) {
f(obj.cast<ClientT>(), message);
@ -32,8 +31,7 @@ class NetObjManagerTypeList {
typeIndexFunctionsServer[std::type_index(typeid(ServerT*))] = TypeIndexFunctions {
.readConstructorFunc = [f = funcs.readConstructorFuncServer](const NetObjTemporaryPtr<void>& obj, cereal::PortableBinaryInputArchive& message, const std::shared_ptr<NetServer::ClientData>& c) {
if(f)
f(obj.cast<ServerT>(), message, c);
f(obj.cast<ServerT>(), message, c);
},
.writeConstructorFunc = [f = funcs.writeConstructorFuncServer](const NetObjTemporaryPtr<void>& obj, cereal::PortableBinaryOutputArchive& message) {
f(obj.cast<ServerT>(), message);
@ -44,15 +42,13 @@ class NetObjManagerTypeList {
netTypeIDFunctionsClient[netTypeID] = NetTypeIDFunctions {
.readUpdateFunc = [f = funcs.readUpdateFuncClient](const NetObjTemporaryPtr<void>& obj, cereal::PortableBinaryInputArchive& message, const std::shared_ptr<NetServer::ClientData>& c) {
if(f)
f(obj.cast<ClientT>(), message, c);
f(obj.cast<ClientT>(), message, c);
}
};
netTypeIDFunctionsServer[netTypeID] = NetTypeIDFunctions {
.readUpdateFunc = [f = funcs.readUpdateFuncServer](const NetObjTemporaryPtr<void>& obj, cereal::PortableBinaryInputArchive& message, const std::shared_ptr<NetServer::ClientData>& c) {
if(f)
f(obj.cast<ServerT>(), message, c);
f(obj.cast<ServerT>(), message, c);
}
};

View file

@ -39,38 +39,38 @@ namespace NetworkingObjects {
template <typename T> class NetObjOrderedList {
public:
// Don't use this function unless you're sure that class T isn't a base class
template <typename ...Args> NetObjTemporaryPtr<T> emplace_back_direct(const NetObjTemporaryPtr<NetObjOrderedList<T>>& l, Args&&... items) {
template <typename ...Args> const NetObjOrderedListObjectInfoPtr<T>& emplace_back_direct(const NetObjTemporaryPtr<NetObjOrderedList<T>>& l, Args&&... items) {
NetObjOwnerPtr<T> newObj = l.get_obj_man()->template make_obj_direct<T>(items...);
NetObjTemporaryPtr<T> tempPtr(newObj);
l->insert(l, nullptr, l->size(), std::move(newObj));
return tempPtr;
return l->insert(l, nullptr, l->size(), std::move(newObj));
}
static void push_back_and_send_create(const NetObjTemporaryPtr<NetObjOrderedList<T>>& l, T* newObj) {
l->insert(l, nullptr, l->size(), newObj);
static const NetObjOrderedListObjectInfoPtr<T>& push_back_and_send_create(const NetObjTemporaryPtr<NetObjOrderedList<T>>& l, T* newObj) {
NetObjOwnerPtr<T> newObjOwner = l.get_obj_man()->template make_obj<T>(newObj);
return l->insert(l, nullptr, l->size(), std::move(newObjOwner));
}
static void insert_and_send_create(const NetObjTemporaryPtr<NetObjOrderedList<T>>& l, uint32_t posToInsertAt, const NetObjTemporaryPtr<T>& newObj) {
l->insert(l, nullptr, posToInsertAt, newObj);
static const NetObjOrderedListObjectInfoPtr<T>& insert_and_send_create(const NetObjTemporaryPtr<NetObjOrderedList<T>>& l, uint32_t posToInsertAt, T* newObj) {
NetObjOwnerPtr<T> newObjOwner = l.get_obj_man()->template make_obj<T>(newObj);
return l->insert(l, nullptr, posToInsertAt, std::move(newObjOwner));
}
static void erase(const NetObjTemporaryPtr<NetObjOrderedList<T>>& l, uint32_t indexToErase) {
return l->erase_by_index(l, indexToErase);
l->erase_by_index(l, indexToErase);
}
static uint32_t erase(const NetObjTemporaryPtr<NetObjOrderedList<T>>& l, const NetObjTemporaryPtr<T>& p) {
return l->erase_by_ptr(l, p);
}
virtual bool contains(const NetObjTemporaryPtr<T>& p) const = 0;
virtual uint32_t size() const = 0;
virtual const NetObjOwnerPtr<T>& at(uint32_t index) const = 0;
virtual const NetObjOrderedListObjectInfoPtr<T>& at(uint32_t index) const = 0;
virtual bool empty() const = 0;
virtual ~NetObjOrderedList() {}
protected:
virtual void insert(const NetObjTemporaryPtr<NetObjOrderedList<T>>& l, const std::shared_ptr<NetServer::ClientData>& clientInserting, uint32_t posToInsertAt, NetObjOwnerPtr<T> newObj) = 0;
virtual const NetObjOrderedListObjectInfoPtr<T>& insert(const NetObjTemporaryPtr<NetObjOrderedList<T>>& l, const std::shared_ptr<NetServer::ClientData>& clientInserting, uint32_t posToInsertAt, NetObjOwnerPtr<T> newObj) = 0;
virtual void erase_by_index(const NetObjTemporaryPtr<NetObjOrderedList<T>>& l, uint32_t indexToErase) = 0;
virtual uint32_t erase_by_ptr(const NetObjTemporaryPtr<NetObjOrderedList<T>>& l, const NetObjTemporaryPtr<T>& p) = 0;
virtual void write_constructor(const NetObjTemporaryPtr<NetObjOrderedList<T>>& l, cereal::PortableBinaryOutputArchive& a) = 0;
virtual void read_update(const NetObjTemporaryPtr<NetObjOrderedList<T>>& l, cereal::PortableBinaryInputArchive& a, const std::shared_ptr<NetServer::ClientData>&) = 0;
virtual void read_constructor(const NetObjTemporaryPtr<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);
template <typename S> friend void register_ordered_list_class(NetObjManager& t);
static void write_constructor_func(const NetObjTemporaryPtr<NetObjOrderedList<T>>& l, cereal::PortableBinaryOutputArchive& a) {
l->write_constructor(l, a);
}
@ -91,14 +91,14 @@ namespace NetworkingObjects {
virtual uint32_t size() const override {
return data.size();
}
virtual const NetObjOwnerPtr<T>& at(uint32_t index) const override {
return data[index]->obj;
virtual const NetObjOrderedListObjectInfoPtr<T>& at(uint32_t index) const override {
return data[index];
}
virtual bool empty() const override {
return data.empty();
}
protected:
virtual void insert(const NetObjTemporaryPtr<NetObjOrderedList<T>>& l, const std::shared_ptr<NetServer::ClientData>& clientInserting, uint32_t posToInsertAt, NetObjOwnerPtr<T> newObj) override {
virtual const NetObjOrderedListObjectInfoPtr<T>& insert(const NetObjTemporaryPtr<NetObjOrderedList<T>>& l, const std::shared_ptr<NetServer::ClientData>& clientInserting, uint32_t posToInsertAt, NetObjOwnerPtr<T> newObj) override {
posToInsertAt = std::min<uint32_t>(posToInsertAt, data.size());
auto newObjInfoPtr = std::make_shared<NetObjOrderedListObjectInfo<T>>(std::move(newObj), 0);
data.insert(data.begin() + posToInsertAt, newObjInfoPtr);
@ -111,6 +111,7 @@ namespace NetworkingObjects {
a(ObjPtrOrderedListCommand_StoC::INSERT_SINGLE_REFERENCE, posToInsertAt, newObjInfoPtr->obj.get_net_id());
});
set_positions_for_object_info_vector<T>(data, posToInsertAt);
return data[posToInsertAt];
}
virtual void erase_by_index(const NetObjTemporaryPtr<NetObjOrderedList<T>>& l, uint32_t indexToErase) override {
if(data.empty())
@ -188,14 +189,14 @@ namespace NetworkingObjects {
virtual uint32_t size() const override {
return clientData.size();
}
virtual const NetObjOwnerPtr<T>& at(uint32_t index) const override {
return clientData[index]->obj;
virtual const NetObjOrderedListObjectInfoPtr<T>& at(uint32_t index) const override {
return clientData[index];
}
virtual bool empty() const override {
return clientData.empty();
}
protected:
virtual void insert(const NetObjTemporaryPtr<NetObjOrderedList<T>>& l, const std::shared_ptr<NetServer::ClientData>&, uint32_t posToInsertAt, NetObjOwnerPtr<T> newObj) {
virtual const NetObjOrderedListObjectInfoPtr<T>& insert(const NetObjTemporaryPtr<NetObjOrderedList<T>>& l, const std::shared_ptr<NetServer::ClientData>&, uint32_t posToInsertAt, NetObjOwnerPtr<T> newObj) {
posToInsertAt = std::min<uint32_t>(posToInsertAt, clientData.size());
auto newObjInfoPtr = std::make_shared<NetObjOrderedListObjectInfo<T>>(std::move(newObj), 0);
clientData.insert(clientData.begin() + posToInsertAt, newObjInfoPtr);
@ -206,6 +207,7 @@ namespace NetworkingObjects {
newObjInfoPtr->obj.write_create_message(a);
});
set_positions_for_object_info_vector<T>(clientData, posToInsertAt);
return clientData[posToInsertAt];
}
virtual void erase_by_index(const NetObjTemporaryPtr<NetObjOrderedList<T>>& l, uint32_t indexToErase) override {
if(clientData.empty())
@ -329,8 +331,8 @@ namespace NetworkingObjects {
std::unordered_map<NetObjID, NetObjOrderedListObjectInfoPtr<T>> clientJustInsertedSyncIgnore;
};
template <typename S> void register_ordered_list_class(NetObjManagerTypeList& t) {
t.register_class<NetObjOrderedList<S>, NetObjOrderedList<S>, NetObjOrderedListClient<S>, NetObjOrderedListServer<S>>({
template <typename S> void register_ordered_list_class(NetObjManager& objMan) {
objMan.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,

View file

@ -7,7 +7,6 @@
#include "NetObjOwnerPtr.decl.hpp"
#include "NetObjTemporaryPtr.hpp"
#include "NetObjManager.hpp"
#include "NetObjManagerTypeList.hpp"
namespace NetworkingObjects {
template <typename T> NetObjOwnerPtr<T>::NetObjOwnerPtr():

View file

@ -6,7 +6,6 @@
#include <type_traits>
#include "NetObjTemporaryPtr.decl.hpp"
#include "NetObjManager.hpp"
#include "NetObjManagerTypeList.hpp"
namespace NetworkingObjects {
template <typename T> NetObjTemporaryPtr<T>::NetObjTemporaryPtr():