mirror of
https://gitea.wildfiregames.com/0ad/0ad
synced 2026-06-16 05:13:58 -07:00
Do the gamestate compression in the task-manager
Some checks failed
checkrefs / lfscheck (push) Has been cancelled
checkrefs / checkrefs (push) Has been cancelled
lint / cppcheck (push) Has been cancelled
lint / copyright (push) Has been cancelled
lint / jenkinsfiles (push) Has been cancelled
pre-commit / build (push) Has been cancelled
Some checks failed
checkrefs / lfscheck (push) Has been cancelled
checkrefs / checkrefs (push) Has been cancelled
lint / cppcheck (push) Has been cancelled
lint / copyright (push) Has been cancelled
lint / jenkinsfiles (push) Has been cancelled
pre-commit / build (push) Has been cancelled
This reduces the stutter when a client joins. The decompression isn't put on the task manager. As the client would have to wait for that either way. Also a new polling loop would have to be introduced. The compression code is moved to the file transferer so all data send through it gits compressed. Refs: #4210
This commit is contained in:
parent
6a3da535f3
commit
6893654cfc
4 changed files with 44 additions and 27 deletions
|
|
@ -34,7 +34,6 @@
|
|||
#include "network/StunClient.h"
|
||||
#include "ps/CLogger.h"
|
||||
#include "ps/CStr.h"
|
||||
#include "ps/Compress.h"
|
||||
#include "ps/Game.h"
|
||||
#include "ps/Hashing.h"
|
||||
#include "ps/Profile.h"
|
||||
|
|
@ -581,7 +580,7 @@ bool CNetClient::HandleMessage(CNetMessage* message)
|
|||
{
|
||||
CFileTransferRequestMessage* reqMessage = static_cast<CFileTransferRequestMessage*>(message);
|
||||
|
||||
std::string uncompressedGameState{[&]
|
||||
std::string gameState{[&]
|
||||
{
|
||||
if (static_cast<CNetFileTransferer::RequestType>(reqMessage->m_RequestType) ==
|
||||
CNetFileTransferer::RequestType::LOADGAME)
|
||||
|
|
@ -600,13 +599,8 @@ bool CNetClient::HandleMessage(CNetMessage* message)
|
|||
return stream.str();
|
||||
}()};
|
||||
|
||||
// Compress the content with zlib to save bandwidth
|
||||
// (TODO: if this is still too large, compressing with e.g. LZMA works much better)
|
||||
std::string compressedGameState;
|
||||
CompressZLib(std::move(uncompressedGameState), compressedGameState, true);
|
||||
|
||||
m_Session->GetFileTransferer().StartResponse(reqMessage->m_RequestID,
|
||||
std::move(compressedGameState));
|
||||
std::move(gameState));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -625,10 +619,7 @@ void CNetClient::LoadFinished()
|
|||
// We're rejoining a game, and just finished loading the initial map,
|
||||
// so deserialize the saved game state now
|
||||
|
||||
std::string state;
|
||||
DecompressZLib(m_JoinSyncBuffer, state, true);
|
||||
|
||||
std::stringstream stream(state);
|
||||
std::stringstream stream(m_JoinSyncBuffer);
|
||||
|
||||
u32 turn;
|
||||
stream.read((char*)&turn, sizeof(turn));
|
||||
|
|
@ -857,10 +848,7 @@ bool CNetClient::OnSavedGameStart(CNetClient* client, CFsmEvent<CNetMessage*>* e
|
|||
client->m_Session->GetFileTransferer().StartTask(CNetFileTransferer::RequestType::LOADGAME,
|
||||
[client, initAttribs](std::string buffer)
|
||||
{
|
||||
std::string state;
|
||||
DecompressZLib(buffer, state, true);
|
||||
|
||||
client->StartGame(&*initAttribs, state);
|
||||
client->StartGame(&*initAttribs, std::move(buffer));
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@
|
|||
#include "network/NetMessage.h"
|
||||
#include "ps/CLogger.h"
|
||||
#include "ps/CStr.h"
|
||||
#include "ps/Compress.h"
|
||||
#include "ps/TaskManager.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
|
|
@ -102,7 +104,9 @@ Status CNetFileTransferer::OnFileTransferData(const CFileTransferDataMessage& me
|
|||
{
|
||||
LOGMESSAGERENDER("Download completed");
|
||||
|
||||
task.onComplete(std::move(task.buffer));
|
||||
std::string uncompressed;
|
||||
DecompressZLib(task.buffer, uncompressed, true);
|
||||
task.onComplete(std::move(uncompressed));
|
||||
m_FileReceiveTasks.erase(it);
|
||||
return INFO::OK;
|
||||
}
|
||||
|
|
@ -161,16 +165,18 @@ void CNetFileTransferer::StartResponse(u32 requestID, const std::string& data)
|
|||
{
|
||||
CNetFileSendTask task;
|
||||
task.requestID = requestID;
|
||||
task.buffer = data;
|
||||
task.offset = 0;
|
||||
task.packetsInFlight = 0;
|
||||
task.maxWindowSize = DEFAULT_FILE_TRANSFER_WINDOW_SIZE;
|
||||
task.task = {g_TaskManager, [data]
|
||||
{
|
||||
// Compress the content with zlib to save bandwidth
|
||||
std::string compressedGameState;
|
||||
CompressZLib(std::move(data), compressedGameState, true);
|
||||
return compressedGameState;
|
||||
}, Threading::TaskPriority::LOW};
|
||||
|
||||
m_FileSendTasks[task.requestID] = task;
|
||||
CFileTransferResponseMessage respMessage;
|
||||
respMessage.m_RequestID = requestID;
|
||||
respMessage.m_Length = task.buffer.size();
|
||||
m_SendMessage(&respMessage);
|
||||
m_FileSendTasks.insert({task.requestID, std::move(task)});
|
||||
}
|
||||
|
||||
void CNetFileTransferer::Poll()
|
||||
|
|
@ -181,6 +187,19 @@ void CNetFileTransferer::Poll()
|
|||
{
|
||||
CNetFileSendTask& task = p.second;
|
||||
|
||||
if (task.task.Valid())
|
||||
{
|
||||
if (!task.task.IsDone())
|
||||
continue;
|
||||
|
||||
task.buffer = std::exchange(task.task, {}).Get();
|
||||
|
||||
CFileTransferResponseMessage respMessage;
|
||||
respMessage.m_RequestID = task.requestID;
|
||||
respMessage.m_Length = task.buffer.size();
|
||||
m_SendMessage(&respMessage);
|
||||
}
|
||||
|
||||
while (task.packetsInFlight < task.maxWindowSize && task.offset < task.buffer.size())
|
||||
{
|
||||
CFileTransferDataMessage dataMessage;
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#include "lib/alignment.h"
|
||||
#include "lib/status.h"
|
||||
#include "lib/types.h"
|
||||
#include "ps/Future.h"
|
||||
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
|
|
@ -105,6 +106,7 @@ private:
|
|||
size_t offset;
|
||||
size_t maxWindowSize;
|
||||
size_t packetsInFlight;
|
||||
Future<std::string> task;
|
||||
};
|
||||
|
||||
std::function<bool(const CNetMessage* message)> m_SendMessage;
|
||||
|
|
|
|||
|
|
@ -20,13 +20,17 @@
|
|||
#include "network/NetFileTransfer.h"
|
||||
#include "network/NetMessage.h"
|
||||
|
||||
#include <chrono>
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
#include <initializer_list>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
using namespace std::literals;
|
||||
|
||||
namespace
|
||||
{
|
||||
constexpr const char* MESSAGECONTENT{"Some example message content"};
|
||||
|
|
@ -102,14 +106,18 @@ public:
|
|||
CheckSizes(client.queues, 1, 0, 0, 0);
|
||||
|
||||
server.transferer.StartResponse(client.queues.requests.at(0).m_RequestID, MESSAGECONTENT);
|
||||
CheckSizes(server.queues, 0, 1, 0, 0);
|
||||
CheckSizes(server.queues, 0, 0, 0, 0);
|
||||
|
||||
while (server.queues.responses.size() == 0)
|
||||
{
|
||||
std::this_thread::sleep_for(10ms);
|
||||
server.transferer.Poll();
|
||||
}
|
||||
CheckSizes(server.queues, 0, 1, 1, 0);
|
||||
|
||||
client.transferer.HandleMessageReceive(server.queues.responses.at(0));
|
||||
CheckSizes(client.queues, 1, 0, 0, 0);
|
||||
|
||||
server.transferer.Poll();
|
||||
CheckSizes(server.queues, 0, 1, 1, 0);
|
||||
|
||||
server.transferer.Poll();
|
||||
// If `MESSAGECONTENT` would be longer another message would be sent.
|
||||
CheckSizes(server.queues, 0, 1, 1, 0);
|
||||
|
|
|
|||
Loading…
Reference in a new issue