Browse Source

Refactor timed message handling

pull/2421/head
Vladimir Olteanu 5 years ago committed by Anders Jenbo
parent
commit
f8d98560ae
  1. 9
      Source/multi.cpp
  2. 64
      Source/tmsg.cpp
  3. 20
      Source/tmsg.h

9
Source/multi.cpp

@ -303,12 +303,11 @@ void HandleAllPackets(int pnum, byte *pData, size_t nSize)
void ProcessTmsgs() void ProcessTmsgs()
{ {
size_t cnt; uint8_t cnt;
TPkt pkt; std::unique_ptr<byte[]> msg;
while ((cnt = tmsg_get((byte *)&pkt)) != 0) { while ((cnt = tmsg_get(&msg)) != 0)
HandleAllPackets(MyPlayerId, (byte *)&pkt, cnt); HandleAllPackets(MyPlayerId, msg.get(), cnt);
}
} }
void SendPlayerInfo(int pnum, _cmd_id cmd) void SendPlayerInfo(int pnum, _cmd_id cmd)

64
Source/tmsg.cpp

@ -3,67 +3,61 @@
* *
* Implementation of functionality transmitting chat messages. * Implementation of functionality transmitting chat messages.
*/ */
#include <list>
#include "tmsg.h" #include "tmsg.h"
#include "diablo.h" #include "diablo.h"
namespace devilution { namespace devilution {
namespace { namespace {
TMsg *sgpTimedMsgHead; struct TMsg {
uint32_t time;
std::unique_ptr<byte[]> body;
uint8_t len;
TMsg(uint32_t time, byte *data, uint8_t len)
: time(time)
, body(new byte[len])
, len(len)
{
memcpy(body.get(), data, len);
}
};
std::list<TMsg> TimedMsgList;
} // namespace } // namespace
size_t tmsg_get(byte *pbMsg) uint8_t tmsg_get(std::unique_ptr<byte[]> *msg)
{ {
TMsg *head; if (TimedMsgList.empty())
if (sgpTimedMsgHead == nullptr)
return 0; return 0;
if ((int)(sgpTimedMsgHead->hdr.dwTime - SDL_GetTicks()) >= 0) TMsg &head = TimedMsgList.front();
if ((int)(head.time - SDL_GetTicks()) >= 0)
return 0; return 0;
head = sgpTimedMsgHead;
sgpTimedMsgHead = head->hdr.pNext; uint8_t len = head.len;
size_t len = head->hdr.bLen; *msg = std::move(head.body);
// BUGFIX: ignores dwMaxLen TimedMsgList.pop_front();
memcpy(pbMsg, head->body, len);
std::free(head);
return len; return len;
} }
void tmsg_add(byte *pbMsg, uint8_t bLen) void tmsg_add(byte *msg, uint8_t len)
{ {
TMsg **tail; uint32_t time = SDL_GetTicks() + gnTickDelay * 10;
TimedMsgList.emplace_back(time, msg, len);
TMsg *msg = static_cast<TMsg *>(std::malloc(bLen + sizeof(*msg)));
if (msg == nullptr)
app_fatal("Failed to allocate memory");
msg->hdr.pNext = nullptr;
msg->hdr.dwTime = SDL_GetTicks() + gnTickDelay * 10;
msg->hdr.bLen = bLen;
memcpy(msg->body, pbMsg, bLen);
for (tail = &sgpTimedMsgHead; *tail != nullptr; tail = &(*tail)->hdr.pNext) {
;
}
*tail = msg;
} }
void tmsg_start() void tmsg_start()
{ {
assert(!sgpTimedMsgHead); assert(TimedMsgList.empty());
} }
void tmsg_cleanup() void tmsg_cleanup()
{ {
TMsg *next; TimedMsgList.clear();
while (sgpTimedMsgHead != nullptr) {
next = sgpTimedMsgHead->hdr.pNext;
std::free(sgpTimedMsgHead);
sgpTimedMsgHead = next;
}
} }
} // namespace devilution } // namespace devilution

20
Source/tmsg.h

@ -6,28 +6,14 @@
#pragma once #pragma once
#include <cstdint> #include <cstdint>
#include <memory>
#include "utils/stdcompat/cstddef.hpp" #include "utils/stdcompat/cstddef.hpp"
namespace devilution { namespace devilution {
#pragma pack(push, 1) uint8_t tmsg_get(std::unique_ptr<byte[]> *msg);
struct TMsgHdr { void tmsg_add(byte *msg, uint8_t bLen);
struct TMsg *pNext;
int32_t dwTime;
uint8_t bLen;
};
struct TMsg {
TMsgHdr hdr;
// this is actually alignment padding, but the message body is appended to the struct
// so it's convenient to use byte-alignment and name it "body"
byte body[3];
};
#pragma pack(pop)
size_t tmsg_get(byte *pbMsg);
void tmsg_add(byte *pbMsg, uint8_t bLen);
void tmsg_start(); void tmsg_start();
void tmsg_cleanup(); void tmsg_cleanup();

Loading…
Cancel
Save