Started canvas component work, and moving to unique network pointers (build is broken)
This commit is contained in:
parent
d3d080620a
commit
5b5aef8369
33 changed files with 750 additions and 468 deletions
|
|
@ -79,6 +79,9 @@ set(sources "src/main.cpp"
|
|||
"src/DrawingProgram/EllipseDrawEditTool.cpp"
|
||||
"src/DrawingProgram/RectDrawEditTool.cpp"
|
||||
"src/DrawingProgram/TextBoxEditTool.cpp"
|
||||
#"src/CanvasComponents/CanvasComponentContainer.cpp"
|
||||
#"src/CanvasComponents/CanvasComponentBrushStroke.cpp"
|
||||
#"src/CanvasComponents/CanvasComponent.cpp"
|
||||
"src/DrawComponents/DrawEllipse.cpp"
|
||||
"src/DrawComponents/DrawRectangle.cpp"
|
||||
"src/DrawComponents/DrawImage.cpp"
|
||||
|
|
|
|||
|
|
@ -9,16 +9,16 @@ namespace NetworkingObjects {
|
|||
public:
|
||||
template <typename T> void register_class(NetObjManagerTypeList& t) {
|
||||
t.register_class<T, T, T, T>({
|
||||
.writeConstructorFuncClient = [&](const NetObjPtr<T>& o, cereal::PortableBinaryOutputArchive& a){client_write_func<T>(std::nullopt, o, a);},
|
||||
.readConstructorFuncClient = [&](const NetObjPtr<T>& o, cereal::PortableBinaryInputArchive& a, const std::shared_ptr<NetServer::ClientData>&){delay_read_func<T>(o, a);},
|
||||
.readUpdateFuncClient = [&](const NetObjPtr<T>& o, cereal::PortableBinaryInputArchive& a, const std::shared_ptr<NetServer::ClientData>&){delay_read_func<T>(o, a);},
|
||||
.writeConstructorFuncServer = [&](const NetObjPtr<T>& o, cereal::PortableBinaryOutputArchive& a){server_write_func<T>(o, a);},
|
||||
.readConstructorFuncServer = [&](const NetObjPtr<T>& o, cereal::PortableBinaryInputArchive& a, const std::shared_ptr<NetServer::ClientData>&){delay_read_func<T>(o, a);},
|
||||
.readUpdateFuncServer = [&](const NetObjPtr<T>& o, cereal::PortableBinaryInputArchive& a, const std::shared_ptr<NetServer::ClientData>&){server_read_update_func<T>(o, a);}
|
||||
.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);},
|
||||
.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::NetObjPtr<T>& o, bool finalUpdate) {
|
||||
o.send_update_to_all(finalUpdate ? RELIABLE_COMMAND_CHANNEL : UNRELIABLE_COMMAND_CHANNEL, [&](const NetObjPtr<T>& o, cereal::PortableBinaryOutputArchive& a) {
|
||||
template <typename T> void send_update_to_all(const NetworkingObjects::NetObjTemporaryPtr<T>& o, 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);
|
||||
else
|
||||
|
|
@ -27,7 +27,7 @@ namespace NetworkingObjects {
|
|||
}
|
||||
void update();
|
||||
private:
|
||||
template <typename T> void client_write_func(std::optional<bool> finalUpdate, const NetObjPtr<T>& o, cereal::PortableBinaryOutputArchive& a) {
|
||||
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());
|
||||
a(*o);
|
||||
|
|
@ -35,10 +35,11 @@ namespace NetworkingObjects {
|
|||
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]() {
|
||||
NetObjPtr<T> oLock = oWeak.lock();
|
||||
if(oLock)
|
||||
toAdd.setDataAfterTimeout = [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);
|
||||
};
|
||||
updatingObjs.emplace(o.get_net_id(), toAdd);
|
||||
|
|
@ -49,28 +50,34 @@ namespace NetworkingObjects {
|
|||
}
|
||||
}
|
||||
|
||||
template <typename T> void delay_read_func(const NetObjPtr<T>& o, cereal::PortableBinaryInputArchive& a) {
|
||||
template <typename T> void delay_read_func_constructor(const NetObjTemporaryPtr<T>& o, cereal::PortableBinaryInputArchive& a) {
|
||||
a(*o);
|
||||
}
|
||||
|
||||
template <typename T> void delay_read_func(const NetObjTemporaryPtr<T>& o, cereal::PortableBinaryInputArchive& a) {
|
||||
auto it = updatingObjs.find(o.get_net_id());
|
||||
if(it == updatingObjs.end())
|
||||
a(*o);
|
||||
else {
|
||||
auto& [netID, updatingObjData] = *it;
|
||||
a(*std::static_pointer_cast<T>(updatingObjData.objToUpdateCurrentData));
|
||||
*updatingObjData.doLastAssignment = true;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T> void server_write_func(const NetObjPtr<T>& o, cereal::PortableBinaryOutputArchive& a) {
|
||||
template <typename T> void server_write_func(const NetObjTemporaryPtr<T>& o, cereal::PortableBinaryOutputArchive& a) {
|
||||
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.setDataAfterTimeout = [oWeak = NetObjWeakPtr<T>(o), currentData = toAdd.objToUpdateCurrentData]() {
|
||||
NetObjPtr<T> oLock = oWeak.lock();
|
||||
if(oLock) {
|
||||
toAdd.doLastAssignment = std::make_shared<bool>(false);
|
||||
toAdd.setDataAfterTimeout = [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);
|
||||
oLock.send_server_update_to_all_clients(RELIABLE_COMMAND_CHANNEL, [](const NetObjPtr<T>& o, cereal::PortableBinaryOutputArchive& a) {
|
||||
oLock.send_server_update_to_all_clients(RELIABLE_COMMAND_CHANNEL, [](const NetObjTemporaryPtr<T>& o, cereal::PortableBinaryOutputArchive& a) {
|
||||
a(*o);
|
||||
});
|
||||
}
|
||||
|
|
@ -81,26 +88,29 @@ namespace NetworkingObjects {
|
|||
auto& [netID, updatingObjData] = *it;
|
||||
updatingObjData.lastUpdateTimePoint = std::chrono::steady_clock::now();
|
||||
*std::static_pointer_cast<T>(updatingObjs[o.get_net_id()].objToUpdateCurrentData) = *o;
|
||||
*updatingObjData.doLastAssignment = false;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T> void server_read_update_func(const NetObjPtr<T>& o, cereal::PortableBinaryInputArchive& a) {
|
||||
template <typename T> void server_read_update_func(const NetObjTemporaryPtr<T>& o, cereal::PortableBinaryInputArchive& a) {
|
||||
auto it = updatingObjs.find(o.get_net_id());
|
||||
bool finalUpdate;
|
||||
if(it == updatingObjs.end()) {
|
||||
a(finalUpdate, *o);
|
||||
o.send_server_update_to_all_clients(finalUpdate ? RELIABLE_COMMAND_CHANNEL : UNRELIABLE_COMMAND_CHANNEL, [](const NetObjPtr<T>& o, cereal::PortableBinaryOutputArchive& a) {
|
||||
o.send_server_update_to_all_clients(finalUpdate ? RELIABLE_COMMAND_CHANNEL : UNRELIABLE_COMMAND_CHANNEL, [](const NetObjTemporaryPtr<T>& o, cereal::PortableBinaryOutputArchive& a) {
|
||||
a(*o);
|
||||
});
|
||||
}
|
||||
else {
|
||||
auto& [netID, updatingObjData] = *it;
|
||||
a(finalUpdate, *std::static_pointer_cast<T>(updatingObjData.objToUpdateCurrentData));
|
||||
*updatingObjData.doLastAssignment = true;
|
||||
}
|
||||
}
|
||||
|
||||
struct UpdatingObject {
|
||||
std::shared_ptr<void> objToUpdateCurrentData;
|
||||
std::shared_ptr<bool> doLastAssignment;
|
||||
std::chrono::steady_clock::time_point lastUpdateTimePoint;
|
||||
std::function<void()> setDataAfterTimeout;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,34 +1,38 @@
|
|||
#pragma once
|
||||
#include "NetObjPtr.hpp"
|
||||
#include "NetObjTemporaryPtr.hpp"
|
||||
#include "cereal/archives/portable_binary.hpp"
|
||||
#include <chrono>
|
||||
|
||||
namespace NetworkingObjects {
|
||||
template <typename T> void default_serialize_write_func(const NetObjPtr<T>& o, cereal::PortableBinaryOutputArchive& a) {
|
||||
template <typename T> void default_serialize_write_func(const NetObjTemporaryPtr<T>& o, cereal::PortableBinaryOutputArchive& a) {
|
||||
a(*o);
|
||||
}
|
||||
|
||||
template <typename T> void default_serialize_read_func(const NetObjPtr<T>& o, cereal::PortableBinaryInputArchive& a, const std::shared_ptr<NetServer::ClientData>&) {
|
||||
template <typename T> void default_serialize_read_func_client(const NetObjTemporaryPtr<T>& o, cereal::PortableBinaryInputArchive& a, const std::shared_ptr<NetServer::ClientData>&) {
|
||||
a(*o);
|
||||
}
|
||||
|
||||
template <typename T> void default_serialize_read_constructor_func(NetObjManager*, const std::shared_ptr<T>& o, cereal::PortableBinaryInputArchive& a, const std::shared_ptr<NetServer::ClientData>&) {
|
||||
a(*o);
|
||||
}
|
||||
|
||||
template <typename T> void register_generic_serialized_class(NetObjManagerTypeList& t) {
|
||||
t.register_class<T, T, T, T>({
|
||||
.writeConstructorFuncClient = default_serialize_write_func<T>,
|
||||
.readConstructorFuncClient = default_serialize_read_func<T>,
|
||||
.readUpdateFuncClient = default_serialize_read_func<T>,
|
||||
.readConstructorFuncClient = default_serialize_read_constructor_func<T>,
|
||||
.readUpdateFuncClient = default_serialize_read_func_client<T>,
|
||||
.writeConstructorFuncServer = default_serialize_write_func<T>,
|
||||
.readConstructorFuncServer = default_serialize_read_func<T>,
|
||||
.readUpdateFuncServer = [](const NetObjPtr<T>& o, cereal::PortableBinaryInputArchive& a, const std::shared_ptr<NetServer::ClientData>&) {
|
||||
.readConstructorFuncServer = default_serialize_read_constructor_func<T>,
|
||||
.readUpdateFuncServer = [](const NetObjTemporaryPtr<T>& o, cereal::PortableBinaryInputArchive& a, const std::shared_ptr<NetServer::ClientData>&) {
|
||||
a(*o);
|
||||
o.send_server_update_to_all_clients(RELIABLE_COMMAND_CHANNEL, [](const NetObjPtr<T>& o, cereal::PortableBinaryOutputArchive& a) {
|
||||
o.send_server_update_to_all_clients(RELIABLE_COMMAND_CHANNEL, [](const NetObjTemporaryPtr<T>& o, cereal::PortableBinaryOutputArchive& a) {
|
||||
a(*o);
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
template <typename T> void generic_serialized_class_send_update_to_all(const NetworkingObjects::NetObjPtr<T>& o) {
|
||||
template <typename T> void generic_serialized_class_send_update_to_all(const NetworkingObjects::NetObjTemporaryPtr<T>& o) {
|
||||
o.send_update_to_all(RELIABLE_COMMAND_CHANNEL, default_serialize_write_func<T>);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
#include "NetObjManager.hpp"
|
||||
#include "NetObjPtr.hpp"
|
||||
#include "NetObjTemporaryPtr.hpp"
|
||||
|
||||
namespace NetworkingObjects {
|
||||
NetObjManager::NetObjManager(std::shared_ptr<NetObjManagerTypeList> initTypeList, bool initIsServer):
|
||||
|
|
@ -16,7 +16,7 @@ namespace NetworkingObjects {
|
|||
auto it = objectData.find(id);
|
||||
if(it == objectData.end())
|
||||
return;
|
||||
typeList->get_net_type_data(isServer, it->second.netTypeID).readUpdateFunc(NetObjPtr<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;
|
||||
|
|
|
|||
|
|
@ -12,7 +12,8 @@
|
|||
#include "../Networking/NetLibrary.hpp"
|
||||
#include "Helpers/NetworkingObjects/NetObjID.hpp"
|
||||
#include "NetObjManagerTypeList.hpp"
|
||||
#include "NetObjPtr.decl.hpp"
|
||||
#include "NetObjOwnerPtr.decl.hpp"
|
||||
#include "NetObjTemporaryPtr.decl.hpp"
|
||||
#include "../Networking/NetServer.hpp"
|
||||
|
||||
namespace NetworkingObjects {
|
||||
|
|
@ -23,14 +24,17 @@ 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) {
|
||||
template <typename T> NetObjOwnerPtr<T> read_create_message(cereal::PortableBinaryInputArchive& a, const std::shared_ptr<NetServer::ClientData>& clientReceivedFrom) {
|
||||
NetObjID id;
|
||||
a(id);
|
||||
NetObjPtr<T> newPtr = make_obj_with_id_might_already_exist<T>(id);
|
||||
typeList->get_type_index_data<T>(isServer).readConstructorFunc(newPtr.template cast<void>(), a, clientReceivedFrom);
|
||||
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, typeList->get_type_index_data<T>(isServer).allocatorFunc());
|
||||
typeList->get_type_index_data<T>(isServer).readConstructorFunc(newPtr, a, clientReceivedFrom);
|
||||
return newPtr;
|
||||
}
|
||||
template <typename T> NetObjPtr<T> read_get_obj_from_message(cereal::PortableBinaryInputArchive& a) {
|
||||
template <typename T> NetObjTemporaryPtr<T> read_get_obj_ref_from_message(cereal::PortableBinaryInputArchive& a) {
|
||||
NetObjID id;
|
||||
a(id);
|
||||
auto it = objectData.find(id);
|
||||
|
|
@ -38,42 +42,96 @@ namespace NetworkingObjects {
|
|||
return NetObjPtr<T>();
|
||||
return NetObjPtr<T>(this, id, std::static_pointer_cast<T>(it->second.p));
|
||||
}
|
||||
template <typename T> NetObjPtr<T> make_obj() {
|
||||
return emplace_shared_ptr<T>(NetObjID::random_gen(), std::static_pointer_cast<T>(typeList->get_type_index_data<T>(isServer).allocatorFunc()));
|
||||
template <typename T> NetObjOwnerPtr<T> make_obj() {
|
||||
return emplace_raw_ptr<T>(NetObjID::random_gen(), 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> NetObjPtr<T> make_obj_direct(Args&&... items) {
|
||||
return emplace_shared_ptr<T>(NetObjID::random_gen(), std::make_shared<T>(items...));
|
||||
template <typename T, typename... Args> NetObjOwnerPtr<T> make_obj_direct(Args&&... items) {
|
||||
return emplace_raw_ptr<T>(NetObjID::random_gen(), new T(items...));
|
||||
}
|
||||
template <typename T> NetObjPtr<T> obj_from_ptr(T* p) {
|
||||
return emplace_shared_ptr<T>(NetObjID::random_gen(), std::shared_ptr<T>(p));
|
||||
template <typename T> NetObjOwnerPtr<T> obj_from_ptr(T* p) {
|
||||
return emplace_raw_ptr<T>(NetObjID::random_gen(), p);
|
||||
}
|
||||
template <typename T> NetObjPtr<T> get_obj_from_id(NetObjID id) {
|
||||
template <typename T> NetObjOwnerPtr<T> get_obj_ref_from_id(NetObjID id) {
|
||||
auto it = objectData.find(id);
|
||||
if(it == objectData.end())
|
||||
throw std::runtime_error("[NetObjManager::get_obj_from_id] ID doesn't exist");
|
||||
return NetObjPtr<T>(this, id, std::static_pointer_cast<T>(it->second.p));
|
||||
}
|
||||
private:
|
||||
template <typename T> NetObjPtr<T> make_obj_with_id_might_already_exist(NetObjID id) {
|
||||
auto alreadyExistsIt = objectData.find(id);
|
||||
if(alreadyExistsIt != objectData.end())
|
||||
return NetObjPtr<T>(this, id, std::static_pointer_cast<T>(alreadyExistsIt->second.p));
|
||||
return emplace_shared_ptr<T>(id, std::static_pointer_cast<T>(typeList->get_type_index_data<T>(isServer).allocatorFunc()));
|
||||
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)
|
||||
throw std::runtime_error("[NetObjManager::emplace_raw_ptr] ID Collision");
|
||||
return NetObjOwnerPtr<T>(this, id, rawPtr);
|
||||
}
|
||||
|
||||
template <typename T> NetObjPtr<T> emplace_shared_ptr(NetObjID id, const std::shared_ptr<T>& sharedPtr) {
|
||||
if(!objectData.emplace(id, SingleObjectData{.netTypeID = typeList->get_type_index_data<T>(isServer).netTypeID, .p = std::static_pointer_cast<void>(sharedPtr)}).second)
|
||||
throw std::runtime_error("[NetObjManager::emplace_shared_ptr] ID Collision");
|
||||
return NetObjPtr<T>(this, id, sharedPtr);
|
||||
template <typename T> static void send_update_to_all(const NetObjTemporaryPtr<T>& ptr, const std::string& channel, std::function<void(const NetObjTemporaryPtr<T>&, cereal::PortableBinaryOutputArchive&)> sendUpdateFunc) {
|
||||
if(ptr.get_obj_man()->isServer)
|
||||
NetObjManager::send_server_update_to_all_clients(ptr, channel, sendUpdateFunc);
|
||||
else
|
||||
NetObjManager::send_client_update(ptr, channel, sendUpdateFunc);
|
||||
}
|
||||
|
||||
template <typename T> friend class NetObjPtr;
|
||||
template <typename T> static void send_client_update(const NetObjTemporaryPtr<T>& ptr, const std::string& channel, std::function<void(const NetObjTemporaryPtr<T>&, cereal::PortableBinaryOutputArchive&)> sendUpdateFunc) {
|
||||
if(ptr.get_obj_man()->client && !ptr.get_obj_man()->client->is_disconnected()) {
|
||||
auto ss(std::make_shared<std::stringstream>());
|
||||
{
|
||||
cereal::PortableBinaryOutputArchive m(*ss);
|
||||
m(ptr.get_obj_man()->updateCommandID, ptr.get_net_id());
|
||||
sendUpdateFunc(ptr, m);
|
||||
}
|
||||
ptr.get_obj_man()->client->send_string_stream_to_server(channel, ss);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T> static void send_server_update_to_client(const NetObjTemporaryPtr<T>& ptr, const std::shared_ptr<NetServer::ClientData>& clientToSendTo, const std::string& channel, std::function<void(const NetObjTemporaryPtr<T>&, cereal::PortableBinaryOutputArchive&)> sendUpdateFunc) {
|
||||
if(ptr.get_obj_man()->server && !ptr.get_obj_man()->server->is_disconnected()) {
|
||||
auto ss(std::make_shared<std::stringstream>());
|
||||
{
|
||||
cereal::PortableBinaryOutputArchive m(*ss);
|
||||
m(ptr.get_obj_man()->updateCommandID, ptr.get_net_id());
|
||||
sendUpdateFunc(ptr, m);
|
||||
}
|
||||
ptr.get_obj_man()->server->send_string_stream_to_client(clientToSendTo, channel, ss);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T> static void send_server_update_to_all_clients_except(const NetObjTemporaryPtr<T>& ptr, const std::shared_ptr<NetServer::ClientData>& clientToNotSendTo, const std::string& channel, std::function<void(const NetObjTemporaryPtr<T>&, cereal::PortableBinaryOutputArchive&)> sendUpdateFunc) {
|
||||
if(ptr.get_obj_man()->server && !ptr.get_obj_man()->server->is_disconnected()) {
|
||||
auto ss(std::make_shared<std::stringstream>());
|
||||
{
|
||||
cereal::PortableBinaryOutputArchive m(*ss);
|
||||
m(ptr.get_obj_man()->updateCommandID, ptr.get_net_id());
|
||||
sendUpdateFunc(ptr, m);
|
||||
}
|
||||
ptr.get_obj_man()->server->send_string_stream_to_all_clients_except(clientToNotSendTo, channel, ss);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T> static void send_server_update_to_all_clients(const NetObjTemporaryPtr<T>& ptr, const std::string& channel, std::function<void(const NetObjTemporaryPtr<T>&, cereal::PortableBinaryOutputArchive&)> sendUpdateFunc) {
|
||||
if(ptr.get_obj_man()->server && !ptr.get_obj_man()->server->is_disconnected()) {
|
||||
auto ss(std::make_shared<std::stringstream>());
|
||||
{
|
||||
cereal::PortableBinaryOutputArchive m(*ss);
|
||||
m(ptr.get_obj_man()->updateCommandID, ptr.get_net_id());
|
||||
sendUpdateFunc(ptr, m);
|
||||
}
|
||||
ptr.get_obj_man()->server->send_string_stream_to_all_clients(channel, ss);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T> static void write_create_message(const NetObjTemporaryPtr<T>& ptr, cereal::PortableBinaryOutputArchive& a) {
|
||||
a(ptr.get_obj_man()->id);
|
||||
ptr.get_obj_man()->typeList->template get_type_index_data<T>(ptr.get_obj_man()->isServer).writeConstructorFunc(ptr, a);
|
||||
}
|
||||
|
||||
template <typename T> friend class NetObjOwnerPtr;
|
||||
template <typename T> friend class NetObjTemporaryPtr;
|
||||
template <typename T> friend class NetObjWeakPtr;
|
||||
|
||||
struct SingleObjectData {
|
||||
NetTypeIDType netTypeID;
|
||||
std::shared_ptr<void> p;
|
||||
void* p;
|
||||
};
|
||||
|
||||
bool isServer;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#pragma once
|
||||
#include "../Networking/NetLibrary.hpp"
|
||||
#include <cereal/archives/portable_binary.hpp>
|
||||
#include "NetObjPtr.decl.hpp"
|
||||
#include "NetObjTemporaryPtr.decl.hpp"
|
||||
#include "../Networking/NetServer.hpp"
|
||||
|
||||
namespace NetworkingObjects {
|
||||
|
|
@ -9,48 +9,48 @@ namespace NetworkingObjects {
|
|||
class NetObjManagerTypeList {
|
||||
public:
|
||||
template <typename ClientT, typename ServerT> struct ServerClientClassFunctions {
|
||||
std::function<void(const NetObjPtr<ClientT>&, cereal::PortableBinaryOutputArchive&)> writeConstructorFuncClient;
|
||||
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 NetObjTemporaryPtr<ClientT>&, cereal::PortableBinaryOutputArchive&)> writeConstructorFuncClient;
|
||||
std::function<void(const NetObjTemporaryPtr<ClientT>&, cereal::PortableBinaryInputArchive&, const std::shared_ptr<NetServer::ClientData>&)> readConstructorFuncClient;
|
||||
std::function<void(const NetObjTemporaryPtr<ClientT>&, cereal::PortableBinaryInputArchive&, const std::shared_ptr<NetServer::ClientData>&)> readUpdateFuncClient;
|
||||
|
||||
std::function<void(const NetObjPtr<ServerT>&, cereal::PortableBinaryOutputArchive&)> writeConstructorFuncServer;
|
||||
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;
|
||||
std::function<void(const NetObjTemporaryPtr<ServerT>&, cereal::PortableBinaryOutputArchive&)> writeConstructorFuncServer;
|
||||
std::function<void(const NetObjTemporaryPtr<ServerT>&, cereal::PortableBinaryInputArchive&, const std::shared_ptr<NetServer::ClientData>&)> readConstructorFuncServer;
|
||||
std::function<void(const NetObjTemporaryPtr<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) {
|
||||
typeIndexFunctionsClient[std::type_index(typeid(ClientT*))] = TypeIndexFunctions {
|
||||
.readConstructorFunc = [f = funcs.readConstructorFuncClient](const NetObjPtr<void>& obj, cereal::PortableBinaryInputArchive& message, const std::shared_ptr<NetServer::ClientData>& c) {
|
||||
.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);
|
||||
},
|
||||
.writeConstructorFunc = [f = funcs.writeConstructorFuncClient](const NetObjPtr<void>& obj, cereal::PortableBinaryOutputArchive& message) {
|
||||
.writeConstructorFunc = [f = funcs.writeConstructorFuncClient](const NetObjTemporaryPtr<void>& obj, cereal::PortableBinaryOutputArchive& message) {
|
||||
f(obj.cast<ClientT>(), message);
|
||||
},
|
||||
.allocatorFunc = []() { return std::make_shared<ClientAllocatedType>(); },
|
||||
.allocatorFunc = []() { return static_cast<void*>(new ClientAllocatedType); },
|
||||
.netTypeID = netTypeID
|
||||
};
|
||||
|
||||
typeIndexFunctionsServer[std::type_index(typeid(ServerT*))] = TypeIndexFunctions {
|
||||
.readConstructorFunc = [f = funcs.readConstructorFuncServer](const NetObjPtr<void>& obj, cereal::PortableBinaryInputArchive& message, const std::shared_ptr<NetServer::ClientData>& c) {
|
||||
.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);
|
||||
},
|
||||
.writeConstructorFunc = [f = funcs.writeConstructorFuncServer](const NetObjPtr<void>& obj, cereal::PortableBinaryOutputArchive& message) {
|
||||
.writeConstructorFunc = [f = funcs.writeConstructorFuncServer](const NetObjTemporaryPtr<void>& obj, cereal::PortableBinaryOutputArchive& message) {
|
||||
f(obj.cast<ServerT>(), message);
|
||||
},
|
||||
.allocatorFunc = []() { return std::make_shared<ServerAllocatedType>(); },
|
||||
.allocatorFunc = []() { return static_cast<void*>(new ServerAllocatedType); },
|
||||
.netTypeID = netTypeID
|
||||
};
|
||||
|
||||
netTypeIDFunctionsClient[netTypeID] = NetTypeIDFunctions {
|
||||
.readUpdateFunc = [f = funcs.readUpdateFuncClient](const NetObjPtr<void>& obj, cereal::PortableBinaryInputArchive& message, const std::shared_ptr<NetServer::ClientData>& c) {
|
||||
.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);
|
||||
}
|
||||
};
|
||||
|
||||
netTypeIDFunctionsServer[netTypeID] = NetTypeIDFunctions {
|
||||
.readUpdateFunc = [f = funcs.readUpdateFuncServer](const NetObjPtr<void>& obj, cereal::PortableBinaryInputArchive& message, const std::shared_ptr<NetServer::ClientData>& c) {
|
||||
.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);
|
||||
}
|
||||
|
|
@ -60,14 +60,14 @@ class NetObjManagerTypeList {
|
|||
}
|
||||
|
||||
struct TypeIndexFunctions {
|
||||
std::function<void(const NetObjPtr<void>&, cereal::PortableBinaryInputArchive&, const std::shared_ptr<NetServer::ClientData>&)> readConstructorFunc;
|
||||
std::function<void(const NetObjPtr<void>&, cereal::PortableBinaryOutputArchive&)> writeConstructorFunc;
|
||||
std::function<std::shared_ptr<void>()> allocatorFunc;
|
||||
std::function<void(const NetObjTemporaryPtr<void>&, cereal::PortableBinaryInputArchive&, const std::shared_ptr<NetServer::ClientData>&)> readConstructorFunc;
|
||||
std::function<void(const NetObjTemporaryPtr<void>&, cereal::PortableBinaryOutputArchive&)> writeConstructorFunc;
|
||||
std::function<void*()> allocatorFunc;
|
||||
NetTypeIDType netTypeID;
|
||||
};
|
||||
|
||||
struct NetTypeIDFunctions {
|
||||
std::function<void(const NetObjPtr<void>&, cereal::PortableBinaryInputArchive&, const std::shared_ptr<NetServer::ClientData>&)> readUpdateFunc;
|
||||
std::function<void(const NetObjTemporaryPtr<void>&, cereal::PortableBinaryInputArchive&, const std::shared_ptr<NetServer::ClientData>&)> readUpdateFunc;
|
||||
};
|
||||
|
||||
template <typename T> const TypeIndexFunctions& get_type_index_data(bool isServer) {
|
||||
|
|
|
|||
|
|
@ -1,13 +1,15 @@
|
|||
#pragma once
|
||||
#include "Helpers/Networking/NetLibrary.hpp"
|
||||
#include "NetObjPtr.hpp"
|
||||
#include "NetObjOwnerPtr.hpp"
|
||||
#include "NetObjTemporaryPtr.hpp"
|
||||
#include "NetObjID.hpp"
|
||||
#include "cereal/archives/portable_binary.hpp"
|
||||
#include "NetObjManagerTypeList.hpp"
|
||||
|
||||
namespace NetworkingObjects {
|
||||
enum class ObjPtrOrderedListCommand_StoC : uint8_t {
|
||||
INSERT_SINGLE,
|
||||
INSERT_SINGLE_CONSTRUCT,
|
||||
INSERT_SINGLE_REFERENCE,
|
||||
ERASE_SINGLE
|
||||
};
|
||||
|
||||
|
|
@ -17,15 +19,13 @@ namespace NetworkingObjects {
|
|||
};
|
||||
|
||||
template <typename T> struct NetObjOrderedListObjectInfo {
|
||||
NetObjOrderedListObjectInfo(const NetObjPtr<T>& iObj, uint32_t iPos, bool iSyncIgnore):
|
||||
obj(iObj),
|
||||
pos(iPos),
|
||||
syncIgnore(iSyncIgnore)
|
||||
NetObjOrderedListObjectInfo(NetObjOwnerPtr<T> iObj, uint32_t iPos):
|
||||
obj(std::move(iObj)),
|
||||
pos(iPos)
|
||||
{}
|
||||
NetObjOrderedListObjectInfo() = delete;
|
||||
NetObjPtr<T> obj;
|
||||
NetObjOwnerPtr<T> obj;
|
||||
uint32_t pos;
|
||||
bool syncIgnore;
|
||||
};
|
||||
|
||||
template <typename T> using NetObjOrderedListObjectInfoPtr = std::shared_ptr<NetObjOrderedListObjectInfo<T>>;
|
||||
|
|
@ -39,44 +39,45 @@ 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> 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->insert(l, l->size(), newObj);
|
||||
return newObj;
|
||||
template <typename ...Args> NetObjTemporaryPtr<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;
|
||||
}
|
||||
static void push_back_and_send_create(const NetObjPtr<NetObjOrderedList<T>>& l, const NetObjPtr<T>& newObj) {
|
||||
l->insert(l, l->size(), newObj);
|
||||
static void push_back_and_send_create(const NetObjTemporaryPtr<NetObjOrderedList<T>>& l, T* newObj) {
|
||||
l->insert(l, nullptr, l->size(), newObj);
|
||||
}
|
||||
static void insert_and_send_create(const NetObjPtr<NetObjOrderedList<T>>& l, uint32_t posToInsertAt, const NetObjPtr<T>& newObj) {
|
||||
l->insert(l, posToInsertAt, newObj);
|
||||
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 NetObjPtr<T> erase(const NetObjPtr<NetObjOrderedList<T>>& l, uint32_t indexToErase) {
|
||||
static void erase(const NetObjTemporaryPtr<NetObjOrderedList<T>>& l, uint32_t indexToErase) {
|
||||
return l->erase_by_index(l, indexToErase);
|
||||
}
|
||||
static uint32_t erase(const NetObjPtr<NetObjOrderedList<T>>& l, const NetObjPtr<T>& p) {
|
||||
static uint32_t erase(const NetObjTemporaryPtr<NetObjOrderedList<T>>& l, const NetObjTemporaryPtr<T>& p) {
|
||||
return l->erase_by_ptr(l, p);
|
||||
}
|
||||
virtual bool contains(const NetObjPtr<T>& p) const = 0;
|
||||
virtual bool contains(const NetObjTemporaryPtr<T>& p) const = 0;
|
||||
virtual uint32_t size() const = 0;
|
||||
virtual const NetObjPtr<T>& at(uint32_t index) const = 0;
|
||||
virtual const NetObjOwnerPtr<T>& at(uint32_t index) const = 0;
|
||||
virtual bool empty() const = 0;
|
||||
virtual ~NetObjOrderedList() {}
|
||||
protected:
|
||||
virtual void insert(const NetObjPtr<NetObjOrderedList<T>>& l, uint32_t posToInsertAt, const NetObjPtr<T>& newObj) = 0;
|
||||
virtual NetObjPtr<T> erase_by_index(const NetObjPtr<NetObjOrderedList<T>>& l, uint32_t indexToErase) = 0;
|
||||
virtual uint32_t erase_by_ptr(const NetObjPtr<NetObjOrderedList<T>>& l, const NetObjPtr<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(const NetObjPtr<NetObjOrderedList<T>>& l, cereal::PortableBinaryInputArchive& a, const std::shared_ptr<NetServer::ClientData>&) = 0;
|
||||
virtual void 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(NetObjManager* objMan, const std::shared_ptr<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) {
|
||||
static void write_constructor_func(const NetObjTemporaryPtr<NetObjOrderedList<T>>& l, cereal::PortableBinaryOutputArchive& a) {
|
||||
l->write_constructor(l, a);
|
||||
}
|
||||
static void read_constructor_func(const NetObjPtr<NetObjOrderedList<T>>& l, cereal::PortableBinaryInputArchive& a, const std::shared_ptr<NetServer::ClientData>& c) {
|
||||
static void read_constructor_func(const NetObjTemporaryPtr<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) {
|
||||
static void read_update_func(const NetObjTemporaryPtr<NetObjOrderedList<T>>& l, cereal::PortableBinaryInputArchive& a, const std::shared_ptr<NetServer::ClientData>& c) {
|
||||
l->read_update(l, a, c);
|
||||
}
|
||||
};
|
||||
|
|
@ -84,62 +85,46 @@ namespace NetworkingObjects {
|
|||
template <typename T> class NetObjOrderedListServer : public NetObjOrderedList<T> {
|
||||
public:
|
||||
NetObjOrderedListServer() {}
|
||||
virtual bool contains(const NetObjPtr<T>& p) const override {
|
||||
virtual bool contains(const NetObjTemporaryPtr<T>& p) const override {
|
||||
return idToDataMap.contains(p.get_net_id());
|
||||
}
|
||||
virtual uint32_t size() const override {
|
||||
return data.size();
|
||||
}
|
||||
virtual const NetObjPtr<T>& at(uint32_t index) const override {
|
||||
virtual const NetObjOwnerPtr<T>& at(uint32_t index) const override {
|
||||
return data[index]->obj;
|
||||
}
|
||||
virtual bool empty() const override {
|
||||
return data.empty();
|
||||
}
|
||||
protected:
|
||||
virtual void insert(const NetObjPtr<NetObjOrderedList<T>>& l, uint32_t posToInsertAt, const NetObjPtr<T>& newObj) override {
|
||||
uint32_t actualPosToInsertAt = posToInsertAt = std::min<uint32_t>(posToInsertAt, data.size());
|
||||
|
||||
// Find duplicate. If found, erase the duplicate before inserting
|
||||
std::shared_ptr<NetObjOrderedListObjectInfo<T>> newObjInfoPtr;
|
||||
auto itObjAlreadyInData = idToDataMap.find(newObj.get_net_id());
|
||||
if(itObjAlreadyInData != idToDataMap.end()) {
|
||||
uint32_t posToErase = itObjAlreadyInData->second->pos;
|
||||
newObjInfoPtr = data[posToErase];
|
||||
data.erase(data.begin() + posToErase);
|
||||
if(posToErase < actualPosToInsertAt) // Shift insert position if an element was erased before the insert position
|
||||
actualPosToInsertAt--;
|
||||
newObjInfoPtr->pos = actualPosToInsertAt;
|
||||
data.insert(data.begin() + actualPosToInsertAt, newObjInfoPtr);
|
||||
}
|
||||
else {
|
||||
// Insert the new object if no duplicate found
|
||||
newObjInfoPtr = std::make_shared<NetObjOrderedListObjectInfo<T>>(newObj, 0, false);
|
||||
data.insert(data.begin() + actualPosToInsertAt, newObjInfoPtr);
|
||||
idToDataMap.emplace(newObjInfoPtr->obj.get_net_id(), newObjInfoPtr);
|
||||
}
|
||||
|
||||
l.send_server_update_to_all_clients(RELIABLE_COMMAND_CHANNEL, [&newObjInfoPtr, posToInsertAt](const NetObjPtr<NetObjOrderedList<T>>&, cereal::PortableBinaryOutputArchive& a) {
|
||||
a(ObjPtrOrderedListCommand_StoC::INSERT_SINGLE, posToInsertAt); // Dont send actual pos to insert at, since client will check for duplicates on its own and shift the index if necessary
|
||||
virtual void 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);
|
||||
idToDataMap.emplace(newObjInfoPtr->obj.get_net_id(), newObjInfoPtr);
|
||||
l.send_server_update_to_all_clients_except(clientInserting, RELIABLE_COMMAND_CHANNEL, [&newObjInfoPtr, posToInsertAt](const NetObjTemporaryPtr<NetObjOrderedList<T>>&, cereal::PortableBinaryOutputArchive& a) {
|
||||
a(ObjPtrOrderedListCommand_StoC::INSERT_SINGLE_CONSTRUCT, posToInsertAt);
|
||||
newObjInfoPtr->obj.write_create_message(a);
|
||||
});
|
||||
set_positions_for_object_info_vector<T>(data, actualPosToInsertAt);
|
||||
l.send_server_update_to_client(clientInserting, RELIABLE_COMMAND_CHANNEL, [&newObjInfoPtr, posToInsertAt](const NetObjTemporaryPtr<NetObjOrderedList<T>>&, cereal::PortableBinaryOutputArchive& a) {
|
||||
a(ObjPtrOrderedListCommand_StoC::INSERT_SINGLE_REFERENCE, posToInsertAt, newObjInfoPtr->obj.get_net_id());
|
||||
});
|
||||
set_positions_for_object_info_vector<T>(data, posToInsertAt);
|
||||
}
|
||||
virtual NetObjPtr<T> erase_by_index(const NetObjPtr<NetObjOrderedList<T>>& l, uint32_t indexToErase) override {
|
||||
virtual void erase_by_index(const NetObjTemporaryPtr<NetObjOrderedList<T>>& l, uint32_t indexToErase) override {
|
||||
if(data.empty())
|
||||
return {};
|
||||
return;
|
||||
indexToErase = std::min<uint32_t>(indexToErase, data.size() - 1);
|
||||
l.send_server_update_to_all_clients(RELIABLE_COMMAND_CHANNEL, [indexToErase](const NetObjPtr<NetObjOrderedList<T>>&, cereal::PortableBinaryOutputArchive& a) {
|
||||
l.send_server_update_to_all_clients(RELIABLE_COMMAND_CHANNEL, [indexToErase](const NetObjTemporaryPtr<NetObjOrderedList<T>>&, cereal::PortableBinaryOutputArchive& a) {
|
||||
a(ObjPtrOrderedListCommand_StoC::ERASE_SINGLE, indexToErase);
|
||||
});
|
||||
NetObjID idToErase = data[indexToErase]->obj.get_net_id();
|
||||
NetObjPtr<T> toRet = data[indexToErase]->obj;
|
||||
data.erase(data.begin() + indexToErase);
|
||||
idToDataMap.erase(idToErase);
|
||||
set_positions_for_object_info_vector<T>(data, indexToErase);
|
||||
return toRet;
|
||||
}
|
||||
virtual uint32_t erase_by_ptr(const NetObjPtr<NetObjOrderedList<T>>& l, const NetObjPtr<T>& p) override {
|
||||
virtual uint32_t erase_by_ptr(const NetObjTemporaryPtr<NetObjOrderedList<T>>& l, const NetObjTemporaryPtr<T>& p) override {
|
||||
if(data.empty())
|
||||
return std::numeric_limits<uint32_t>::max();
|
||||
auto it = idToDataMap.find(p.get_net_id());
|
||||
|
|
@ -148,37 +133,37 @@ namespace NetworkingObjects {
|
|||
uint32_t indexToErase = it->second->pos;
|
||||
data.erase(data.begin() + indexToErase);
|
||||
idToDataMap.erase(it);
|
||||
l.send_server_update_to_all_clients(RELIABLE_COMMAND_CHANNEL, [indexToErase](const NetObjPtr<NetObjOrderedList<T>>&, cereal::PortableBinaryOutputArchive& a) {
|
||||
l.send_server_update_to_all_clients(RELIABLE_COMMAND_CHANNEL, [indexToErase](const NetObjTemporaryPtr<NetObjOrderedList<T>>&, cereal::PortableBinaryOutputArchive& a) {
|
||||
a(ObjPtrOrderedListCommand_StoC::ERASE_SINGLE, indexToErase);
|
||||
});
|
||||
set_positions_for_object_info_vector<T>(data, indexToErase);
|
||||
return indexToErase;
|
||||
}
|
||||
virtual void write_constructor(const NetObjPtr<NetObjOrderedList<T>>& l, cereal::PortableBinaryOutputArchive& a) override {
|
||||
virtual void write_constructor(const NetObjTemporaryPtr<NetObjOrderedList<T>>& l, cereal::PortableBinaryOutputArchive& a) override {
|
||||
a(static_cast<uint32_t>(data.size()));
|
||||
for(size_t i = 0; i < data.size(); i++)
|
||||
data[i]->obj.write_create_message(a);
|
||||
}
|
||||
virtual void read_constructor(const NetObjPtr<NetObjOrderedList<T>>& l, cereal::PortableBinaryInputArchive& a, const std::shared_ptr<NetServer::ClientData>& c) override {
|
||||
virtual void read_constructor(NetObjManager* objMan, const std::shared_ptr<NetObjOrderedList<T>>& l, cereal::PortableBinaryInputArchive& a, const std::shared_ptr<NetServer::ClientData>& c) override {
|
||||
uint32_t constructedSize;
|
||||
a(constructedSize);
|
||||
data.clear();
|
||||
idToDataMap.clear();
|
||||
for(uint32_t i = 0; i < constructedSize; i++) {
|
||||
data.emplace_back(std::make_shared<NetObjOrderedListObjectInfo<T>>(l.get_obj_man()->template read_create_message<T>(a, c), static_cast<uint32_t>(data.size()), false));
|
||||
data.emplace_back(std::make_shared<NetObjOrderedListObjectInfo<T>>(objMan->template read_create_message<T>(a, c), static_cast<uint32_t>(data.size())));
|
||||
idToDataMap.emplace(data.back()->obj.get_net_id(), data.back());
|
||||
}
|
||||
// Dont send the object data to all clients in the constructor, as the function that called read_create_message is also the one that will decide where to send the data of the constructed object
|
||||
// Example: the INSERT_SINGLE command in read_update, if it was inserting another NetObjOrderedList, would first construct the list using read_create_message, then it will call insert() to send it to clients
|
||||
}
|
||||
virtual void read_update(const NetObjPtr<NetObjOrderedList<T>>& l, cereal::PortableBinaryInputArchive& a, const std::shared_ptr<NetServer::ClientData>& c) override {
|
||||
virtual void read_update(const NetObjTemporaryPtr<NetObjOrderedList<T>>& l, cereal::PortableBinaryInputArchive& a, const std::shared_ptr<NetServer::ClientData>& c) override {
|
||||
ObjPtrOrderedListCommand_CtoS command;
|
||||
a(command);
|
||||
switch(command) {
|
||||
case ObjPtrOrderedListCommand_CtoS::INSERT_SINGLE:
|
||||
uint32_t newPos;
|
||||
a(newPos);
|
||||
insert(l, newPos, l.get_obj_man()->template read_create_message<T>(a, c));
|
||||
insert(l, c, newPos, l.get_obj_man()->template read_create_message<T>(a, c));
|
||||
break;
|
||||
case ObjPtrOrderedListCommand_CtoS::ERASE_SINGLE:
|
||||
NetObjID idToErase;
|
||||
|
|
@ -197,75 +182,51 @@ namespace NetworkingObjects {
|
|||
template <typename T> class NetObjOrderedListClient : public NetObjOrderedList<T> {
|
||||
public:
|
||||
NetObjOrderedListClient() {}
|
||||
virtual bool contains(const NetObjPtr<T>& p) const override {
|
||||
virtual bool contains(const NetObjTemporaryPtr<T>& p) const override {
|
||||
return clientIdToDataMap.contains(p.get_net_id());
|
||||
}
|
||||
virtual uint32_t size() const override {
|
||||
return clientData.size();
|
||||
}
|
||||
virtual const NetObjPtr<T>& at(uint32_t index) const override {
|
||||
virtual const NetObjOwnerPtr<T>& at(uint32_t index) const override {
|
||||
return clientData[index]->obj;
|
||||
}
|
||||
virtual bool empty() const override {
|
||||
return clientData.empty();
|
||||
}
|
||||
protected:
|
||||
virtual void insert(const NetObjPtr<NetObjOrderedList<T>>& l, uint32_t posToInsertAt, const NetObjPtr<T>& newObj) {
|
||||
uint32_t actualPosToInsertAt = posToInsertAt = std::min<uint32_t>(posToInsertAt, clientData.size());
|
||||
|
||||
NetObjOrderedListObjectInfoPtr<T> newObjInfoPtr;
|
||||
auto itObjAlreadyInData = clientIdToDataMap.find(newObj.get_net_id());
|
||||
if(itObjAlreadyInData != clientIdToDataMap.end()) {
|
||||
uint32_t posToErase = itObjAlreadyInData->second->pos;
|
||||
newObjInfoPtr = clientData[posToErase];
|
||||
clientData.erase(clientData.begin() + posToErase);
|
||||
if(posToErase < actualPosToInsertAt) // Shift insert position if an element was erased before the insert position
|
||||
actualPosToInsertAt--;
|
||||
clientData.insert(clientData.begin() + actualPosToInsertAt, newObjInfoPtr);
|
||||
}
|
||||
else {
|
||||
auto serverIt = serverIdToDataMap.find(newObj.get_net_id()); // No duplicate in client data, but check if it's already in server data
|
||||
if(serverIt != serverIdToDataMap.end())
|
||||
newObjInfoPtr = serverIt->second;
|
||||
else
|
||||
newObjInfoPtr = std::make_shared<NetObjOrderedListObjectInfo<T>>(newObj, 0, true);
|
||||
clientData.insert(clientData.begin() + actualPosToInsertAt, newObjInfoPtr);
|
||||
clientIdToDataMap.emplace(newObjInfoPtr->obj.get_net_id(), newObjInfoPtr);
|
||||
}
|
||||
|
||||
newObjInfoPtr->syncIgnore = true;
|
||||
|
||||
l.send_client_update(RELIABLE_COMMAND_CHANNEL, [&newObjInfoPtr, posToInsertAt](const NetObjPtr<NetObjOrderedList<T>>&, cereal::PortableBinaryOutputArchive& a) {
|
||||
virtual void 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);
|
||||
clientIdToDataMap.emplace(newObjInfoPtr->obj.get_net_id(), newObjInfoPtr);
|
||||
clientJustInsertedSyncIgnore.emplace(newObjInfoPtr->obj.get_net_id(), newObjInfoPtr);
|
||||
l.send_client_update(RELIABLE_COMMAND_CHANNEL, [&newObjInfoPtr, posToInsertAt](const NetObjTemporaryPtr<NetObjOrderedList<T>>&, cereal::PortableBinaryOutputArchive& a) {
|
||||
a(ObjPtrOrderedListCommand_CtoS::INSERT_SINGLE, posToInsertAt); // Don't put actual pos to insert at, since the server will check for duplicates and might shift the index on its own
|
||||
newObjInfoPtr->obj.write_create_message(a);
|
||||
});
|
||||
set_positions_for_object_info_vector<T>(clientData, actualPosToInsertAt);
|
||||
set_positions_for_object_info_vector<T>(clientData, posToInsertAt);
|
||||
}
|
||||
virtual NetObjPtr<T> erase_by_index(const NetObjPtr<NetObjOrderedList<T>>& l, uint32_t indexToErase) override {
|
||||
virtual void erase_by_index(const NetObjTemporaryPtr<NetObjOrderedList<T>>& l, uint32_t indexToErase) override {
|
||||
if(clientData.empty())
|
||||
return {};
|
||||
return;
|
||||
indexToErase = std::min<uint32_t>(indexToErase, clientData.size() - 1);
|
||||
auto p = clientData[indexToErase];
|
||||
l.send_client_update(RELIABLE_COMMAND_CHANNEL, [&p](const NetObjPtr<NetObjOrderedList<T>>&, cereal::PortableBinaryOutputArchive& a) {
|
||||
l.send_client_update(RELIABLE_COMMAND_CHANNEL, [&p](const NetObjTemporaryPtr<NetObjOrderedList<T>>&, cereal::PortableBinaryOutputArchive& a) {
|
||||
a(ObjPtrOrderedListCommand_CtoS::ERASE_SINGLE, p->obj.get_net_id());
|
||||
});
|
||||
p->syncIgnore = true;
|
||||
uint32_t iToErase = p->pos;
|
||||
clientIdToDataMap.erase(p->obj.get_net_id());
|
||||
clientData.erase(clientData.begin() + iToErase);
|
||||
set_positions_for_object_info_vector<T>(clientData, iToErase);
|
||||
return p->obj;
|
||||
}
|
||||
virtual uint32_t erase_by_ptr(const NetObjPtr<NetObjOrderedList<T>>& l, const NetObjPtr<T>& p) override {
|
||||
virtual uint32_t erase_by_ptr(const NetObjTemporaryPtr<NetObjOrderedList<T>>& l, const NetObjTemporaryPtr<T>& p) override {
|
||||
if(clientData.empty())
|
||||
return std::numeric_limits<uint32_t>::max();
|
||||
auto it = clientIdToDataMap.find(p.get_net_id());
|
||||
if(it == clientIdToDataMap.end())
|
||||
return std::numeric_limits<uint32_t>::max();
|
||||
l.send_client_update(RELIABLE_COMMAND_CHANNEL, [&p](const NetObjPtr<NetObjOrderedList<T>>&, cereal::PortableBinaryOutputArchive& a) {
|
||||
l.send_client_update(RELIABLE_COMMAND_CHANNEL, [&p](const NetObjTemporaryPtr<NetObjOrderedList<T>>&, cereal::PortableBinaryOutputArchive& a) {
|
||||
a(ObjPtrOrderedListCommand_CtoS::ERASE_SINGLE, p.get_net_id());
|
||||
});
|
||||
it->second->syncIgnore = true;
|
||||
auto it = clientIdToDataMap.find(p.get_net_id());
|
||||
uint32_t iToErase = it->second->pos;
|
||||
auto toRet = clientData[iToErase];
|
||||
clientIdToDataMap.erase(it);
|
||||
|
|
@ -273,104 +234,96 @@ namespace NetworkingObjects {
|
|||
set_positions_for_object_info_vector<T>(clientData, iToErase);
|
||||
return iToErase;
|
||||
}
|
||||
virtual void write_constructor(const NetObjPtr<NetObjOrderedList<T>>& l, cereal::PortableBinaryOutputArchive& a) override {
|
||||
virtual void write_constructor(const NetObjTemporaryPtr<NetObjOrderedList<T>>& l, cereal::PortableBinaryOutputArchive& a) override {
|
||||
a(static_cast<uint32_t>(clientData.size()));
|
||||
for(size_t i = 0; i < clientData.size(); i++)
|
||||
clientData[i]->obj.write_create_message(a);
|
||||
}
|
||||
virtual void read_constructor(const NetObjPtr<NetObjOrderedList<T>>& l, cereal::PortableBinaryInputArchive& a, const std::shared_ptr<NetServer::ClientData>&) override {
|
||||
virtual void read_constructor(NetObjManager* objMan, const std::shared_ptr<NetObjOrderedList<T>>& l, cereal::PortableBinaryInputArchive& a, const std::shared_ptr<NetServer::ClientData>&) override {
|
||||
uint32_t constructedSize;
|
||||
a(constructedSize);
|
||||
clientData.clear();
|
||||
serverData.clear();
|
||||
serverIdToDataMap.clear();
|
||||
clientIdToDataMap.clear();
|
||||
for(uint32_t i = 0; i < constructedSize; i++) {
|
||||
serverData.emplace_back(std::make_shared<NetObjOrderedListObjectInfo<T>>(l.get_obj_man()->template read_create_message<T>(a, nullptr), static_cast<uint32_t>(serverData.size()), false));
|
||||
serverIdToDataMap.emplace(serverData.back()->obj.get_net_id(), serverData.back());
|
||||
clientData.emplace_back(std::make_shared<NetObjOrderedListObjectInfo<T>>(objMan->template read_create_message<T>(a, nullptr), static_cast<uint32_t>(serverData.size())));
|
||||
clientIdToDataMap.emplace_back(clientData.back()->obj.get_net_id(), serverData.back());
|
||||
serverData.emplace_back(clientData.back()->obj.get_net_id());
|
||||
}
|
||||
clientData = serverData;
|
||||
clientIdToDataMap = serverIdToDataMap;
|
||||
}
|
||||
virtual void read_update(const NetObjPtr<NetObjOrderedList<T>>& l, cereal::PortableBinaryInputArchive& a, const std::shared_ptr<NetServer::ClientData>&) override {
|
||||
virtual void read_update(const NetObjTemporaryPtr<NetObjOrderedList<T>>& l, cereal::PortableBinaryInputArchive& a, const std::shared_ptr<NetServer::ClientData>&) override {
|
||||
ObjPtrOrderedListCommand_StoC c;
|
||||
a(c);
|
||||
switch(c) {
|
||||
case ObjPtrOrderedListCommand_StoC::INSERT_SINGLE: {
|
||||
case ObjPtrOrderedListCommand_StoC::INSERT_SINGLE_REFERENCE: {
|
||||
NetObjID newObjID;
|
||||
uint32_t newServerPos;
|
||||
a(newServerPos, newObjID);
|
||||
serverData.insert(serverData.begin() + newServerPos, newObjID);
|
||||
clientJustInsertedSyncIgnore.erase(newObjID);
|
||||
sync();
|
||||
break;
|
||||
}
|
||||
case ObjPtrOrderedListCommand_StoC::INSERT_SINGLE_CONSTRUCT: {
|
||||
uint32_t newServerPos;
|
||||
a(newServerPos);
|
||||
auto objToInsert = l.get_obj_man()->template read_create_message<T>(a, nullptr);
|
||||
auto it = serverIdToDataMap.find(objToInsert.get_net_id());
|
||||
if(it != serverIdToDataMap.end()) {
|
||||
uint32_t serverPosErased = std::numeric_limits<uint32_t>::max();
|
||||
std::erase_if(serverData, [&](auto& objInfo) {
|
||||
if(objToInsert.get_net_id() == objInfo->obj.get_net_id()) {
|
||||
serverPosErased = &objInfo - &serverData[0];
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
assert(serverPosErased != std::numeric_limits<uint32_t>::max());
|
||||
if(serverPosErased < newServerPos)
|
||||
newServerPos--; // Shift if there was a duplicate before this
|
||||
//it->second->pos = newServerPos; // NOTE: DO NOT set the pos variable here, as pos is reserved for the position in the client vector
|
||||
serverData.insert(serverData.begin() + newServerPos, it->second);
|
||||
}
|
||||
else {
|
||||
NetObjOrderedListObjectInfoPtr<T> objInfoToInsert;
|
||||
auto clientIt = clientIdToDataMap.find(objToInsert.get_net_id());
|
||||
if(clientIt != clientIdToDataMap.end())
|
||||
objInfoToInsert = clientIt->second;
|
||||
else
|
||||
objInfoToInsert = std::make_shared<NetObjOrderedListObjectInfo<T>>(objToInsert, 0, false);
|
||||
objInfoToInsert->syncIgnore = false;
|
||||
serverData.insert(serverData.begin() + newServerPos, objInfoToInsert);
|
||||
serverIdToDataMap.emplace(objInfoToInsert->obj.get_net_id(), objInfoToInsert);
|
||||
}
|
||||
auto objInfoToInsert = std::make_shared<NetObjOrderedListObjectInfo<T>>(l.get_obj_man()->template read_create_message<T>(a, nullptr), 0);
|
||||
serverData.insert(serverData.begin() + newServerPos, objInfoToInsert->obj.get_net_id());
|
||||
clientJustInsertedSyncIgnore.erase(objInfoToInsert->obj.get_net_id());
|
||||
sync();
|
||||
break;
|
||||
}
|
||||
case ObjPtrOrderedListCommand_StoC::ERASE_SINGLE: {
|
||||
uint32_t serverPosToErase;
|
||||
a(serverPosToErase);
|
||||
NetObjID objID = serverData[serverPosToErase]->obj.get_net_id();
|
||||
NetObjID objID = serverData[serverPosToErase];
|
||||
serverData.erase(serverData.begin() + serverPosToErase);
|
||||
serverIdToDataMap.erase(objID);
|
||||
auto it = clientIdToDataMap.find(objID);
|
||||
if(it != clientIdToDataMap.end()) {
|
||||
uint32_t clientPosToErase = it->second->pos;
|
||||
clientIdToDataMap.erase(it);
|
||||
clientJustInsertedSyncIgnore.erase(objID);
|
||||
clientData.erase(clientData.begin() + clientPosToErase);
|
||||
set_positions_for_object_info_vector<T>(clientData, clientPosToErase);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
sync();
|
||||
}
|
||||
private:
|
||||
void sync(const std::unordered_map<NetObjID, NetObjOrderedListObjectInfoPtr<T>>& newServerObjects) {
|
||||
std::map<uint32_t, NetObjOrderedListObjectInfoPtr<T>> ignoredToReinsert;
|
||||
for(auto& [netID, objInfoPtr] : clientJustInsertedSyncIgnore)
|
||||
ignoredToReinsert.emplace(objInfoPtr->pos, objInfoPtr);
|
||||
|
||||
void sync() {
|
||||
std::vector<std::pair<uint32_t, NetObjOrderedListObjectInfoPtr<T>>> ignoredToReinsert;
|
||||
for(uint32_t i = 0; i < static_cast<uint32_t>(clientData.size()); i++)
|
||||
if(clientData[i]->syncIgnore)
|
||||
ignoredToReinsert.emplace_back(std::pair<uint32_t, NetObjOrderedListObjectInfoPtr<T>>{i, clientData[i]});
|
||||
clientData = serverData;
|
||||
clientIdToDataMap = serverIdToDataMap;
|
||||
std::erase_if(clientData, [&](const auto& obj) {
|
||||
if(obj->syncIgnore) {
|
||||
clientIdToDataMap.erase(obj->obj.get_net_id());
|
||||
return true;
|
||||
clientData.clear();
|
||||
for(const NetObjID& id : serverData) {
|
||||
auto itFoundInClient = clientIdToDataMap.find(id);
|
||||
if(itFoundInClient != clientIdToDataMap.end())
|
||||
clientData.emplace_back(itFoundInClient->second);
|
||||
else {
|
||||
auto itFoundInServer = newServerObjects.find(id);
|
||||
if(itFoundInServer != newServerObjects.end()) {
|
||||
clientData.emplace_back(itFoundInServer->second);
|
||||
clientIdToDataMap.emplace(itFoundInServer->first, itFoundInServer->second);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
});
|
||||
for(auto& p : ignoredToReinsert) {
|
||||
if(p.first > clientData.size())
|
||||
clientData.emplace_back(p.second);
|
||||
else
|
||||
clientData.insert(clientData.begin() + p.first, p.second);
|
||||
clientIdToDataMap.emplace(p.second->obj.get_net_id(), p.second);
|
||||
}
|
||||
|
||||
for(auto& [pos, objInfoPtr] : ignoredToReinsert) {
|
||||
if(pos > clientData.size())
|
||||
clientData.emplace_back(objInfoPtr);
|
||||
else
|
||||
clientData.insert(clientData.begin() + pos, objInfoPtr);
|
||||
}
|
||||
|
||||
set_positions_for_object_info_vector<T>(clientData);
|
||||
}
|
||||
|
||||
std::vector<NetObjOrderedListObjectInfoPtr<T>> serverData;
|
||||
std::unordered_map<NetObjID, NetObjOrderedListObjectInfoPtr<T>> serverIdToDataMap;
|
||||
|
||||
std::vector<NetObjID> serverData;
|
||||
std::vector<NetObjOrderedListObjectInfoPtr<T>> clientData;
|
||||
std::unordered_map<NetObjID, NetObjOrderedListObjectInfoPtr<T>> clientIdToDataMap;
|
||||
std::unordered_map<NetObjID, NetObjOrderedListObjectInfoPtr<T>> clientJustInsertedSyncIgnore;
|
||||
};
|
||||
|
||||
template <typename S> void register_ordered_list_class(NetObjManagerTypeList& t) {
|
||||
|
|
|
|||
40
include/Helpers/NetworkingObjects/NetObjOwnerPtr.decl.hpp
Normal file
40
include/Helpers/NetworkingObjects/NetObjOwnerPtr.decl.hpp
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
#pragma once
|
||||
#include "NetObjID.hpp"
|
||||
#include <type_traits>
|
||||
#include <cereal/archives/portable_binary.hpp>
|
||||
#include "../Networking/NetServer.hpp"
|
||||
|
||||
namespace NetworkingObjects {
|
||||
class NetObjManager;
|
||||
template <typename T> class NetObjTemporaryPtr;
|
||||
template <typename T> class NetObjOwnerPtr {
|
||||
public:
|
||||
NetObjOwnerPtr();
|
||||
NetObjOwnerPtr(const NetObjOwnerPtr& other) = delete;
|
||||
NetObjOwnerPtr(NetObjOwnerPtr&& other);
|
||||
NetObjOwnerPtr& operator=(const NetObjOwnerPtr& other) = delete;
|
||||
NetObjOwnerPtr& operator=(NetObjOwnerPtr&& other);
|
||||
~NetObjOwnerPtr();
|
||||
NetObjManager* get_obj_man() const;
|
||||
NetObjID get_net_id() const;
|
||||
T* get() const;
|
||||
std::add_lvalue_reference_t<T> operator*() const requires(!std::is_void_v<T>);
|
||||
T* operator->() const;
|
||||
operator bool() const;
|
||||
std::strong_ordering operator<=>(const NetObjOwnerPtr<T>& rhs) const;
|
||||
void send_client_update(const std::string& channel, std::function<void(const NetObjTemporaryPtr<T>&, cereal::PortableBinaryOutputArchive&)> sendUpdateFunc) const;
|
||||
void send_server_update_to_client(const std::shared_ptr<NetServer::ClientData>& clientToSendTo, const std::string& channel, std::function<void(const NetObjTemporaryPtr<T>&, cereal::PortableBinaryOutputArchive&)> sendUpdateFunc) const;
|
||||
void send_server_update_to_all_clients_except(const std::shared_ptr<NetServer::ClientData>& clientToNotSendTo, const std::string& channel, std::function<void(const NetObjTemporaryPtr<T>&, cereal::PortableBinaryOutputArchive&)> sendUpdateFunc) const;
|
||||
void send_server_update_to_all_clients(const std::string& channel, std::function<void(const NetObjTemporaryPtr<T>&, cereal::PortableBinaryOutputArchive&)> sendUpdateFunc) const;
|
||||
void send_update_to_all(const std::string& channel, std::function<void(const NetObjTemporaryPtr<T>&, cereal::PortableBinaryOutputArchive&)> sendUpdateFunc) const;
|
||||
void write_create_message(cereal::PortableBinaryOutputArchive& a) const;
|
||||
private:
|
||||
friend class NetObjManager;
|
||||
template <typename S> friend class NetObjTemporaryPtr;
|
||||
|
||||
NetObjOwnerPtr(NetObjManager* initObjMan, NetObjID initID, T* initRawPtr);
|
||||
NetObjManager* objMan;
|
||||
NetObjID id;
|
||||
T* rawPtr;
|
||||
};
|
||||
}
|
||||
3
include/Helpers/NetworkingObjects/NetObjOwnerPtr.hpp
Normal file
3
include/Helpers/NetworkingObjects/NetObjOwnerPtr.hpp
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
#pragma once
|
||||
#include "NetObjOwnerPtr.decl.hpp"
|
||||
#include "NetObjOwnerPtr.impl.hpp"
|
||||
99
include/Helpers/NetworkingObjects/NetObjOwnerPtr.impl.hpp
Normal file
99
include/Helpers/NetworkingObjects/NetObjOwnerPtr.impl.hpp
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
#pragma once
|
||||
#include <compare>
|
||||
#include <string>
|
||||
#include <functional>
|
||||
#include <cereal/archives/portable_binary.hpp>
|
||||
#include <type_traits>
|
||||
#include "NetObjOwnerPtr.decl.hpp"
|
||||
#include "NetObjTemporaryPtr.hpp"
|
||||
#include "NetObjManager.hpp"
|
||||
#include "NetObjManagerTypeList.hpp"
|
||||
|
||||
namespace NetworkingObjects {
|
||||
template <typename T> NetObjOwnerPtr<T>::NetObjOwnerPtr():
|
||||
objMan(nullptr),
|
||||
rawPtr(nullptr)
|
||||
{}
|
||||
|
||||
template <typename T> NetObjOwnerPtr<T>::NetObjOwnerPtr(NetObjOwnerPtr&& other):
|
||||
objMan(other.objMan),
|
||||
id(other.id),
|
||||
rawPtr(other.rawPtr)
|
||||
{
|
||||
other.objMan = nullptr;
|
||||
other.rawPtr = nullptr;
|
||||
}
|
||||
|
||||
template <typename T> NetObjOwnerPtr<T>& NetObjOwnerPtr<T>::operator=(NetObjOwnerPtr&& other) {
|
||||
objMan = other.objMan;
|
||||
id = other.id;
|
||||
rawPtr = other.rawPtr;
|
||||
other.objMan = nullptr;
|
||||
other.rawPtr = nullptr;
|
||||
}
|
||||
|
||||
template <typename T> NetObjOwnerPtr<T>::~NetObjOwnerPtr() {
|
||||
if(objMan && rawPtr) {
|
||||
auto it = objMan->objectData.find(id);
|
||||
delete static_cast<T*>(it->second.p);
|
||||
objMan->objectData.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T> NetObjManager* NetObjOwnerPtr<T>::get_obj_man() const {
|
||||
return objMan;
|
||||
}
|
||||
|
||||
template <typename T> NetObjID NetObjOwnerPtr<T>::get_net_id() const {
|
||||
return id;
|
||||
}
|
||||
|
||||
template <typename T> T* NetObjOwnerPtr<T>::get() const {
|
||||
return rawPtr;
|
||||
}
|
||||
|
||||
template <typename T> std::add_lvalue_reference_t<T> NetObjOwnerPtr<T>::operator*() const requires(!std::is_void_v<T>) {
|
||||
return *rawPtr;
|
||||
}
|
||||
|
||||
template <typename T> T* NetObjOwnerPtr<T>::operator->() const {
|
||||
return rawPtr;
|
||||
}
|
||||
|
||||
template <typename T> NetObjOwnerPtr<T>::operator bool() const {
|
||||
return rawPtr;
|
||||
}
|
||||
|
||||
template <typename T> std::strong_ordering NetObjOwnerPtr<T>::operator<=>(const NetObjOwnerPtr<T>& rhs) const {
|
||||
return rawPtr <=> rhs.rawPtr;
|
||||
}
|
||||
|
||||
template <typename T> void NetObjOwnerPtr<T>::send_client_update(const std::string& channel, std::function<void(const NetObjTemporaryPtr<T>&, cereal::PortableBinaryOutputArchive&)> sendUpdateFunc) const {
|
||||
NetObjManager::send_client_update(*this, channel, sendUpdateFunc);
|
||||
}
|
||||
|
||||
template <typename T> void NetObjOwnerPtr<T>::send_server_update_to_all_clients(const std::string& channel, std::function<void(const NetObjTemporaryPtr<T>&, cereal::PortableBinaryOutputArchive&)> sendUpdateFunc) const {
|
||||
NetObjManager::send_server_update_to_all_clients(*this, channel, sendUpdateFunc);
|
||||
}
|
||||
|
||||
template <typename T> void NetObjOwnerPtr<T>::send_server_update_to_client(const std::shared_ptr<NetServer::ClientData>& clientToSendTo, const std::string& channel, std::function<void(const NetObjTemporaryPtr<T>&, cereal::PortableBinaryOutputArchive&)> sendUpdateFunc) const {
|
||||
NetObjManager::send_server_update_to_client(*this, clientToSendTo, channel, sendUpdateFunc);
|
||||
}
|
||||
template <typename T> void NetObjOwnerPtr<T>::send_server_update_to_all_clients_except(const std::shared_ptr<NetServer::ClientData>& clientToNotSendTo, const std::string& channel, std::function<void(const NetObjTemporaryPtr<T>&, cereal::PortableBinaryOutputArchive&)> sendUpdateFunc) const {
|
||||
NetObjManager::send_server_update_to_all_clients_except(*this, clientToNotSendTo, channel, sendUpdateFunc);
|
||||
}
|
||||
|
||||
template <typename T> void NetObjOwnerPtr<T>::send_update_to_all(const std::string& channel, std::function<void(const NetObjTemporaryPtr<T>&, cereal::PortableBinaryOutputArchive&)> sendUpdateFunc) const {
|
||||
NetObjManager::send_update_to_all(*this, channel, sendUpdateFunc);
|
||||
}
|
||||
|
||||
template <typename T> void NetObjOwnerPtr<T>::write_create_message(cereal::PortableBinaryOutputArchive& a) const {
|
||||
NetObjManager::write_create_message(*this, a);
|
||||
}
|
||||
|
||||
template <typename T> NetObjOwnerPtr<T>::NetObjOwnerPtr(NetObjManager* initObjMan, NetObjID initID, T* initRawPtr):
|
||||
objMan(initObjMan),
|
||||
id(initID),
|
||||
rawPtr(initRawPtr)
|
||||
{}
|
||||
}
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
#pragma once
|
||||
#include "NetObjID.hpp"
|
||||
#include <type_traits>
|
||||
#include <cereal/archives/portable_binary.hpp>
|
||||
|
||||
namespace NetworkingObjects {
|
||||
class NetObjManager;
|
||||
template <typename T> class NetObjPtr {
|
||||
public:
|
||||
NetObjPtr();
|
||||
NetObjPtr(const NetObjPtr& other);
|
||||
NetObjPtr& operator=(const NetObjPtr& other);
|
||||
~NetObjPtr();
|
||||
template <typename S> NetObjPtr<S> cast() const;
|
||||
NetObjManager* get_obj_man() const;
|
||||
NetObjID get_net_id() const;
|
||||
T* get() const;
|
||||
std::add_lvalue_reference_t<T> operator*() const requires(!std::is_void_v<T>);
|
||||
T* operator->() const;
|
||||
operator bool() const;
|
||||
std::strong_ordering operator<=>(const NetObjPtr<T>& rhs) const;
|
||||
void send_client_update(const std::string& channel, std::function<void(const NetObjPtr<T>&, cereal::PortableBinaryOutputArchive&)> sendUpdateFunc) const;
|
||||
void send_server_update_to_all_clients(const std::string& channel, std::function<void(const NetObjPtr<T>&, cereal::PortableBinaryOutputArchive&)> sendUpdateFunc) const;
|
||||
void send_update_to_all(const std::string& channel, std::function<void(const NetObjPtr<T>&, cereal::PortableBinaryOutputArchive&)> sendUpdateFunc) const;
|
||||
void write_create_message(cereal::PortableBinaryOutputArchive& a) const;
|
||||
private:
|
||||
friend class NetObjManager;
|
||||
template <typename S> friend class NetObjPtr;
|
||||
template <typename S> friend class NetObjWeakPtr;
|
||||
|
||||
NetObjPtr(NetObjManager* initObjMan, NetObjID initID, const std::shared_ptr<T>& initPtr);
|
||||
NetObjManager* objMan;
|
||||
NetObjID id;
|
||||
std::shared_ptr<T> sharedPtr;
|
||||
};
|
||||
}
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
#pragma once
|
||||
#include "NetObjPtr.decl.hpp"
|
||||
#include "NetObjPtr.impl.hpp"
|
||||
|
|
@ -1,109 +0,0 @@
|
|||
#pragma once
|
||||
#include <compare>
|
||||
#include <string>
|
||||
#include <functional>
|
||||
#include <cereal/archives/portable_binary.hpp>
|
||||
#include <type_traits>
|
||||
#include "NetObjPtr.decl.hpp"
|
||||
#include "NetObjManager.hpp"
|
||||
#include "NetObjManagerTypeList.hpp"
|
||||
|
||||
namespace NetworkingObjects {
|
||||
template <typename T> NetObjPtr<T>::NetObjPtr():
|
||||
objMan(nullptr),
|
||||
sharedPtr(nullptr)
|
||||
{}
|
||||
template <typename T> NetObjPtr<T>::NetObjPtr(const NetObjPtr<T>& other):
|
||||
objMan(other.objMan),
|
||||
id(other.id),
|
||||
sharedPtr(other.sharedPtr)
|
||||
{}
|
||||
template <typename T> NetObjPtr<T>& NetObjPtr<T>::operator=(const NetObjPtr<T>& other) {
|
||||
if(this != &other) {
|
||||
if(sharedPtr && sharedPtr.use_count() == 2)
|
||||
objMan->objectData.erase(id);
|
||||
objMan = other.objMan;
|
||||
id = other.id;
|
||||
sharedPtr = other.sharedPtr;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
template <typename T> NetObjPtr<T>::~NetObjPtr() {
|
||||
if(sharedPtr && sharedPtr.use_count() == 2)
|
||||
objMan->objectData.erase(id);
|
||||
}
|
||||
|
||||
template <typename T> template <typename S> NetObjPtr<S> NetObjPtr<T>::cast() const {
|
||||
return NetObjPtr<S>(objMan, id, std::static_pointer_cast<S>(sharedPtr));
|
||||
}
|
||||
|
||||
template <typename T> NetObjManager* NetObjPtr<T>::get_obj_man() const {
|
||||
return objMan;
|
||||
}
|
||||
|
||||
template <typename T> NetObjID NetObjPtr<T>::get_net_id() const {
|
||||
return id;
|
||||
}
|
||||
|
||||
template <typename T> T* NetObjPtr<T>::get() const {
|
||||
return sharedPtr.get();
|
||||
}
|
||||
|
||||
template <typename T> std::add_lvalue_reference_t<T> NetObjPtr<T>::operator*() const requires(!std::is_void_v<T>) {
|
||||
return *sharedPtr;
|
||||
}
|
||||
|
||||
template <typename T> T* NetObjPtr<T>::operator->() const {
|
||||
return sharedPtr.get();
|
||||
}
|
||||
|
||||
template <typename T> NetObjPtr<T>::operator bool() const {
|
||||
return sharedPtr != nullptr;
|
||||
}
|
||||
|
||||
template <typename T> std::strong_ordering NetObjPtr<T>::operator<=>(const NetObjPtr<T>& rhs) const {
|
||||
return sharedPtr <=> rhs.sharedPtr;
|
||||
}
|
||||
|
||||
template <typename T> void NetObjPtr<T>::send_client_update(const std::string& channel, std::function<void(const NetObjPtr<T>&, cereal::PortableBinaryOutputArchive&)> sendUpdateFunc) const {
|
||||
if(objMan->client && !objMan->client->is_disconnected()) {
|
||||
auto ss(std::make_shared<std::stringstream>());
|
||||
{
|
||||
cereal::PortableBinaryOutputArchive m(*ss);
|
||||
m(objMan->updateCommandID, id);
|
||||
sendUpdateFunc(*this, m);
|
||||
}
|
||||
objMan->client->send_string_stream_to_server(channel, ss);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T> void NetObjPtr<T>::send_server_update_to_all_clients(const std::string& channel, std::function<void(const NetObjPtr<T>&, cereal::PortableBinaryOutputArchive&)> sendUpdateFunc) const {
|
||||
if(objMan->server && !objMan->server->is_disconnected()) {
|
||||
auto ss(std::make_shared<std::stringstream>());
|
||||
{
|
||||
cereal::PortableBinaryOutputArchive m(*ss);
|
||||
m(objMan->updateCommandID, id);
|
||||
sendUpdateFunc(*this, m);
|
||||
}
|
||||
objMan->server->send_string_stream_to_all_clients(channel, ss);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T> void NetObjPtr<T>::send_update_to_all(const std::string& channel, std::function<void(const NetObjPtr<T>&, cereal::PortableBinaryOutputArchive&)> sendUpdateFunc) const {
|
||||
if(objMan->is_server())
|
||||
send_server_update_to_all_clients(channel, sendUpdateFunc);
|
||||
else
|
||||
send_client_update(channel, sendUpdateFunc);
|
||||
}
|
||||
|
||||
template <typename T> void NetObjPtr<T>::write_create_message(cereal::PortableBinaryOutputArchive& a) const {
|
||||
a(id);
|
||||
objMan->typeList->get_type_index_data<T>(objMan->isServer).writeConstructorFunc(this->cast<void>(), a);
|
||||
}
|
||||
|
||||
template <typename T> NetObjPtr<T>::NetObjPtr(NetObjManager* initObjMan, NetObjID initID, const std::shared_ptr<T>& initPtr):
|
||||
objMan(initObjMan),
|
||||
id(initID),
|
||||
sharedPtr(initPtr)
|
||||
{}
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
#pragma once
|
||||
#include "NetObjID.hpp"
|
||||
#include <type_traits>
|
||||
#include <cereal/archives/portable_binary.hpp>
|
||||
#include "NetObjOwnerPtr.decl.hpp"
|
||||
#include "../Networking/NetServer.hpp"
|
||||
|
||||
namespace NetworkingObjects {
|
||||
class NetObjManager;
|
||||
template <typename T> class NetObjTemporaryPtr {
|
||||
public:
|
||||
NetObjTemporaryPtr();
|
||||
NetObjTemporaryPtr(const NetObjTemporaryPtr& other);
|
||||
NetObjTemporaryPtr(const NetObjOwnerPtr<T>& owner);
|
||||
NetObjTemporaryPtr& operator=(const NetObjTemporaryPtr& other);
|
||||
template <typename S> NetObjTemporaryPtr<S> cast() const;
|
||||
NetObjManager* get_obj_man() const;
|
||||
NetObjID get_net_id() const;
|
||||
T* get() const;
|
||||
std::add_lvalue_reference_t<T> operator*() const requires(!std::is_void_v<T>);
|
||||
T* operator->() const;
|
||||
operator bool() const;
|
||||
std::strong_ordering operator<=>(const NetObjTemporaryPtr<T>& rhs) const;
|
||||
void send_client_update(const std::string& channel, std::function<void(const NetObjTemporaryPtr<T>&, cereal::PortableBinaryOutputArchive&)> sendUpdateFunc) const;
|
||||
void send_server_update_to_client(const std::shared_ptr<NetServer::ClientData>& clientToSendTo, const std::string& channel, std::function<void(const NetObjTemporaryPtr<T>&, cereal::PortableBinaryOutputArchive&)> sendUpdateFunc) const;
|
||||
void send_server_update_to_all_clients_except(const std::shared_ptr<NetServer::ClientData>& clientToNotSendTo, const std::string& channel, std::function<void(const NetObjTemporaryPtr<T>&, cereal::PortableBinaryOutputArchive&)> sendUpdateFunc) const;
|
||||
void send_server_update_to_all_clients(const std::string& channel, std::function<void(const NetObjTemporaryPtr<T>&, cereal::PortableBinaryOutputArchive&)> sendUpdateFunc) const;
|
||||
void send_update_to_all(const std::string& channel, std::function<void(const NetObjTemporaryPtr<T>&, cereal::PortableBinaryOutputArchive&)> sendUpdateFunc) const;
|
||||
void write_create_message(cereal::PortableBinaryOutputArchive& a) const;
|
||||
private:
|
||||
friend class NetObjManager;
|
||||
template <typename S> friend class NetObjWeakPtr;
|
||||
NetObjTemporaryPtr(NetObjManager* initObjMan, NetObjID initID, T* initRawPtr);
|
||||
|
||||
NetObjManager* objMan;
|
||||
NetObjID id;
|
||||
T* rawPtr;
|
||||
};
|
||||
}
|
||||
3
include/Helpers/NetworkingObjects/NetObjTemporaryPtr.hpp
Normal file
3
include/Helpers/NetworkingObjects/NetObjTemporaryPtr.hpp
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
#pragma once
|
||||
#include "NetObjTemporaryPtr.decl.hpp"
|
||||
#include "NetObjTemporaryPtr.impl.hpp"
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
#pragma once
|
||||
#include <compare>
|
||||
#include <string>
|
||||
#include <functional>
|
||||
#include <cereal/archives/portable_binary.hpp>
|
||||
#include <type_traits>
|
||||
#include "NetObjTemporaryPtr.decl.hpp"
|
||||
#include "NetObjManager.hpp"
|
||||
#include "NetObjManagerTypeList.hpp"
|
||||
|
||||
namespace NetworkingObjects {
|
||||
template <typename T> NetObjTemporaryPtr<T>::NetObjTemporaryPtr():
|
||||
objMan(nullptr),
|
||||
rawPtr(nullptr)
|
||||
{}
|
||||
template <typename T> NetObjTemporaryPtr<T>::NetObjTemporaryPtr(const NetObjTemporaryPtr<T>& other):
|
||||
objMan(other.objMan),
|
||||
id(other.id),
|
||||
rawPtr(other.rawPtr)
|
||||
{}
|
||||
template <typename T> NetObjTemporaryPtr<T>::NetObjTemporaryPtr(const NetObjOwnerPtr<T>& owner):
|
||||
objMan(owner.objMan),
|
||||
id(owner.id),
|
||||
rawPtr(owner.rawPtr)
|
||||
{}
|
||||
|
||||
template <typename T> NetObjTemporaryPtr<T>& NetObjTemporaryPtr<T>::operator=(const NetObjTemporaryPtr<T>& other) {
|
||||
objMan = other.objMan;
|
||||
id = other.id;
|
||||
rawPtr = other.rawPtr;
|
||||
return *this;
|
||||
}
|
||||
template <typename T> template <typename S> NetObjTemporaryPtr<S> NetObjTemporaryPtr<T>::cast() const {
|
||||
return NetObjPtr<S>(objMan, id, static_cast<S>(rawPtr));
|
||||
}
|
||||
|
||||
template <typename T> NetObjManager* NetObjTemporaryPtr<T>::get_obj_man() const {
|
||||
return objMan;
|
||||
}
|
||||
|
||||
template <typename T> NetObjID NetObjTemporaryPtr<T>::get_net_id() const {
|
||||
return id;
|
||||
}
|
||||
|
||||
template <typename T> T* NetObjTemporaryPtr<T>::get() const {
|
||||
return rawPtr;
|
||||
}
|
||||
|
||||
template <typename T> std::add_lvalue_reference_t<T> NetObjTemporaryPtr<T>::operator*() const requires(!std::is_void_v<T>) {
|
||||
return *rawPtr;
|
||||
}
|
||||
|
||||
template <typename T> T* NetObjTemporaryPtr<T>::operator->() const {
|
||||
return rawPtr;
|
||||
}
|
||||
|
||||
template <typename T> NetObjTemporaryPtr<T>::operator bool() const {
|
||||
return rawPtr;
|
||||
}
|
||||
|
||||
template <typename T> std::strong_ordering NetObjTemporaryPtr<T>::operator<=>(const NetObjTemporaryPtr<T>& rhs) const {
|
||||
return rawPtr <=> rhs.rawPtr;
|
||||
}
|
||||
|
||||
template <typename T> void NetObjTemporaryPtr<T>::send_client_update(const std::string& channel, std::function<void(const NetObjTemporaryPtr<T>&, cereal::PortableBinaryOutputArchive&)> sendUpdateFunc) const {
|
||||
NetObjManager::send_client_update(*this, channel, sendUpdateFunc);
|
||||
}
|
||||
|
||||
template <typename T> void NetObjTemporaryPtr<T>::send_server_update_to_all_clients(const std::string& channel, std::function<void(const NetObjTemporaryPtr<T>&, cereal::PortableBinaryOutputArchive&)> sendUpdateFunc) const {
|
||||
NetObjManager::send_server_update_to_all_clients(*this, channel, sendUpdateFunc);
|
||||
}
|
||||
|
||||
|
||||
template <typename T> void NetObjTemporaryPtr<T>::send_server_update_to_client(const std::shared_ptr<NetServer::ClientData>& clientToSendTo, const std::string& channel, std::function<void(const NetObjTemporaryPtr<T>&, cereal::PortableBinaryOutputArchive&)> sendUpdateFunc) const {
|
||||
NetObjManager::send_server_update_to_client(*this, clientToSendTo, channel, sendUpdateFunc);
|
||||
}
|
||||
template <typename T> void NetObjTemporaryPtr<T>::send_server_update_to_all_clients_except(const std::shared_ptr<NetServer::ClientData>& clientToNotSendTo, const std::string& channel, std::function<void(const NetObjTemporaryPtr<T>&, cereal::PortableBinaryOutputArchive&)> sendUpdateFunc) const {
|
||||
NetObjManager::send_server_update_to_all_clients_except(*this, clientToNotSendTo, channel, sendUpdateFunc);
|
||||
}
|
||||
|
||||
template <typename T> void NetObjTemporaryPtr<T>::send_update_to_all(const std::string& channel, std::function<void(const NetObjTemporaryPtr<T>&, cereal::PortableBinaryOutputArchive&)> sendUpdateFunc) const {
|
||||
NetObjManager::send_update_to_all(*this, channel, sendUpdateFunc);
|
||||
}
|
||||
|
||||
template <typename T> void NetObjTemporaryPtr<T>::write_create_message(cereal::PortableBinaryOutputArchive& a) const {
|
||||
NetObjManager::write_create_message(*this, a);
|
||||
}
|
||||
|
||||
template <typename T> NetObjTemporaryPtr<T>::NetObjTemporaryPtr(NetObjManager* initObjMan, NetObjID initID, T* initRawPtr):
|
||||
objMan(initObjMan),
|
||||
id(initID),
|
||||
rawPtr(initRawPtr)
|
||||
{}
|
||||
}
|
||||
|
||||
|
|
@ -1,7 +1,9 @@
|
|||
#pragma once
|
||||
#include "NetObjID.hpp"
|
||||
#include "NetObjManager.hpp"
|
||||
#include "NetObjPtr.decl.hpp"
|
||||
#include "NetObjOwnerPtr.decl.hpp"
|
||||
#include "NetObjTemporaryPtr.decl.hpp"
|
||||
#include <memory>
|
||||
|
||||
namespace NetworkingObjects {
|
||||
template <typename T> class NetObjWeakPtr {
|
||||
|
|
@ -14,10 +16,22 @@ namespace NetworkingObjects {
|
|||
objMan(other.objMan),
|
||||
id(other.id)
|
||||
{}
|
||||
NetObjWeakPtr(const NetObjPtr<T>& other):
|
||||
NetObjWeakPtr(const NetObjOwnerPtr<T>& other):
|
||||
objMan(other.objMan),
|
||||
id(other.id)
|
||||
{}
|
||||
NetObjWeakPtr(const NetObjTemporaryPtr<T>& other):
|
||||
objMan(other.objMan),
|
||||
id(other.id)
|
||||
{}
|
||||
NetObjWeakPtr& operator=(const NetObjOwnerPtr<T>& other) {
|
||||
objMan = other.objMan;
|
||||
id = other.id;
|
||||
}
|
||||
NetObjWeakPtr& operator=(const NetObjTemporaryPtr<T>& other) {
|
||||
objMan = other.objMan;
|
||||
id = other.id;
|
||||
}
|
||||
NetObjWeakPtr& operator=(const NetObjWeakPtr& other) {
|
||||
objMan = other.objMan;
|
||||
id = other.id;
|
||||
|
|
@ -26,17 +40,15 @@ namespace NetworkingObjects {
|
|||
return NetObjWeakPtr<S>(objMan, id);
|
||||
}
|
||||
bool expired() const {
|
||||
if(!objMan)
|
||||
return true;
|
||||
auto it = objMan->objectData.find(id);
|
||||
return it == objMan->objectData.end();
|
||||
return !objMan || objMan->objectData.contains(id);
|
||||
}
|
||||
NetObjPtr<T> lock() const {
|
||||
NetObjTemporaryPtr<T> lock() const {
|
||||
if(!objMan)
|
||||
return NetObjTemporaryPtr<T>();
|
||||
auto it = objMan->objectData.find(id);
|
||||
if(it == objMan->objectData.end())
|
||||
return NetObjPtr<T>();
|
||||
else
|
||||
return NetObjPtr<T>(objMan, id, std::static_pointer_cast<T>(it->second.p));
|
||||
return NetObjTemporaryPtr<T>();
|
||||
return NetObjTemporaryPtr<T>(objMan, id, static_cast<T*>(it->second.p));
|
||||
}
|
||||
NetObjManager* get_obj_man() const {
|
||||
return objMan;
|
||||
|
|
@ -56,7 +68,6 @@ namespace NetworkingObjects {
|
|||
id(initID)
|
||||
{}
|
||||
|
||||
template <typename S> friend class NetObjPtr;
|
||||
NetObjManager* objMan;
|
||||
NetObjID id;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -23,32 +23,15 @@ void BookmarkManager::init() {
|
|||
}
|
||||
|
||||
void BookmarkManager::add_bookmark(const std::string& name) {
|
||||
NetworkingObjects::NetObjPtr<Bookmark> bookmarkPtr = bookmarks->emplace_back_direct(bookmarks, Bookmark{name, world.drawData.cam.c, world.main.window.size.cast<int32_t>()});
|
||||
uint32_t pos = bookmarks->size() - 1;
|
||||
world.undo.push({[&bookmarks = bookmarks, bookmarkPtr](){
|
||||
bookmarks->erase(bookmarks, bookmarkPtr);
|
||||
return true;
|
||||
},
|
||||
[&bookmarks = bookmarks, bookmarkPtr, pos]() {
|
||||
bookmarks->insert_and_send_create(bookmarks, pos, bookmarkPtr);
|
||||
return true;
|
||||
}});
|
||||
bookmarks->emplace_back_direct(bookmarks, Bookmark{name, world.drawData.cam.c, world.main.window.size.cast<int32_t>()});
|
||||
}
|
||||
|
||||
void BookmarkManager::remove_bookmark(uint32_t bookmarkIndex) {
|
||||
NetworkingObjects::NetObjPtr<Bookmark> bookmarkPtr = bookmarks->erase(bookmarks, bookmarkIndex);
|
||||
world.undo.push({[&bookmarks = bookmarks, bookmarkPtr, bookmarkIndex]() {
|
||||
bookmarks->insert_and_send_create(bookmarks, bookmarkIndex, bookmarkPtr);
|
||||
return true;
|
||||
},
|
||||
[&bookmarks = bookmarks, bookmarkPtr](){
|
||||
bookmarks->erase(bookmarks, bookmarkPtr);
|
||||
return true;
|
||||
}});
|
||||
bookmarks->erase(bookmarks, bookmarkIndex);
|
||||
}
|
||||
|
||||
void BookmarkManager::jump_to_bookmark(uint32_t bookmarkIndex) {
|
||||
const NetworkingObjects::NetObjPtr<Bookmark>& b = bookmarks->at(bookmarkIndex);
|
||||
auto& b = bookmarks->at(bookmarkIndex);
|
||||
world.drawData.cam.smooth_move_to(world, b->coords, b->windowSize.cast<float>());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ class BookmarkManager {
|
|||
}
|
||||
}
|
||||
|
||||
NetworkingObjects::NetObjPtr<NetworkingObjects::NetObjOrderedList<Bookmark>> bookmarks;
|
||||
NetworkingObjects::NetObjOwnerPtr<NetworkingObjects::NetObjOrderedList<Bookmark>> bookmarks;
|
||||
private:
|
||||
World& world;
|
||||
};
|
||||
|
|
|
|||
0
src/CanvasComponents/CanvasComponent.cpp
Normal file
0
src/CanvasComponents/CanvasComponent.cpp
Normal file
20
src/CanvasComponents/CanvasComponent.hpp
Normal file
20
src/CanvasComponents/CanvasComponent.hpp
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
#pragma once
|
||||
#include <cstdint>
|
||||
#include <cereal/archives/portable_binary.hpp>
|
||||
#include <Helpers/VersionNumber.hpp>
|
||||
|
||||
class CanvasComponent {
|
||||
public:
|
||||
enum class CompType : uint8_t {
|
||||
BRUSHSTROKE = 0,
|
||||
RECTANGLE,
|
||||
ELLIPSE,
|
||||
TEXTBOX,
|
||||
IMAGE
|
||||
};
|
||||
protected:
|
||||
virtual void write_update() const;
|
||||
virtual void read_update();
|
||||
virtual void save_file(cereal::PortableBinaryOutputArchive& a) const;
|
||||
virtual void load_file(cereal::PortableBinaryInputArchive& a, VersionNumber version);
|
||||
};
|
||||
0
src/CanvasComponents/CanvasComponentBrushStroke.cpp
Normal file
0
src/CanvasComponents/CanvasComponentBrushStroke.cpp
Normal file
62
src/CanvasComponents/CanvasComponentBrushStroke.hpp
Normal file
62
src/CanvasComponents/CanvasComponentBrushStroke.hpp
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
#pragma once
|
||||
#include "CanvasComponent.hpp"
|
||||
#include "Helpers/SCollision.hpp"
|
||||
#include <Helpers/Serializers.hpp>
|
||||
#include <include/core/SkPath.h>
|
||||
#include <include/core/SkPathBuilder.h>
|
||||
|
||||
struct DrawBrushStrokePoint {
|
||||
Vector2f pos;
|
||||
float width;
|
||||
|
||||
template <typename Archive> void serialize(Archive& a) {
|
||||
a(pos, width);
|
||||
}
|
||||
};
|
||||
|
||||
class CanvasComponentBrushStroke : public CanvasComponent {
|
||||
public:
|
||||
constexpr static float DRAW_MINIMUM_LIMIT = 0.3;
|
||||
|
||||
virtual DrawComponentType get_type() const override;
|
||||
virtual void write_update(cereal::PortableBinaryOutputArchive& a) const override;
|
||||
virtual void read_update(cereal::PortableBinaryInputArchive& a) override;
|
||||
virtual void save_file(cereal::PortableBinaryOutputArchive& a) const override;
|
||||
virtual void load_file(cereal::PortableBinaryInputArchive& a, VersionNumber version) override;
|
||||
|
||||
struct Data {
|
||||
std::vector<DrawBrushStrokePoint> points;
|
||||
Vector4f color;
|
||||
bool hasRoundCaps;
|
||||
};
|
||||
std::shared_ptr<Data> d = std::make_shared<Data>(); // It's a pointer here since brush strokes cant be edited
|
||||
|
||||
#ifndef IS_SERVER
|
||||
virtual std::shared_ptr<DrawComponent> copy(DrawingProgram& drawP) const override;
|
||||
virtual std::shared_ptr<DrawComponent> deep_copy(DrawingProgram& drawP) const override;
|
||||
|
||||
virtual void draw(SkCanvas* canvas, const DrawData& drawData) override;
|
||||
virtual void initialize_draw_data(DrawingProgram& drawP) override;
|
||||
virtual void update(DrawingProgram& drawP) override;
|
||||
virtual bool collides_within_coords(const SCollision::ColliderCollection<float>& checkAgainst) override;
|
||||
void create_collider();
|
||||
virtual void update_from_delayed_ptr(const std::shared_ptr<DrawComponent>& delayedUpdatePtr) override;
|
||||
|
||||
virtual SCollision::AABB<float> get_obj_coord_bounds() const override;
|
||||
|
||||
std::shared_ptr<SkPath> brushPath;
|
||||
SCollision::AABB<float> bounds;
|
||||
|
||||
std::array<std::shared_ptr<SkPath>, 2> brushPathLOD;
|
||||
private:
|
||||
std::vector<DrawBrushStrokePoint> every_nth_point_include_front_and_back(const std::vector<DrawBrushStrokePoint>& pts, size_t n);
|
||||
|
||||
void add_precheck_aabb_level(size_t level, const std::vector<SCollision::BVHContainer<float>>& levelArray);
|
||||
std::vector<SCollision::AABB<float>> precheckAABBLevels;
|
||||
void create_triangles(const std::function<bool(Vector2f, Vector2f, Vector2f)>& passTriangleFunc, const std::vector<DrawBrushStrokePoint>& smoothedPoints, size_t skipVertexCount, std::shared_ptr<SkPathBuilder> bPath);
|
||||
std::vector<size_t> get_wedge_indices(const std::vector<DrawBrushStrokePoint>& points);
|
||||
std::vector<DrawBrushStrokePoint> smooth_points(size_t beginIndex, size_t endIndex, unsigned numOfDivisions);
|
||||
std::vector<DrawBrushStrokePoint> smooth_points_avg(size_t beginIndex, size_t endIndex, unsigned numOfDivisions);
|
||||
#endif
|
||||
};
|
||||
|
||||
41
src/CanvasComponents/CanvasComponentContainer.cpp
Normal file
41
src/CanvasComponents/CanvasComponentContainer.cpp
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
#include "CanvasComponentContainer.hpp"
|
||||
|
||||
CanvasComponentContainer::CanvasComponentContainer() { }
|
||||
|
||||
CanvasComponentContainer::CanvasComponentContainer(CanvasComponent::CompType type) {
|
||||
allocate_comp(type);
|
||||
}
|
||||
|
||||
void CanvasComponentContainer::register_class(NetworkingObjects::NetObjManagerTypeList& t) {
|
||||
t.register_class<CanvasComponentContainer, CanvasComponentContainer, CanvasComponentContainer, CanvasComponentContainer>({
|
||||
});
|
||||
}
|
||||
|
||||
std::unique_ptr<CanvasComponent> CanvasComponentContainer::allocate_comp(CanvasComponent::CompType type) {
|
||||
switch(type) {
|
||||
case CanvasComponent::CompType::BRUSHSTROKE:
|
||||
return std::make_unique<CanvasComponentBrushStroke>();
|
||||
case CanvasComponent::CompType::RECTANGLE:
|
||||
return std::make_unique<CanvasComponentRectangle>();
|
||||
case CanvasComponent::CompType::ELLIPSE:
|
||||
return std::make_unique<CanvasComponentEllipse>();
|
||||
case CanvasComponent::CompType::TEXTBOX:
|
||||
return std::make_unique<CanvasComponentTextBox>();
|
||||
case CanvasComponent::CompType::IMAGE:
|
||||
return std::make_unique<CanvasComponentImage>();
|
||||
}
|
||||
}
|
||||
|
||||
void CanvasComponentContainer::save_file(cereal::PortableBinaryOutputArchive& a) const {
|
||||
}
|
||||
|
||||
void CanvasComponentContainer::load_file(cereal::PortableBinaryInputArchive& a, VersionNumber version) {
|
||||
}
|
||||
|
||||
const std::unique_ptr<CanvasComponent>& CanvasComponentContainer::get_comp() {
|
||||
return comp;
|
||||
}
|
||||
|
||||
const CoordSpaceHelper& CanvasComponentContainer::get_coords() {
|
||||
return coords;
|
||||
}
|
||||
20
src/CanvasComponents/CanvasComponentContainer.hpp
Normal file
20
src/CanvasComponents/CanvasComponentContainer.hpp
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
#pragma once
|
||||
#include "../CoordSpaceHelper.hpp"
|
||||
#include "CanvasComponent.hpp"
|
||||
#include <Helpers/NetworkingObjects/NetObjManagerTypeList.hpp>
|
||||
#include "../VersionConstants.hpp"
|
||||
|
||||
class CanvasComponentContainer {
|
||||
public:
|
||||
CanvasComponentContainer();
|
||||
CanvasComponentContainer(CanvasComponent::CompType type);
|
||||
static void register_class(NetworkingObjects::NetObjManagerTypeList& t);
|
||||
void save_file(cereal::PortableBinaryOutputArchive& a) const;
|
||||
void load_file(cereal::PortableBinaryInputArchive& a, VersionNumber version);
|
||||
const std::unique_ptr<CanvasComponent>& get_comp();
|
||||
const CoordSpaceHelper& get_coords();
|
||||
private:
|
||||
std::unique_ptr<CanvasComponent> allocate_comp(CanvasComponent::CompType type);
|
||||
std::unique_ptr<CanvasComponent> comp;
|
||||
CoordSpaceHelper coords;
|
||||
};
|
||||
|
|
@ -283,7 +283,7 @@ void DrawingProgram::tool_options_gui() {
|
|||
}
|
||||
}
|
||||
|
||||
void DrawingProgram::modify_grid(const NetworkingObjects::NetObjPtr<WorldGrid>& gridToModify) {
|
||||
void DrawingProgram::modify_grid(const NetworkingObjects::NetObjWeakPtr<WorldGrid>& gridToModify) {
|
||||
std::unique_ptr<GridModifyTool> newTool(std::make_unique<GridModifyTool>(*this));
|
||||
newTool->set_grid(gridToModify);
|
||||
switch_to_tool_ptr(std::move(newTool));
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
#include "../DrawData.hpp"
|
||||
#include "DrawingProgramCache.hpp"
|
||||
#include "GridModifyTool.hpp"
|
||||
#include <Helpers/NetworkingObjects/NetObjPtr.hpp>
|
||||
#include <Helpers/NetworkingObjects/NetObjWeakPtr.hpp>
|
||||
#include "PanCanvasTool.hpp"
|
||||
#include "ZoomCanvasTool.hpp"
|
||||
#include "cereal/archives/portable_binary.hpp"
|
||||
|
|
@ -64,7 +64,7 @@ class DrawingProgram {
|
|||
|
||||
void clear_draw_cache();
|
||||
|
||||
void modify_grid(const NetworkingObjects::NetObjPtr<WorldGrid>& gridToModify);
|
||||
void modify_grid(const NetworkingObjects::NetObjWeakPtr<WorldGrid>& gridToModify);
|
||||
|
||||
private:
|
||||
std::optional<std::chrono::steady_clock::time_point> badFrametimeTimePoint;
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
#include "../MainProgram.hpp"
|
||||
#include "../DrawData.hpp"
|
||||
#include "Helpers/Networking/NetLibrary.hpp"
|
||||
#include "Helpers/NetworkingObjects/NetObjTemporaryPtr.decl.hpp"
|
||||
#include <Helpers/NetworkingObjects/NetObjWeakPtr.hpp>
|
||||
#include <Helpers/NetworkingObjects/NetObjGenericSerializedClass.hpp>
|
||||
#include <cstddef>
|
||||
|
|
@ -14,10 +15,11 @@ GridModifyTool::GridModifyTool(DrawingProgram& initDrawP):
|
|||
{
|
||||
}
|
||||
|
||||
void GridModifyTool::set_grid(const NetObjPtr<WorldGrid>& newGrid) {
|
||||
void GridModifyTool::set_grid(const NetObjWeakPtr<WorldGrid>& newGrid) {
|
||||
grid = newGrid;
|
||||
if(drawP.world.gridMan.grids->contains(grid)) {
|
||||
WorldGrid& g = *grid;
|
||||
NetworkingObjects::NetObjTemporaryPtr<WorldGrid> gLock = grid.lock();
|
||||
if(gLock) {
|
||||
WorldGrid& g = *gLock;
|
||||
oldGrid = g;
|
||||
CoordSpaceHelper newCam;
|
||||
newCam.inverseScale = g.size / WorldScalar(WorldGrid::GRID_UNIT_PIXEL_SIZE);
|
||||
|
|
@ -35,8 +37,9 @@ void GridModifyTool::gui_toolbox() {
|
|||
Toolbar& t = drawP.world.main.toolbar;
|
||||
t.gui.push_id("Grid modify tool");
|
||||
t.gui.text_label_centered("Edit Grid");
|
||||
if(drawP.world.gridMan.grids->contains(grid)) {
|
||||
WorldGrid& g = *grid;
|
||||
NetworkingObjects::NetObjTemporaryPtr<WorldGrid> gLock = grid.lock();
|
||||
if(gLock) {
|
||||
WorldGrid& g = *gLock;
|
||||
t.gui.input_text_field("grid name", "Name", &g.name);
|
||||
t.gui.checkbox_field("Visible", "Visible", &g.visible);
|
||||
t.gui.checkbox_field("Display in Front", "Display in front of canvas", &g.displayInFront);
|
||||
|
|
@ -86,8 +89,9 @@ bool GridModifyTool::right_click_popup_gui(Vector2f popupPos) {
|
|||
}
|
||||
|
||||
void GridModifyTool::tool_update() {
|
||||
if(drawP.world.gridMan.grids->contains(grid)) {
|
||||
WorldGrid& g = *grid;
|
||||
NetworkingObjects::NetObjTemporaryPtr<WorldGrid> gLock = grid.lock();
|
||||
if(gLock) {
|
||||
WorldGrid& g = *gLock;
|
||||
switch(selectionMode) {
|
||||
case 0:
|
||||
if(drawP.controls.leftClick) {
|
||||
|
|
@ -137,7 +141,7 @@ void GridModifyTool::tool_update() {
|
|||
selectionMode = 0;
|
||||
break;
|
||||
}
|
||||
drawP.world.delayedUpdateObjectManager.send_update_to_all<WorldGrid>(grid, false);
|
||||
drawP.world.delayedUpdateObjectManager.send_update_to_all<WorldGrid>(gLock, false);
|
||||
}
|
||||
else
|
||||
selectionMode = 0;
|
||||
|
|
@ -148,8 +152,9 @@ bool GridModifyTool::prevent_undo_or_redo() {
|
|||
}
|
||||
|
||||
void GridModifyTool::draw(SkCanvas* canvas, const DrawData& drawData) {
|
||||
if(drawP.world.gridMan.grids->contains(grid)) {
|
||||
WorldGrid& g = *grid;
|
||||
NetworkingObjects::NetObjTemporaryPtr<WorldGrid> gLock = grid.lock();
|
||||
if(gLock) {
|
||||
WorldGrid& g = *gLock;
|
||||
if(g.bounds.has_value()) {
|
||||
const auto& b = g.bounds.value();
|
||||
Vector2f bMin = drawP.world.drawData.cam.c.to_space(b.min);
|
||||
|
|
@ -180,5 +185,7 @@ void GridModifyTool::draw(SkCanvas* canvas, const DrawData& drawData) {
|
|||
}
|
||||
|
||||
void GridModifyTool::switch_tool(DrawingProgramToolType newTool) {
|
||||
drawP.world.delayedUpdateObjectManager.send_update_to_all<WorldGrid>(grid, true);
|
||||
NetworkingObjects::NetObjTemporaryPtr<WorldGrid> gLock = grid.lock();
|
||||
if(gLock)
|
||||
drawP.world.delayedUpdateObjectManager.send_update_to_all<WorldGrid>(gLock, true);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
#pragma once
|
||||
#include "DrawingProgramToolBase.hpp"
|
||||
#include "../WorldGrid.hpp"
|
||||
#include "Helpers/NetworkingObjects/NetObjPtr.hpp"
|
||||
#include "Helpers/NetworkingObjects/NetObjWeakPtr.hpp"
|
||||
|
||||
class DrawingProgram;
|
||||
|
||||
class GridModifyTool : public DrawingProgramToolBase {
|
||||
public:
|
||||
GridModifyTool(DrawingProgram& initDrawP);
|
||||
void set_grid(const NetworkingObjects::NetObjPtr<WorldGrid>& newGrid);
|
||||
void set_grid(const NetworkingObjects::NetObjWeakPtr<WorldGrid>& newGrid);
|
||||
virtual DrawingProgramToolType get_type() override;
|
||||
virtual void gui_toolbox() override;
|
||||
virtual bool right_click_popup_gui(Vector2f popupPos) override;
|
||||
|
|
@ -18,6 +18,6 @@ class GridModifyTool : public DrawingProgramToolBase {
|
|||
virtual void switch_tool(DrawingProgramToolType newTool) override;
|
||||
private:
|
||||
WorldGrid oldGrid;
|
||||
NetworkingObjects::NetObjPtr<WorldGrid> grid;
|
||||
NetworkingObjects::NetObjWeakPtr<WorldGrid> grid;
|
||||
unsigned selectionMode = 0;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -21,32 +21,13 @@ void GridManager::add_default_grid(const std::string& newName) {
|
|||
g.color = color_mul_alpha(convert_vec4<Vector4f>(world.canvasTheme.toolFrontColor), 0.4f);
|
||||
g.size = world.drawData.cam.c.inverseScale * WorldScalar(WorldGrid::GRID_UNIT_PIXEL_SIZE);
|
||||
g.offset = world.drawData.cam.c.pos + world.drawData.cam.c.dir_from_space(world.main.window.size.cast<float>() * 0.5f);
|
||||
NetworkingObjects::NetObjPtr<WorldGrid> gridPtr = grids->emplace_back_direct(grids, g);
|
||||
|
||||
uint32_t pos = grids->size() - 1;
|
||||
world.undo.push({[&grids = grids, gridPtr](){
|
||||
grids->erase(grids, gridPtr);
|
||||
return true;
|
||||
},
|
||||
[&grids = grids, gridPtr, pos]() {
|
||||
grids->insert_and_send_create(grids, pos, gridPtr);
|
||||
return true;
|
||||
}});
|
||||
grids->emplace_back_direct(grids, g);
|
||||
}
|
||||
}
|
||||
|
||||
void GridManager::remove_grid(uint32_t indexToRemove) {
|
||||
if(grids) {
|
||||
NetworkingObjects::NetObjPtr<WorldGrid> gridPtr = grids->erase(grids, indexToRemove);
|
||||
world.undo.push({[&grids = grids, gridPtr, indexToRemove]() {
|
||||
grids->insert_and_send_create(grids, indexToRemove, gridPtr);
|
||||
return true;
|
||||
},
|
||||
[&grids = grids, gridPtr](){
|
||||
grids->erase(grids, gridPtr);
|
||||
return true;
|
||||
}});
|
||||
}
|
||||
if(grids)
|
||||
grids->erase(grids, indexToRemove);
|
||||
}
|
||||
|
||||
void GridManager::draw_back(SkCanvas* canvas, const DrawData& drawData) {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#pragma once
|
||||
#include "Helpers/NetworkingObjects/NetObjPtr.decl.hpp"
|
||||
#include "WorldGrid.hpp"
|
||||
#include <Helpers/NetworkingObjects/NetObjOrderedList.hpp>
|
||||
#include <Helpers/NetworkingObjects/NetObjOwnerPtr.hpp>
|
||||
|
||||
class World;
|
||||
|
||||
|
|
@ -33,6 +33,6 @@ class GridManager {
|
|||
void draw_coordinates(SkCanvas* canvas, const DrawData& drawData);
|
||||
void scale_up(const WorldScalar& scaleUpAmount);
|
||||
|
||||
NetworkingObjects::NetObjPtr<NetworkingObjects::NetObjOrderedList<WorldGrid>> grids;
|
||||
NetworkingObjects::NetObjOwnerPtr<NetworkingObjects::NetObjOrderedList<WorldGrid>> grids;
|
||||
World& world;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -38,8 +38,6 @@
|
|||
#endif
|
||||
|
||||
#include <Helpers/Logger.hpp>
|
||||
#include <Helpers/NetworkingObjects/NetObjOrderedList.hpp>
|
||||
#include <Helpers/NetworkingObjects/NetObjGenericSerializedClass.hpp>
|
||||
|
||||
MainProgram::MainProgram():
|
||||
fonts(std::make_shared<FontData>()),
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#pragma once
|
||||
#include "Helpers/NetworkingObjects/DelayUpdateSerializedClassManager.hpp"
|
||||
#include "Helpers/NetworkingObjects/NetObjOrderedList.hpp"
|
||||
#include <Helpers/NetworkingObjects/DelayUpdateSerializedClassManager.hpp>
|
||||
#include <Helpers/NetworkingObjects/NetObjOrderedList.hpp>
|
||||
#include "UndoManager.hpp"
|
||||
#include "BookmarkManager.hpp"
|
||||
#include "ResourceManager.hpp"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue