Added generic delayed update objects
This commit is contained in:
parent
ceafbf8bb6
commit
d266508bbf
14 changed files with 176 additions and 43 deletions
|
|
@ -103,6 +103,7 @@ set(sources "src/main.cpp"
|
|||
"include/Helpers/Networking/NetServer.cpp"
|
||||
"include/Helpers/Networking/NetClient.cpp"
|
||||
"include/Helpers/Networking/ByteStream.cpp"
|
||||
"include/Helpers/NetworkingObjects/DelayUpdateSerializedClassManager.cpp"
|
||||
"include/Helpers/NetworkingObjects/NetObjManagerTypeList.cpp"
|
||||
"include/Helpers/NetworkingObjects/NetObjManager.cpp"
|
||||
"include/Helpers/NetworkingObjects/NetObjID.cpp"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
#include "DelayUpdateSerializedClassManager.hpp"
|
||||
|
||||
namespace NetworkingObjects {
|
||||
void DelayUpdateSerializedClassManager::update() {
|
||||
std::erase_if(updatingObjs, [](auto& updatingPair) {
|
||||
if((std::chrono::steady_clock::now() - updatingPair.second.lastUpdateTimePoint) >= std::chrono::seconds(3)) {
|
||||
updatingPair.second.setDataAfterTimeout();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,105 @@
|
|||
#pragma once
|
||||
#include "NetObjWeakPtr.hpp"
|
||||
#include "cereal/archives/portable_binary.hpp"
|
||||
#include <chrono>
|
||||
|
||||
namespace NetworkingObjects {
|
||||
class DelayUpdateSerializedClassManager {
|
||||
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>(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);}
|
||||
});
|
||||
}
|
||||
template <typename T> void send_update_to_all(const NetworkingObjects::NetObjPtr<T>& o) {
|
||||
o.send_update_to_all(RELIABLE_COMMAND_CHANNEL, [&](const NetObjPtr<T>& o, cereal::PortableBinaryOutputArchive& a) {
|
||||
if(o.get_obj_man()->is_server())
|
||||
server_write_func(o, a);
|
||||
else
|
||||
client_write_func(o, a);
|
||||
});
|
||||
}
|
||||
void update();
|
||||
private:
|
||||
template <typename T> void client_write_func(const NetObjPtr<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)
|
||||
*oLock = *std::static_pointer_cast<T>(currentData);
|
||||
};
|
||||
updatingObjs.emplace(o.get_net_id(), toAdd);
|
||||
}
|
||||
else {
|
||||
auto& [netID, updatingObjData] = *it;
|
||||
updatingObjData.lastUpdateTimePoint = std::chrono::steady_clock::now();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T> void delay_read_func(const NetObjPtr<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));
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T> void server_write_func(const NetObjPtr<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) {
|
||||
*oLock = *std::static_pointer_cast<T>(currentData);
|
||||
oLock.send_server_update_to_all_clients(RELIABLE_COMMAND_CHANNEL, [](const NetObjPtr<T>& o, cereal::PortableBinaryOutputArchive& a) {
|
||||
a(*o);
|
||||
});
|
||||
}
|
||||
};
|
||||
updatingObjs.emplace(o.get_net_id(), toAdd);
|
||||
}
|
||||
else {
|
||||
auto& [netID, updatingObjData] = *it;
|
||||
updatingObjData.lastUpdateTimePoint = std::chrono::steady_clock::now();
|
||||
*std::static_pointer_cast<T>(updatingObjs[o.get_net_id()].objToUpdateCurrentData) = *o;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T> void server_read_update_func(const NetObjPtr<T>& o, cereal::PortableBinaryInputArchive& a) {
|
||||
auto it = updatingObjs.find(o.get_net_id());
|
||||
if(it == updatingObjs.end()) {
|
||||
a(*o);
|
||||
o.send_server_update_to_all_clients(RELIABLE_COMMAND_CHANNEL, [](const NetObjPtr<T>& o, cereal::PortableBinaryOutputArchive& a) {
|
||||
a(*o);
|
||||
});
|
||||
}
|
||||
else {
|
||||
auto& [netID, updatingObjData] = *it;
|
||||
a(*std::static_pointer_cast<T>(updatingObjData.objToUpdateCurrentData));
|
||||
}
|
||||
}
|
||||
|
||||
struct UpdatingObject {
|
||||
std::shared_ptr<void> objToUpdateCurrentData;
|
||||
std::chrono::steady_clock::time_point lastUpdateTimePoint;
|
||||
std::function<void()> setDataAfterTimeout;
|
||||
};
|
||||
std::unordered_map<NetObjID, UpdatingObject> updatingObjs;
|
||||
};
|
||||
}
|
||||
|
|
@ -1,25 +1,24 @@
|
|||
#pragma once
|
||||
#include "Helpers/NetworkingObjects/NetObjPtr.decl.hpp"
|
||||
#include "NetObjPtr.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) {
|
||||
a(*o);
|
||||
}
|
||||
|
||||
template <typename T> void default_serialize_read_func(const NetObjPtr<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 = [](const NetObjPtr<T>& o, cereal::PortableBinaryOutputArchive& a) {
|
||||
a(*o);
|
||||
},
|
||||
.readConstructorFuncClient = [](const NetObjPtr<T>& o, cereal::PortableBinaryInputArchive& a, const std::shared_ptr<NetServer::ClientData>&) {
|
||||
a(*o);
|
||||
},
|
||||
.readUpdateFuncClient = [](const NetObjPtr<T>& o, cereal::PortableBinaryInputArchive& a, const std::shared_ptr<NetServer::ClientData>&) {
|
||||
a(*o);
|
||||
},
|
||||
.writeConstructorFuncServer = [](const NetObjPtr<T>& o, cereal::PortableBinaryOutputArchive& a) {
|
||||
a(*o);
|
||||
},
|
||||
.readConstructorFuncServer = [](const NetObjPtr<T>& o, cereal::PortableBinaryInputArchive& a, const std::shared_ptr<NetServer::ClientData>&) {
|
||||
a(*o);
|
||||
},
|
||||
.writeConstructorFuncClient = default_serialize_write_func<T>,
|
||||
.readConstructorFuncClient = default_serialize_read_func<T>,
|
||||
.readUpdateFuncClient = default_serialize_read_func<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>&) {
|
||||
a(*o);
|
||||
o.send_server_update_to_all_clients(RELIABLE_COMMAND_CHANNEL, [](const NetObjPtr<T>& o, cereal::PortableBinaryOutputArchive& a) {
|
||||
|
|
@ -30,8 +29,6 @@ namespace NetworkingObjects {
|
|||
}
|
||||
|
||||
template <typename T> void generic_serialized_class_send_update_to_all(const NetworkingObjects::NetObjPtr<T>& o) {
|
||||
o.send_update_to_all(RELIABLE_COMMAND_CHANNEL, [](const NetworkingObjects::NetObjPtr<T>& o, cereal::PortableBinaryOutputArchive& a) {
|
||||
a(*o);
|
||||
});
|
||||
o.send_update_to_all(RELIABLE_COMMAND_CHANNEL, default_serialize_write_func<T>);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,12 +12,14 @@ void Bookmark::scale_up(const WorldScalar& scaleUpAmount) {
|
|||
|
||||
BookmarkManager::BookmarkManager(World& w):
|
||||
world(w)
|
||||
{
|
||||
{}
|
||||
|
||||
void BookmarkManager::init() {
|
||||
// NOTE: Should find a way for bookmarks added from the network to take into account the client's canvasScale
|
||||
// Have the canvasScale variable come with the ClientData object, and the grid scale commands can be part of
|
||||
// the client data class
|
||||
if(w.netObjMan.is_server())
|
||||
bookmarks = w.netObjMan.make_obj<NetworkingObjects::NetObjOrderedList<Bookmark>>();
|
||||
if(world.netObjMan.is_server())
|
||||
bookmarks = world.netObjMan.make_obj<NetworkingObjects::NetObjOrderedList<Bookmark>>();
|
||||
}
|
||||
|
||||
void BookmarkManager::add_bookmark(const std::string& name) {
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ class World;
|
|||
class BookmarkManager {
|
||||
public:
|
||||
BookmarkManager(World& w);
|
||||
void init();
|
||||
void add_bookmark(const std::string& name);
|
||||
void remove_bookmark(uint32_t bookmarkIndex);
|
||||
void jump_to_bookmark(uint32_t bookmarkIndex);
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@
|
|||
#include "../World.hpp"
|
||||
#include "../MainProgram.hpp"
|
||||
#include "Helpers/FileDownloader.hpp"
|
||||
#include "Helpers/NetworkingObjects/NetObjWeakPtr.hpp"
|
||||
#include "Helpers/StringHelpers.hpp"
|
||||
#include "LassoSelectTool.hpp"
|
||||
#include <Helpers/Logger.hpp>
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
#include "DrawingProgram.hpp"
|
||||
#include "../MainProgram.hpp"
|
||||
#include "../DrawData.hpp"
|
||||
#include "Helpers/Networking/NetLibrary.hpp"
|
||||
#include <Helpers/NetworkingObjects/NetObjWeakPtr.hpp>
|
||||
#include <Helpers/NetworkingObjects/NetObjGenericSerializedClass.hpp>
|
||||
#include <cstddef>
|
||||
|
|
@ -136,6 +137,7 @@ void GridModifyTool::tool_update() {
|
|||
selectionMode = 0;
|
||||
break;
|
||||
}
|
||||
drawP.world.delayedUpdateObjectManager.send_update_to_all<WorldGrid>(grid);
|
||||
}
|
||||
else
|
||||
selectionMode = 0;
|
||||
|
|
|
|||
|
|
@ -7,9 +7,11 @@
|
|||
#include <algorithm>
|
||||
|
||||
GridManager::GridManager(World& w):
|
||||
world(w) {
|
||||
if(w.netObjMan.is_server())
|
||||
grids = w.netObjMan.make_obj<NetworkingObjects::NetObjOrderedList<WorldGrid>>();
|
||||
world(w) {}
|
||||
|
||||
void GridManager::init() {
|
||||
if(world.netObjMan.is_server())
|
||||
grids = world.netObjMan.make_obj<NetworkingObjects::NetObjOrderedList<WorldGrid>>();
|
||||
}
|
||||
|
||||
void GridManager::add_default_grid(const std::string& newName) {
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ class World;
|
|||
class GridManager {
|
||||
public:
|
||||
GridManager(World& w);
|
||||
void init();
|
||||
|
||||
void add_default_grid(const std::string& newName);
|
||||
|
||||
|
|
|
|||
|
|
@ -45,14 +45,6 @@ MainProgram::MainProgram():
|
|||
fonts(std::make_shared<FontData>()),
|
||||
toolbar(*this)
|
||||
{
|
||||
netObjectTypeList = std::make_shared<NetworkingObjects::NetObjManagerTypeList>();
|
||||
NetworkingObjects::register_generic_serialized_class<std::string>(*netObjectTypeList);
|
||||
NetworkingObjects::register_ordered_list_class<std::string>(*netObjectTypeList);
|
||||
NetworkingObjects::register_generic_serialized_class<Bookmark>(*netObjectTypeList);
|
||||
NetworkingObjects::register_ordered_list_class<Bookmark>(*netObjectTypeList);
|
||||
NetworkingObjects::register_generic_serialized_class<WorldGrid>(*netObjectTypeList);
|
||||
NetworkingObjects::register_ordered_list_class<WorldGrid>(*netObjectTypeList);
|
||||
|
||||
displayName = Random::get().alphanumeric_str(10);
|
||||
|
||||
Logger::get().add_log("WORLDFATAL", [&](const std::string& text) {
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@
|
|||
#include "SharedTypes.hpp"
|
||||
#include <Eigen/Dense>
|
||||
#include <include/core/SkSurfaceProps.h>
|
||||
#include <Helpers/NetworkingObjects/NetObjManagerTypeList.hpp>
|
||||
#include "Toolbar.hpp"
|
||||
#include "World.hpp"
|
||||
|
||||
|
|
@ -116,8 +115,6 @@ class MainProgram {
|
|||
|
||||
std::string displayName;
|
||||
|
||||
std::shared_ptr<NetworkingObjects::NetObjManagerTypeList> netObjectTypeList;
|
||||
|
||||
~MainProgram();
|
||||
private:
|
||||
void new_tab_open();
|
||||
|
|
|
|||
|
|
@ -1,10 +1,13 @@
|
|||
#include "World.hpp"
|
||||
#include "DrawComponents/DrawComponent.hpp"
|
||||
#include "Helpers/HsvRgb.hpp"
|
||||
#include "Helpers/MathExtras.hpp"
|
||||
#include "Helpers/Networking/ByteStream.hpp"
|
||||
#include "Helpers/NetworkingObjects/NetObjManager.hpp"
|
||||
#include "Helpers/VersionNumber.hpp"
|
||||
#include <Helpers/HsvRgb.hpp>
|
||||
#include <Helpers/MathExtras.hpp>
|
||||
#include <Helpers/Networking/ByteStream.hpp>
|
||||
#include <Helpers/NetworkingObjects/NetObjManager.hpp>
|
||||
#include <Helpers/NetworkingObjects/NetObjManagerTypeList.hpp>
|
||||
#include <Helpers/VersionNumber.hpp>
|
||||
#include <Helpers/NetworkingObjects/NetObjGenericSerializedClass.hpp>
|
||||
#include <Helpers/NetworkingObjects/DelayUpdateSerializedClassManager.hpp>
|
||||
#include "Server/CommandList.hpp"
|
||||
#include "MainProgram.hpp"
|
||||
#include "SharedTypes.hpp"
|
||||
|
|
@ -27,13 +30,18 @@
|
|||
#endif
|
||||
|
||||
World::World(MainProgram& initMain, OpenWorldInfo& worldInfo):
|
||||
netObjMan(initMain.netObjectTypeList, worldInfo.conType != CONNECTIONTYPE_CLIENT),
|
||||
netObjectTypeList(std::make_shared<NetworkingObjects::NetObjManagerTypeList>()),
|
||||
netObjMan(netObjectTypeList, worldInfo.conType != CONNECTIONTYPE_CLIENT),
|
||||
main(initMain),
|
||||
rMan(*this),
|
||||
drawProg(*this),
|
||||
bMan(*this),
|
||||
gridMan(*this)
|
||||
{
|
||||
init_net_obj_type_list();
|
||||
gridMan.init();
|
||||
bMan.init();
|
||||
|
||||
set_canvas_background_color(main.defaultCanvasBackgroundColor);
|
||||
displayName = main.displayName;
|
||||
|
||||
|
|
@ -70,6 +78,13 @@ World::World(MainProgram& initMain, OpenWorldInfo& worldInfo):
|
|||
con.client_send_items_to_server(RELIABLE_COMMAND_CHANNEL, SERVER_INITIAL_DATA, displayName, false);
|
||||
}
|
||||
|
||||
void World::init_net_obj_type_list() {
|
||||
NetworkingObjects::register_generic_serialized_class<Bookmark>(*netObjectTypeList);
|
||||
NetworkingObjects::register_ordered_list_class<Bookmark>(*netObjectTypeList);
|
||||
delayedUpdateObjectManager.register_class<WorldGrid>(*netObjectTypeList);
|
||||
NetworkingObjects::register_ordered_list_class<WorldGrid>(*netObjectTypeList);
|
||||
}
|
||||
|
||||
void World::init_client_callbacks() {
|
||||
con.client_add_recv_callback(CLIENT_INITIAL_DATA, [&](cereal::PortableBinaryInputArchive& message) {
|
||||
bool isDirectConnect;
|
||||
|
|
@ -171,6 +186,7 @@ void World::focus_update() {
|
|||
}
|
||||
|
||||
if(!clientStillConnecting) {
|
||||
delayedUpdateObjectManager.update();
|
||||
constexpr float SECONDS_TO_SEND_CAMERA_DATA = 0.5f;
|
||||
timeToSendCameraData.update_time_since();
|
||||
if(timeToSendCameraData.get_time_since() > SECONDS_TO_SEND_CAMERA_DATA) {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#pragma once
|
||||
#include "Helpers/NetworkingObjects/DelayUpdateSerializedClassManager.hpp"
|
||||
#include "Helpers/NetworkingObjects/NetObjOrderedList.hpp"
|
||||
#include "UndoManager.hpp"
|
||||
#include "BookmarkManager.hpp"
|
||||
|
|
@ -36,6 +37,7 @@ class World {
|
|||
|
||||
World(MainProgram& initMain, OpenWorldInfo& worldInfo);
|
||||
|
||||
std::shared_ptr<NetworkingObjects::NetObjManagerTypeList> netObjectTypeList;
|
||||
// NOTE: Keep at the very beginning so that it's destroyed last
|
||||
NetworkingObjects::NetObjManager netObjMan;
|
||||
|
||||
|
|
@ -106,10 +108,13 @@ class World {
|
|||
uint64_t canvasScale = 0;
|
||||
|
||||
bool setToDestroy = false;
|
||||
NetworkingObjects::DelayUpdateSerializedClassManager delayedUpdateObjectManager;
|
||||
private:
|
||||
void init_net_obj_type_list();
|
||||
|
||||
ClientPortionID get_max_id(ServerPortionID serverID);
|
||||
|
||||
|
||||
void init_client_callbacks();
|
||||
void set_name(const std::string& n);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue