Added multi command block
This commit is contained in:
parent
6889eeff60
commit
279a9317a4
14 changed files with 173 additions and 106 deletions
|
|
@ -21,6 +21,8 @@
|
|||
#include "NetServer.hpp"
|
||||
#include <chrono>
|
||||
#include <Helpers/Logger.hpp>
|
||||
#include <cereal/types/vector.hpp>
|
||||
#include <cereal/types/string.hpp>
|
||||
|
||||
NetClient::NetClient(const std::string& serverFullID) {
|
||||
receiveQueue = std::make_shared<ReceiveQueue>();
|
||||
|
|
@ -111,9 +113,14 @@ void NetClient::parse_received_messages() {
|
|||
decode_fragmented_message(inArchive, spfm, NetLibrary::FRAGMENT_MESSAGE_STRIDE, [&](cereal::PortableBinaryInputArchive& completeArchive) {
|
||||
MessageCommandType completeCommandID;
|
||||
completeArchive(completeCommandID);
|
||||
recvCallbacks[completeCommandID](completeArchive);
|
||||
if(completeCommandID == 1)
|
||||
parse_multi_command_id(completeArchive);
|
||||
else
|
||||
recvCallbacks[completeCommandID](completeArchive);
|
||||
});
|
||||
}
|
||||
else if(commandID == 1)
|
||||
parse_multi_command_id(inArchive);
|
||||
else
|
||||
recvCallbacks[commandID](inArchive);
|
||||
|
||||
|
|
@ -121,23 +128,39 @@ void NetClient::parse_received_messages() {
|
|||
}
|
||||
}
|
||||
|
||||
void NetClient::parse_multi_command_id(cereal::PortableBinaryInputArchive& a) {
|
||||
std::vector<std::string> commands;
|
||||
a(commands);
|
||||
for(const std::string& str : commands) {
|
||||
ByteMemStream strm((char*)str.data(), str.size());
|
||||
cereal::PortableBinaryInputArchive inArchive(strm);
|
||||
MessageCommandType commandID;
|
||||
inArchive(commandID);
|
||||
recvCallbacks[commandID](inArchive);
|
||||
}
|
||||
}
|
||||
|
||||
void NetClient::send_string_stream_to_server(const std::string& channel, const std::shared_ptr<std::stringstream>& ss) {
|
||||
if(isDisconnected)
|
||||
return;
|
||||
|
||||
auto& messageQueue = messageQueues[channel];
|
||||
|
||||
if(channel == UNRELIABLE_COMMAND_CHANNEL) {
|
||||
if(ss->view().length() <= NetLibrary::MAX_UNRELIABLE_MESSAGE_SIZE) // Drop unreliable messages that are too big
|
||||
messageQueue.emplace(NetLibrary::calc_order_for_queued_message(channel, nextMessageOrderToSend), ss);
|
||||
}
|
||||
if(!multiCommandData.expired() && channel == multiCommandData.lock()->channelToSendTo)
|
||||
multiCommandData.lock()->commands.emplace_back(ss->str());
|
||||
else {
|
||||
std::vector<std::shared_ptr<std::stringstream>> fragmentedMessage = fragment_message(ss->view(), NetLibrary::FRAGMENT_MESSAGE_STRIDE);
|
||||
if(fragmentedMessage.empty())
|
||||
messageQueue.emplace(NetLibrary::calc_order_for_queued_message(channel, nextMessageOrderToSend), ss);
|
||||
auto& messageQueue = messageQueues[channel];
|
||||
|
||||
if(channel == UNRELIABLE_COMMAND_CHANNEL) {
|
||||
if(ss->view().length() <= NetLibrary::MAX_UNRELIABLE_MESSAGE_SIZE) // Drop unreliable messages that are too big
|
||||
messageQueue.emplace(NetLibrary::calc_order_for_queued_message(channel, nextMessageOrderToSend), ss);
|
||||
}
|
||||
else {
|
||||
for(auto& ss2 : fragmentedMessage)
|
||||
messageQueue.emplace(NetLibrary::calc_order_for_queued_message(channel, nextMessageOrderToSend), ss2);
|
||||
std::vector<std::shared_ptr<std::stringstream>> fragmentedMessage = fragment_message(ss->view(), NetLibrary::FRAGMENT_MESSAGE_STRIDE);
|
||||
if(fragmentedMessage.empty())
|
||||
messageQueue.emplace(NetLibrary::calc_order_for_queued_message(channel, nextMessageOrderToSend), ss);
|
||||
else {
|
||||
for(auto& ss2 : fragmentedMessage)
|
||||
messageQueue.emplace(NetLibrary::calc_order_for_queued_message(channel, nextMessageOrderToSend), ss2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -194,6 +217,22 @@ void NetClient::send_queued_messages() {
|
|||
}
|
||||
}
|
||||
|
||||
void NetClient::send_multi_command_to_server(const std::string& channel, const std::function<void()>& captureSendBlock) {
|
||||
if(!is_disconnected() && multiCommandData.expired() && !channel.empty()) { // Check for multiUpdateData.expired() to make sure we aren't overriding a previous call to send_multi_update_messsage
|
||||
std::shared_ptr<MultiCommandData> d = std::make_shared<MultiCommandData>();
|
||||
d->channelToSendTo = channel;
|
||||
multiCommandData = d; // Using weak pointer here ensures that object will be freed
|
||||
captureSendBlock();
|
||||
if(!d->commands.empty()) {
|
||||
std::vector<std::string> movedVec = std::move(d->commands);
|
||||
d = nullptr;
|
||||
send_items_to_server(channel, (MessageCommandType)1, movedVec);
|
||||
}
|
||||
}
|
||||
else
|
||||
captureSendBlock();
|
||||
}
|
||||
|
||||
bool NetClient::is_disconnected() const {
|
||||
return isDisconnected;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ class NetClient : public std::enable_shared_from_this<NetClient> {
|
|||
send_string_stream_to_server(channel, ss);
|
||||
}
|
||||
void send_string_stream_to_server(const std::string& channel, const std::shared_ptr<std::stringstream>& ss);
|
||||
void send_multi_command_to_server(const std::string& channel, const std::function<void()>& captureSendBlock);
|
||||
void update();
|
||||
void add_recv_callback(MessageCommandType commandID, const NetClientRecvCallback& callback);
|
||||
bool is_disconnected() const;
|
||||
|
|
@ -58,6 +59,7 @@ class NetClient : public std::enable_shared_from_this<NetClient> {
|
|||
void parse_received_messages();
|
||||
void send_queued_messages();
|
||||
void send_str_as_bytes(std::shared_ptr<rtc::DataChannel> channel, const std::string& str);
|
||||
void parse_multi_command_id(cereal::PortableBinaryInputArchive& inArchive);
|
||||
|
||||
struct OutgoingMessage {
|
||||
MessageOrder order;
|
||||
|
|
@ -90,6 +92,12 @@ class NetClient : public std::enable_shared_from_this<NetClient> {
|
|||
std::string serverFullID;
|
||||
bool fullyRegistered = false;
|
||||
|
||||
struct MultiCommandData {
|
||||
std::string channelToSendTo;
|
||||
std::vector<std::string> commands;
|
||||
};
|
||||
std::weak_ptr<MultiCommandData> multiCommandData;
|
||||
|
||||
std::chrono::steady_clock::time_point lastMessageTime;
|
||||
|
||||
friend class NetLibrary;
|
||||
|
|
|
|||
|
|
@ -24,7 +24,9 @@
|
|||
#include <Helpers/Random.hpp>
|
||||
#include <Helpers/Logger.hpp>
|
||||
#include "NetClient.hpp"
|
||||
#include "cereal/archives/portable_binary.hpp"
|
||||
#include <cereal/archives/portable_binary.hpp>
|
||||
#include <cereal/types/vector.hpp>
|
||||
#include <cereal/types/string.hpp>
|
||||
|
||||
NetServer::NetServer(const std::string& serverLocalID) {
|
||||
localID = serverLocalID;
|
||||
|
|
@ -124,6 +126,9 @@ void NetServer::client_connected(std::shared_ptr<rtc::PeerConnection> connection
|
|||
}
|
||||
|
||||
void NetServer::send_string_stream_to_client(const std::shared_ptr<ClientData>& client, const std::string& channel, const std::shared_ptr<std::stringstream>& ss) {
|
||||
if(!multiCommandData.expired() && channel == multiCommandData.lock()->channelToSendTo)
|
||||
throw std::runtime_error("[NetServer::send_string_stream_to_client] Can't call when in send_multi_command block using same channel");
|
||||
|
||||
if(!client)
|
||||
return;
|
||||
|
||||
|
|
@ -144,18 +149,33 @@ void NetServer::send_string_stream_to_client(const std::shared_ptr<ClientData>&
|
|||
}
|
||||
|
||||
void NetServer::send_string_stream_to_all_clients(const std::string& channel, const std::shared_ptr<std::stringstream>& ss) {
|
||||
send_string_stream_to_client_if([&](const std::shared_ptr<ClientData>& c) {
|
||||
return true;
|
||||
}, channel, ss);
|
||||
if(!multiCommandData.expired() && channel == multiCommandData.lock()->channelToSendTo)
|
||||
multiCommandData.lock()->commands.emplace_back(ss->str());
|
||||
else {
|
||||
send_string_stream_to_client_if([&](const std::shared_ptr<ClientData>& c) {
|
||||
return true;
|
||||
}, channel, ss);
|
||||
}
|
||||
}
|
||||
|
||||
void NetServer::send_string_stream_to_all_clients_except(const std::shared_ptr<ClientData>& client, const std::string& channel, const std::shared_ptr<std::stringstream>& ss) {
|
||||
send_string_stream_to_client_if([&](const std::shared_ptr<ClientData>& c) {
|
||||
return c != client;
|
||||
}, channel, ss);
|
||||
if(!multiCommandData.expired() && channel == multiCommandData.lock()->channelToSendTo) {
|
||||
if(!client)
|
||||
multiCommandData.lock()->commands.emplace_back(ss->str());
|
||||
else
|
||||
throw std::runtime_error("[NetServer::send_string_stream_to_all_clients_except] Can't call when in send_multi_command block using same channel");
|
||||
}
|
||||
else {
|
||||
send_string_stream_to_client_if([&](const std::shared_ptr<ClientData>& c) {
|
||||
return c != client;
|
||||
}, channel, ss);
|
||||
}
|
||||
}
|
||||
|
||||
void NetServer::send_string_stream_to_client_if(std::function<bool(const std::shared_ptr<ClientData>&)> clientChecker, const std::string& channel, const std::shared_ptr<std::stringstream>& ss) {
|
||||
if(!multiCommandData.expired() && channel == multiCommandData.lock()->channelToSendTo)
|
||||
throw std::runtime_error("[NetServer::send_string_stream_to_client_if] Can't call when in send_multi_command block using same channel");
|
||||
|
||||
if(channel == UNRELIABLE_COMMAND_CHANNEL) {
|
||||
if(ss->view().length() <= NetLibrary::MAX_UNRELIABLE_MESSAGE_SIZE) { // Drop unreliable messages that are too big
|
||||
for(auto& client : clients) {
|
||||
|
|
@ -183,6 +203,22 @@ void NetServer::send_string_stream_to_client_if(std::function<bool(const std::sh
|
|||
}
|
||||
}
|
||||
|
||||
void NetServer::send_multi_command_to_all_clients(const std::string& channel, const std::function<void()>& captureSendBlock) {
|
||||
if(!is_disconnected() && multiCommandData.expired() && !channel.empty()) { // Check for multiUpdateData.expired() to make sure we aren't overriding a previous call to send_multi_update_messsage
|
||||
std::shared_ptr<MultiCommandData> d = std::make_shared<MultiCommandData>();
|
||||
d->channelToSendTo = channel;
|
||||
multiCommandData = d; // Using weak pointer here ensures that object will be freed
|
||||
captureSendBlock();
|
||||
if(!d->commands.empty()) {
|
||||
std::vector<std::string> movedVec = std::move(d->commands);
|
||||
d = nullptr;
|
||||
send_items_to_all_clients(channel, (MessageCommandType)1, movedVec);
|
||||
}
|
||||
}
|
||||
else
|
||||
captureSendBlock();
|
||||
}
|
||||
|
||||
void NetServer::ClientData::send_queued_messages(NetServer& server) {
|
||||
for(auto& [channelName, messageQueue] : messageQueues) {
|
||||
bool addMessageOrder = NetLibrary::is_ordered_channel(channelName);
|
||||
|
|
@ -258,9 +294,14 @@ void NetServer::ClientData::parse_received_messages(NetServer& server) {
|
|||
decode_fragmented_message(inArchive, spfm, NetLibrary::FRAGMENT_MESSAGE_STRIDE, [&](cereal::PortableBinaryInputArchive& completeArchive) {
|
||||
MessageCommandType completeCommandID;
|
||||
completeArchive(completeCommandID);
|
||||
server.recvCallbacks[completeCommandID](shared_from_this(), completeArchive);
|
||||
if(completeCommandID == 1)
|
||||
parse_multi_command_id(server, completeArchive);
|
||||
else
|
||||
server.recvCallbacks[completeCommandID](shared_from_this(), completeArchive);
|
||||
});
|
||||
}
|
||||
else if(commandID == 1)
|
||||
parse_multi_command_id(server, inArchive);
|
||||
else
|
||||
server.recvCallbacks[commandID](shared_from_this(), inArchive);
|
||||
|
||||
|
|
@ -268,6 +309,18 @@ void NetServer::ClientData::parse_received_messages(NetServer& server) {
|
|||
}
|
||||
}
|
||||
|
||||
void NetServer::ClientData::parse_multi_command_id(NetServer& server, cereal::PortableBinaryInputArchive& a) {
|
||||
std::vector<std::string> commands;
|
||||
a(commands);
|
||||
for(const std::string& str : commands) {
|
||||
ByteMemStream strm((char*)str.data(), str.size());
|
||||
cereal::PortableBinaryInputArchive inArchive(strm);
|
||||
MessageCommandType commandID;
|
||||
inArchive(commandID);
|
||||
server.recvCallbacks[commandID](shared_from_this(), inArchive);
|
||||
}
|
||||
}
|
||||
|
||||
NetLibrary::DownloadProgress NetServer::ClientData::get_progress_into_fragmented_message(const std::string& channel) const {
|
||||
auto it = pfm.find(channel);
|
||||
if(it == pfm.end())
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ class NetServer : public std::enable_shared_from_this<NetServer> {
|
|||
|
||||
void send_queued_messages(NetServer& server);
|
||||
void parse_received_messages(NetServer& server);
|
||||
void parse_multi_command_id(NetServer& server, cereal::PortableBinaryInputArchive& a);
|
||||
void send_str_as_bytes(std::shared_ptr<rtc::DataChannel> channel, const std::string& str);
|
||||
NetLibrary::DownloadProgress get_progress_into_fragmented_message(const std::string& channel) const;
|
||||
|
||||
|
|
@ -98,6 +99,7 @@ class NetServer : public std::enable_shared_from_this<NetServer> {
|
|||
void send_string_stream_to_all_clients(const std::string& channel, const std::shared_ptr<std::stringstream>& ss);
|
||||
void send_string_stream_to_all_clients_except(const std::shared_ptr<ClientData>& client, const std::string& channel, const std::shared_ptr<std::stringstream>& ss);
|
||||
void send_string_stream_to_client_if(std::function<bool(const std::shared_ptr<ClientData>&)> clientChecker, const std::string& channel, const std::shared_ptr<std::stringstream>& ss);
|
||||
void send_multi_command_to_all_clients(const std::string& channel, const std::function<void()>& captureSendBlock);
|
||||
|
||||
bool is_disconnected() const;
|
||||
|
||||
|
|
@ -127,6 +129,12 @@ class NetServer : public std::enable_shared_from_this<NetServer> {
|
|||
NetClient* directConnectClient = nullptr;
|
||||
std::shared_ptr<ClientData> directConnectClientData;
|
||||
|
||||
struct MultiCommandData {
|
||||
std::string channelToSendTo;
|
||||
std::vector<std::string> commands;
|
||||
};
|
||||
std::weak_ptr<MultiCommandData> multiCommandData;
|
||||
|
||||
friend class NetLibrary;
|
||||
friend class NetClient;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -35,24 +35,13 @@ namespace NetworkingObjects {
|
|||
return;
|
||||
typeList.get_net_type_data(isServer, it->second.netTypeID).readUpdateFunc(NetObjTemporaryPtr<void>(this, id, it->second.p), a, clientReceivedFrom);
|
||||
}
|
||||
void NetObjManager::read_many_update_message(cereal::PortableBinaryInputArchive& a, const std::shared_ptr<NetServer::ClientData>& clientReceivedFrom) {
|
||||
for(;;) {
|
||||
bool objExists;
|
||||
a(objExists);
|
||||
if(!objExists)
|
||||
break;
|
||||
read_update_message(a, clientReceivedFrom);
|
||||
}
|
||||
}
|
||||
void NetObjManager::set_client(std::shared_ptr<NetClient> initClient, MessageCommandType initUpdateCommandID, MessageCommandType initMultiUpdateCommandID) {
|
||||
void NetObjManager::set_client(std::shared_ptr<NetClient> initClient, MessageCommandType initUpdateCommandID) {
|
||||
client = initClient;
|
||||
updateCommandID = initUpdateCommandID;
|
||||
multiUpdateCommandID = initMultiUpdateCommandID;
|
||||
}
|
||||
void NetObjManager::set_server(std::shared_ptr<NetServer> initServer, MessageCommandType initUpdateCommandID, MessageCommandType initMultiUpdateCommandID) {
|
||||
void NetObjManager::set_server(std::shared_ptr<NetServer> initServer, MessageCommandType initUpdateCommandID) {
|
||||
server = initServer;
|
||||
updateCommandID = initUpdateCommandID;
|
||||
multiUpdateCommandID = initMultiUpdateCommandID;
|
||||
}
|
||||
void NetObjManager::disconnect() {
|
||||
server = nullptr;
|
||||
|
|
@ -67,23 +56,6 @@ namespace NetworkingObjects {
|
|||
void NetObjManager::set_netobj_destroy_callback(const std::function<void(const NetworkingObjects::NetObjID& netID)>& newDestroyCallback) {
|
||||
destroyCallback = newDestroyCallback;
|
||||
}
|
||||
void NetObjManager::send_multi_update_messsage(std::function<void()> captureSendBlock, SendUpdateType updateType, const std::shared_ptr<NetServer::ClientData>& specificClient) {
|
||||
if(is_connected() && multiUpdateData.expired()) { // Check for multiUpdateData.expired() to make sure we aren't overriding a previous call to send_multi_update_messsage
|
||||
std::shared_ptr<MultiUpdateData> d = std::make_shared<MultiUpdateData>();
|
||||
d->ss = std::make_shared<std::stringstream>(std::ios::binary | std::ios::out);
|
||||
d->outArchive = std::make_unique<cereal::PortableBinaryOutputArchive>(*d->ss);
|
||||
(*d->outArchive)(multiUpdateCommandID);
|
||||
multiUpdateData = d; // Using weak pointer here ensures that object will be freed
|
||||
captureSendBlock();
|
||||
if(!d->channelToSendTo.empty()) {
|
||||
(*d->outArchive)(false);
|
||||
d->outArchive = nullptr; // Destroy output archive to finalize serialization
|
||||
send_update_data_by_type(d->channelToSendTo, d->ss, updateType, specificClient);
|
||||
}
|
||||
}
|
||||
else
|
||||
captureSendBlock();
|
||||
}
|
||||
|
||||
void NetObjManager::send_update_data_by_type(const std::string& channel, const std::shared_ptr<std::stringstream>& ss, SendUpdateType updateType, const std::shared_ptr<NetServer::ClientData>& specificClient) {
|
||||
if(client && updateType != SendUpdateType::SEND_TO_ALL)
|
||||
|
|
|
|||
|
|
@ -40,8 +40,8 @@ namespace NetworkingObjects {
|
|||
NetObjManager(bool initIsServer);
|
||||
void read_update_message(cereal::PortableBinaryInputArchive& a, const std::shared_ptr<NetServer::ClientData>& clientReceivedFrom);
|
||||
void read_many_update_message(cereal::PortableBinaryInputArchive& a, const std::shared_ptr<NetServer::ClientData>& clientReceivedFrom);
|
||||
void set_client(std::shared_ptr<NetClient> initClient, MessageCommandType initUpdateCommandID, MessageCommandType initMultiUpdateCommandID);
|
||||
void set_server(std::shared_ptr<NetServer> initServer, MessageCommandType initUpdateCommandID, MessageCommandType initMultiUpdateCommandID);
|
||||
void set_client(std::shared_ptr<NetClient> initClient, MessageCommandType initUpdateCommandID);
|
||||
void set_server(std::shared_ptr<NetServer> initServer, MessageCommandType initUpdateCommandID);
|
||||
void disconnect();
|
||||
bool is_server() const;
|
||||
bool is_connected() const;
|
||||
|
|
@ -71,7 +71,6 @@ namespace NetworkingObjects {
|
|||
SEND_TO_ALL_EXCEPT,
|
||||
SEND_TO_SPECIFIC_CLIENT
|
||||
};
|
||||
void send_multi_update_messsage(std::function<void()> captureSendBlock, SendUpdateType updateType, const std::shared_ptr<NetServer::ClientData>& specificClient);
|
||||
|
||||
// NOTE: DO NOT USE THESE FUNCTIONS UNLESS SITUATION ISN'T NORMAL, EVERY OBJECT SHOULD HAVE A UNIQUE ID AND IDS SHOULDNT BE REUSED UNDER ANY CIRCUMSTANCES
|
||||
template <typename T> NetObjOwnerPtr<T> make_obj_with_specific_id(const NetObjID& id) {
|
||||
|
|
@ -117,49 +116,40 @@ namespace NetworkingObjects {
|
|||
}
|
||||
|
||||
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) {
|
||||
auto ss = send_update_general_check_for_multi_update(channel, ptr, sendUpdateFunc);
|
||||
auto ss = send_update_general(channel, ptr, sendUpdateFunc);
|
||||
if(ss)
|
||||
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(clientToSendTo) {
|
||||
auto ss = send_update_general_check_for_multi_update(channel, ptr, sendUpdateFunc);
|
||||
auto ss = send_update_general(channel, ptr, sendUpdateFunc);
|
||||
if(ss)
|
||||
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) {
|
||||
auto ss = send_update_general_check_for_multi_update(channel, ptr, sendUpdateFunc);
|
||||
auto ss = send_update_general(channel, ptr, sendUpdateFunc);
|
||||
if(ss)
|
||||
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) {
|
||||
auto ss = send_update_general_check_for_multi_update(channel, ptr, sendUpdateFunc);
|
||||
auto ss = send_update_general(channel, ptr, sendUpdateFunc);
|
||||
if(ss)
|
||||
ptr.get_obj_man()->server->send_string_stream_to_all_clients(channel, ss);
|
||||
}
|
||||
|
||||
template <typename T> static std::shared_ptr<std::stringstream> send_update_general_check_for_multi_update(const std::string& channel, const NetObjTemporaryPtr<T>& ptr, std::function<void(const NetObjTemporaryPtr<T>&, cereal::PortableBinaryOutputArchive&)> sendUpdateFunc) {
|
||||
template <typename T> static std::shared_ptr<std::stringstream> send_update_general(const std::string& channel, const NetObjTemporaryPtr<T>& ptr, std::function<void(const NetObjTemporaryPtr<T>&, cereal::PortableBinaryOutputArchive&)> sendUpdateFunc) {
|
||||
if(ptr.get_obj_man()->is_connected()) {
|
||||
std::shared_ptr<MultiUpdateData> mData = ptr.get_obj_man()->multiUpdateData.lock();
|
||||
if(mData) {
|
||||
mData->channelToSendTo = channel;
|
||||
(*mData->outArchive)(true, ptr.get_net_id());
|
||||
sendUpdateFunc(ptr, *mData->outArchive);
|
||||
return nullptr;
|
||||
}
|
||||
else {
|
||||
auto ss(std::make_shared<std::stringstream>(std::ios::binary | std::ios::out));
|
||||
{
|
||||
cereal::PortableBinaryOutputArchive m(*ss);
|
||||
m(ptr.get_obj_man()->updateCommandID, ptr.get_net_id());
|
||||
sendUpdateFunc(ptr, m);
|
||||
}
|
||||
return ss;
|
||||
auto ss(std::make_shared<std::stringstream>(std::ios::binary | std::ios::out));
|
||||
{
|
||||
cereal::PortableBinaryOutputArchive m(*ss);
|
||||
m(ptr.get_obj_man()->updateCommandID, ptr.get_net_id());
|
||||
sendUpdateFunc(ptr, m);
|
||||
}
|
||||
return ss;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
|
@ -178,18 +168,10 @@ namespace NetworkingObjects {
|
|||
void* p;
|
||||
};
|
||||
|
||||
struct MultiUpdateData {
|
||||
std::string channelToSendTo;
|
||||
std::shared_ptr<std::stringstream> ss;
|
||||
std::unique_ptr<cereal::PortableBinaryOutputArchive> outArchive;
|
||||
};
|
||||
std::weak_ptr<MultiUpdateData> multiUpdateData;
|
||||
|
||||
bool isServer;
|
||||
std::shared_ptr<NetClient> client;
|
||||
std::shared_ptr<NetServer> server;
|
||||
MessageCommandType updateCommandID;
|
||||
MessageCommandType multiUpdateCommandID;
|
||||
std::unordered_map<NetObjID, SingleObjectData> objectData;
|
||||
NetObjManagerTypeList typeList;
|
||||
NetTypeIDType nextTypeID;
|
||||
|
|
|
|||
|
|
@ -22,10 +22,10 @@
|
|||
|
||||
enum ServerCommands : MessageCommandType {
|
||||
SERVER_FRAGMENT = 0,
|
||||
SERVER_MULTI_COMMAND = 1,
|
||||
SERVER_KEEP_ALIVE,
|
||||
SERVER_INITIAL_DATA,
|
||||
SERVER_UPDATE_NETWORK_OBJECT,
|
||||
SERVER_UPDATE_MANY_NETWORK_OBJECTS,
|
||||
SERVER_NEW_RESOURCE_ID,
|
||||
SERVER_NEW_RESOURCE_DATA,
|
||||
SERVER_TRANSFORM_MANY_COMPONENTS
|
||||
|
|
@ -33,10 +33,10 @@ enum ServerCommands : MessageCommandType {
|
|||
|
||||
enum ClientCommands : MessageCommandType {
|
||||
CLIENT_FRAGMENT = 0,
|
||||
CLIENT_MULTI_COMMAND = 1,
|
||||
CLIENT_KEEP_ALIVE,
|
||||
CLIENT_INITIAL_DATA,
|
||||
CLIENT_UPDATE_NETWORK_OBJECT,
|
||||
CLIENT_UPDATE_MANY_NETWORK_OBJECTS,
|
||||
CLIENT_NEW_RESOURCE_ID,
|
||||
CLIENT_NEW_RESOURCE_DATA,
|
||||
CLIENT_TRANSFORM_MANY_COMPONENTS
|
||||
|
|
|
|||
|
|
@ -127,7 +127,7 @@ void DrawingProgramLayerManager::push_components_to(const std::vector<CanvasComp
|
|||
|
||||
auto& undoMan = drawP.world.undo;
|
||||
|
||||
drawP.world.netObjMan.send_multi_update_messsage([&]() {
|
||||
drawP.world.send_reliable_multi_command_to_all([&]() {
|
||||
std::unordered_map<DrawingProgramLayerListItem*, std::vector<CanvasComponentContainer::ObjInfo*>> toEraseMap;
|
||||
std::vector<NetObjOwnerPtr<DrawingProgramLayerListItem>> toInsertObjPtrs;
|
||||
|
||||
|
|
@ -168,7 +168,7 @@ void DrawingProgramLayerManager::push_components_to(const std::vector<CanvasComp
|
|||
toEraseList.emplace_back(obj->obj->objInfo);
|
||||
}
|
||||
commitMoveOnLayer();
|
||||
}, NetObjManager::SendUpdateType::SEND_TO_ALL, nullptr);
|
||||
});
|
||||
|
||||
class MoveComponentsUndoAction : public WorldUndoAction {
|
||||
public:
|
||||
|
|
@ -376,12 +376,12 @@ void DrawingProgramLayerManager::add_undo_place_component(CanvasComponentContain
|
|||
|
||||
void DrawingProgramLayerManager::erase_component_map(const std::unordered_map<DrawingProgramLayerListItem*, std::vector<CanvasComponentContainer::ObjInfoIterator>>& eraseMap, bool newUndo) {
|
||||
add_undo_erase_components(eraseMap, newUndo);
|
||||
drawP.world.netObjMan.send_multi_update_messsage([&]() {
|
||||
drawP.world.send_reliable_multi_command_to_all([&]() {
|
||||
for(auto& [layerListItem, netObjSetToErase] : eraseMap) {
|
||||
auto& layerComponentList = layerListItem->get_layer().components;
|
||||
layerComponentList->erase_list(layerComponentList, netObjSetToErase);
|
||||
}
|
||||
}, NetworkingObjects::NetObjManager::SendUpdateType::SEND_TO_ALL, nullptr);
|
||||
});
|
||||
}
|
||||
|
||||
void DrawingProgramLayerManager::add_undo_erase_components(const std::unordered_map<DrawingProgramLayerListItem*, std::vector<CanvasComponentContainer::ObjInfoIterator>>& eraseMap, bool newUndo) {
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
#include "../../MainProgram.hpp"
|
||||
#include "DrawingProgramToolBase.hpp"
|
||||
#include "../../CanvasComponents/MeshCanvasComponent.hpp"
|
||||
#include "Helpers/Networking/NetLibrary.hpp"
|
||||
#include "Helpers/NetworkingObjects/NetObjTemporaryPtr.decl.hpp"
|
||||
#include "../../CanvasComponents/CanvasComponentContainer.hpp"
|
||||
#include "../../GUIStuff/ElementHelpers/TextLabelHelpers.hpp"
|
||||
|
|
@ -85,10 +86,10 @@ void BrushTool::commit_data(bool final) {
|
|||
}
|
||||
containerPtr->commit_update(drawP);
|
||||
if(final) {
|
||||
drawP.world.netObjMan.send_multi_update_messsage([&]() {
|
||||
drawP.world.send_reliable_multi_command_to_all([&]() {
|
||||
drawP.send_transforms_for({objInfoBeingEdited});
|
||||
containerPtr->send_comp_update(drawP, final);
|
||||
}, NetworkingObjects::NetObjManager::SendUpdateType::SEND_TO_ALL, nullptr);
|
||||
containerPtr->send_comp_update(drawP, true);
|
||||
});
|
||||
}
|
||||
else
|
||||
containerPtr->send_comp_update(drawP, final);
|
||||
|
|
|
|||
|
|
@ -242,7 +242,7 @@ void EraserTool::commit_erase() {
|
|||
return false;
|
||||
});
|
||||
|
||||
drawP.world.netObjMan.send_multi_update_messsage([&]() {
|
||||
drawP.world.send_reliable_multi_command_to_all([&]() {
|
||||
bool firstPlacement = true;
|
||||
for(auto& [layer, compMap] : newObjectsToPlace) {
|
||||
layer->get_layer().components->sort_netobj_ordered_list_iterator_insert_list(layer->get_layer().components, compMap);
|
||||
|
|
@ -269,7 +269,7 @@ void EraserTool::commit_erase() {
|
|||
else
|
||||
drawP.world.undo.push_on_last(std::make_unique<EditTransformCanvasComponentWorldUndoAction>(std::move(oldData.copyData->obj), oldData.copyData->coords, drawP.world.undo.get_undoid_from_netid(comp->obj.get_net_id())));
|
||||
}
|
||||
}, NetworkingObjects::NetObjManager::SendUpdateType::SEND_TO_ALL, nullptr);
|
||||
});
|
||||
erasedComponents.clear();
|
||||
updatedComponents.clear();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,10 +59,10 @@ void LineDrawTool::commit_data(bool final) {
|
|||
}
|
||||
containerPtr->commit_update(drawP);
|
||||
if(final) {
|
||||
drawP.world.netObjMan.send_multi_update_messsage([&]() {
|
||||
drawP.world.send_reliable_multi_command_to_all([&]() {
|
||||
drawP.send_transforms_for({objInfoBeingEdited});
|
||||
containerPtr->send_comp_update(drawP, final);
|
||||
}, NetworkingObjects::NetObjManager::SendUpdateType::SEND_TO_ALL, nullptr);
|
||||
});
|
||||
}
|
||||
else
|
||||
containerPtr->send_comp_update(drawP, final);
|
||||
|
|
|
|||
|
|
@ -149,7 +149,7 @@ void World::init_client(const std::string& serverFullID) {
|
|||
netClient = std::make_shared<NetClient>(serverFullID);
|
||||
lastKeepAliveSent = std::chrono::steady_clock::now();
|
||||
NetLibrary::register_client(netClient);
|
||||
netObjMan.set_client(netClient, SERVER_UPDATE_NETWORK_OBJECT, SERVER_UPDATE_MANY_NETWORK_OBJECTS);
|
||||
netObjMan.set_client(netClient, SERVER_UPDATE_NETWORK_OBJECT);
|
||||
set_name("");
|
||||
|
||||
rMan.init_client_callbacks();
|
||||
|
|
@ -179,15 +179,21 @@ void World::init_client(const std::string& serverFullID) {
|
|||
netClient->add_recv_callback(CLIENT_UPDATE_NETWORK_OBJECT, [&](cereal::PortableBinaryInputArchive& message) {
|
||||
netObjMan.read_update_message(message, nullptr);
|
||||
});
|
||||
netClient->add_recv_callback(CLIENT_UPDATE_MANY_NETWORK_OBJECTS, [&](cereal::PortableBinaryInputArchive& message) {
|
||||
netObjMan.read_many_update_message(message, nullptr);
|
||||
});
|
||||
netClient->add_recv_callback(CLIENT_KEEP_ALIVE, [&](cereal::PortableBinaryInputArchive& message) {
|
||||
});
|
||||
|
||||
netClient->send_items_to_server(RELIABLE_COMMAND_CHANNEL, SERVER_INITIAL_DATA, main.conf.displayName);
|
||||
}
|
||||
|
||||
void World::send_reliable_multi_command_to_all(const std::function<void()>& captureSendBlock) {
|
||||
if(netServer)
|
||||
netServer->send_multi_command_to_all_clients(RELIABLE_COMMAND_CHANNEL, captureSendBlock);
|
||||
else if(netClient)
|
||||
netClient->send_multi_command_to_server(RELIABLE_COMMAND_CHANNEL, captureSendBlock);
|
||||
else
|
||||
captureSendBlock();
|
||||
}
|
||||
|
||||
void World::focus_update() {
|
||||
if(!clientStillConnecting) {
|
||||
delayedUpdateObjectManager.update(netObjMan);
|
||||
|
|
@ -417,7 +423,7 @@ void World::start_hosting(const std::string& initNetSource, const std::string& s
|
|||
netServer = std::make_shared<NetServer>(serverLocalID);
|
||||
lastKeepAliveSent = std::chrono::steady_clock::now();
|
||||
NetLibrary::register_server(netServer);
|
||||
netObjMan.set_server(netServer, CLIENT_UPDATE_NETWORK_OBJECT, CLIENT_UPDATE_MANY_NETWORK_OBJECTS);
|
||||
netObjMan.set_server(netServer, CLIENT_UPDATE_NETWORK_OBJECT);
|
||||
netSource = initNetSource;
|
||||
rMan.init_server_callbacks();
|
||||
drawProg.init_server_callbacks();
|
||||
|
|
@ -455,9 +461,6 @@ void World::start_hosting(const std::string& initNetSource, const std::string& s
|
|||
netServer->add_recv_callback(SERVER_UPDATE_NETWORK_OBJECT, [&](std::shared_ptr<NetServer::ClientData> client, cereal::PortableBinaryInputArchive& message) {
|
||||
netObjMan.read_update_message(message, client);
|
||||
});
|
||||
netServer->add_recv_callback(SERVER_UPDATE_MANY_NETWORK_OBJECTS, [&](std::shared_ptr<NetServer::ClientData> client, cereal::PortableBinaryInputArchive& message) {
|
||||
netObjMan.read_many_update_message(message, client);
|
||||
});
|
||||
netServer->add_recv_callback(SERVER_KEEP_ALIVE, [&](std::shared_ptr<NetServer::ClientData> client, cereal::PortableBinaryInputArchive& message) {
|
||||
});
|
||||
netServer->add_disconnect_callback([&](std::shared_ptr<NetServer::ClientData> client) {
|
||||
|
|
|
|||
|
|
@ -106,6 +106,7 @@ class World {
|
|||
void set_has_unsaved_local_changes(bool newHasUnsavedLocalChangesVal);
|
||||
bool is_focus();
|
||||
void set_to_layout_gui_if_focus();
|
||||
void send_reliable_multi_command_to_all(const std::function<void()>& captureSendBlock);
|
||||
|
||||
NetworkingObjects::DelayUpdateSerializedClassManager delayedUpdateObjectManager;
|
||||
|
||||
|
|
|
|||
|
|
@ -76,14 +76,14 @@ void WorldUndoManager::undo() {
|
|||
|
||||
bool undoFail = false;
|
||||
|
||||
world.netObjMan.send_multi_update_messsage([&]() {
|
||||
world.send_reliable_multi_command_to_all([&]() {
|
||||
for(auto& u : std::views::reverse(undoQueue.back())) {
|
||||
if(!u->undo(*this)) {
|
||||
undoFail = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}, NetworkingObjects::NetObjManager::SendUpdateType::SEND_TO_ALL, nullptr);
|
||||
});
|
||||
|
||||
if(undoFail) {
|
||||
clear();
|
||||
|
|
@ -106,14 +106,14 @@ void WorldUndoManager::redo() {
|
|||
world.bMan.refresh_gui_data();
|
||||
|
||||
bool redoFail = false;
|
||||
world.netObjMan.send_multi_update_messsage([&]() {
|
||||
world.send_reliable_multi_command_to_all([&]() {
|
||||
for(auto& u : redoQueue.back()) {
|
||||
if(!u->redo(*this)) {
|
||||
redoFail = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}, NetworkingObjects::NetObjManager::SendUpdateType::SEND_TO_ALL, nullptr);
|
||||
});
|
||||
|
||||
if(redoFail) {
|
||||
clear();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue