1
0
Fork 0

Codechange: replace custom deque with actual deque when loading network games

pull/13341/head
Rubidium 2025-01-14 22:35:13 +01:00 committed by rubidium42
parent 4b2051a1c1
commit 51529b83b1
1 changed files with 14 additions and 48 deletions

View File

@ -41,27 +41,17 @@
/** Read some packets, and when do use that data as initial load filter. */ /** Read some packets, and when do use that data as initial load filter. */
struct PacketReader : LoadFilter { struct PacketReader : LoadFilter {
static const size_t CHUNK = 32 * 1024; ///< 32 KiB chunks of memory. using Buffer = std::deque<uint8_t>; ///< The underlying buffer type that's being use.
std::vector<uint8_t *> blocks; ///< Buffer with blocks of allocated memory. Buffer buffer; ///< Buffer with the raw save game data.
uint8_t *buf; ///< Buffer we're going to write to/read from. Buffer::const_iterator iterator; ///< Buffer we're going to write to/read from.
uint8_t *bufe; ///< End of the buffer we write to/read from. size_t read_bytes = 0; ///< The total number of read bytes.
uint8_t **block; ///< The block we're reading from/writing to.
size_t written_bytes; ///< The total number of bytes we've written.
size_t read_bytes; ///< The total number of read bytes.
/** Initialise everything. */ /** Initialise everything. */
PacketReader() : LoadFilter(nullptr), buf(nullptr), bufe(nullptr), block(nullptr), written_bytes(0), read_bytes(0) PacketReader() : LoadFilter(nullptr)
{ {
} }
~PacketReader() override
{
for (auto p : this->blocks) {
free(p);
}
}
/** /**
* Simple wrapper around fwrite to be able to pass it to Packet's TransferOut. * Simple wrapper around fwrite to be able to pass it to Packet's TransferOut.
* @param destination The reader to add the data to. * @param destination The reader to add the data to.
@ -71,9 +61,7 @@ struct PacketReader : LoadFilter {
*/ */
static inline ssize_t TransferOutMemCopy(PacketReader *destination, const char *source, size_t amount) static inline ssize_t TransferOutMemCopy(PacketReader *destination, const char *source, size_t amount)
{ {
memcpy(destination->buf, source, amount); std::copy_n(source, amount, std::back_inserter(destination->buffer));
destination->buf += amount;
destination->written_bytes += amount;
return amount; return amount;
} }
@ -84,47 +72,25 @@ struct PacketReader : LoadFilter {
void AddPacket(Packet &p) void AddPacket(Packet &p)
{ {
assert(this->read_bytes == 0); assert(this->read_bytes == 0);
p.TransferOutWithLimit(TransferOutMemCopy, this->bufe - this->buf, this); p.TransferOut(TransferOutMemCopy, this);
/* Did everything fit in the current chunk, then we're done. */
if (p.RemainingBytesToTransfer() == 0) return;
/* Allocate a new chunk and add the remaining data. */
this->blocks.push_back(this->buf = CallocT<uint8_t>(CHUNK));
this->bufe = this->buf + CHUNK;
p.TransferOutWithLimit(TransferOutMemCopy, this->bufe - this->buf, this);
} }
size_t Read(uint8_t *rbuf, size_t size) override size_t Read(uint8_t *rbuf, size_t size) override
{ {
/* Limit the amount to read to whatever we still have. */ /* Limit the amount to read to whatever we still have. */
size_t ret_size = size = std::min(this->written_bytes - this->read_bytes, size); size_t read_size = std::min(this->buffer.size() - this->read_bytes, size);
this->read_bytes += ret_size;
const uint8_t *rbufe = rbuf + ret_size;
while (rbuf != rbufe) { std::copy_n(this->iterator, read_size, rbuf);
if (this->buf == this->bufe) { std::advance(this->iterator, read_size);
this->buf = *this->block++; this->read_bytes += read_size;
this->bufe = this->buf + CHUNK;
}
size_t to_write = std::min(this->bufe - this->buf, rbufe - rbuf); return read_size;
memcpy(rbuf, this->buf, to_write);
rbuf += to_write;
this->buf += to_write;
}
return ret_size;
} }
void Reset() override void Reset() override
{ {
this->read_bytes = 0; this->read_bytes = 0;
this->iterator = this->buffer.cbegin();
this->block = this->blocks.data();
this->buf = *this->block++;
this->bufe = this->buf + CHUNK;
} }
}; };
@ -833,7 +799,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_MAP_DATA(Packet
/* We are still receiving data, put it to the file */ /* We are still receiving data, put it to the file */
this->savegame->AddPacket(p); this->savegame->AddPacket(p);
_network_join_bytes = (uint32_t)this->savegame->written_bytes; _network_join_bytes = static_cast<uint32_t>(this->savegame->buffer.size());
SetWindowDirty(WC_NETWORK_STATUS_WINDOW, WN_NETWORK_STATUS_WINDOW_JOIN); SetWindowDirty(WC_NETWORK_STATUS_WINDOW, WN_NETWORK_STATUS_WINDOW_JOIN);
return NETWORK_RECV_STATUS_OKAY; return NETWORK_RECV_STATUS_OKAY;