Just use stack allocations in parsing by default.
This commit is contained in:
parent
63058ddf23
commit
38c0599380
4 changed files with 59 additions and 30 deletions
|
@ -82,18 +82,40 @@ extern "C" void Discord_UpdateConnection()
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// reads
|
// reads
|
||||||
JsonDocument message;
|
|
||||||
while (Connection->Read(message)) {
|
// json parser will use this buffer first, then allocate more if needed; I seriously doubt we send any messages that would use all of this, though.
|
||||||
|
char parseBuffer[32 * 1024];
|
||||||
|
for (;;) {
|
||||||
|
PoolAllocator pa(parseBuffer, sizeof(parseBuffer));
|
||||||
|
StackAllocator sa;
|
||||||
|
JsonDocument message(rapidjson::kObjectType, &pa, sizeof(sa.fixedBuffer_), &sa);
|
||||||
|
|
||||||
|
if (!Connection->Read(message)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* evtName = nullptr;
|
||||||
|
auto evt = message.FindMember("evt");
|
||||||
|
if (evt != message.MemberEnd() && evt->value.IsString()) {
|
||||||
|
evtName = evt->value.GetString();
|
||||||
|
}
|
||||||
|
|
||||||
auto nonce = message.FindMember("nonce");
|
auto nonce = message.FindMember("nonce");
|
||||||
if (nonce != message.MemberEnd() && nonce->value.IsString()) {
|
if (nonce != message.MemberEnd() && nonce->value.IsString()) {
|
||||||
// in responses only -- should use to match up response when needed.
|
// in responses only -- should use to match up response when needed.
|
||||||
//auto cmd = message.FindMember("cmd"); needed?
|
|
||||||
|
if (evtName && strcmp(evtName, "ERROR") == 0) {
|
||||||
|
auto data = message.FindMember("data");
|
||||||
|
LastErrorCode = data->value["code"].GetInt();
|
||||||
|
StringCopy(LastErrorMessage, data->value["message"].GetString());
|
||||||
|
GotErrorMessage.store(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// should have evt == name of event, optional data
|
// should have evt == name of event, optional data
|
||||||
auto evt = message.FindMember("evt");
|
if (evtName == nullptr) {
|
||||||
if (evt != message.MemberEnd() && evt->value.IsString()) {
|
continue;
|
||||||
const char* evtName = evt->value.GetString();
|
}
|
||||||
|
|
||||||
// todo ug
|
// todo ug
|
||||||
if (strcmp(evtName, "PRESENCE_REQUESTED") == 0) {
|
if (strcmp(evtName, "PRESENCE_REQUESTED") == 0) {
|
||||||
|
@ -113,7 +135,6 @@ extern "C" void Discord_UpdateConnection()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// writes
|
// writes
|
||||||
while (SendQueuePendingSends.load()) {
|
while (SendQueuePendingSends.load()) {
|
||||||
|
|
|
@ -34,7 +34,10 @@ void RpcConnection::Open()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state == State::SentHandshake) {
|
if (state == State::SentHandshake) {
|
||||||
JsonDocument message;
|
char parseBuffer[32 * 1024];
|
||||||
|
PoolAllocator pa(parseBuffer, sizeof(parseBuffer));
|
||||||
|
StackAllocator sa;
|
||||||
|
JsonDocument message(rapidjson::kObjectType, &pa, sizeof(sa.fixedBuffer_), &sa);
|
||||||
if (Read(message)) {
|
if (Read(message)) {
|
||||||
auto cmd = message.FindMember("cmd");
|
auto cmd = message.FindMember("cmd");
|
||||||
if (cmd == message.MemberEnd() || !cmd->value.IsString()) {
|
if (cmd == message.MemberEnd() || !cmd->value.IsString()) {
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
#include "connection.h"
|
#include "connection.h"
|
||||||
#include "discord-rpc.h"
|
#include "discord-rpc.h"
|
||||||
|
|
||||||
|
MallocAllocator MallocAllocatorInst;
|
||||||
|
|
||||||
// it's ever so slightly faster to not have to strlen the key
|
// it's ever so slightly faster to not have to strlen the key
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void WriteKey(JsonWriter& w, T& k) {
|
void WriteKey(JsonWriter& w, T& k) {
|
||||||
|
@ -46,7 +48,7 @@ void JsonWriteCommandEnd(JsonWriter& writer)
|
||||||
size_t JsonWriteRichPresenceObj(char* dest, size_t maxLen, int nonce, int pid, const DiscordRichPresence* presence)
|
size_t JsonWriteRichPresenceObj(char* dest, size_t maxLen, int nonce, int pid, const DiscordRichPresence* presence)
|
||||||
{
|
{
|
||||||
DirectStringBuffer sb(dest, maxLen);
|
DirectStringBuffer sb(dest, maxLen);
|
||||||
WriterAllocator wa;
|
StackAllocator wa;
|
||||||
JsonWriter writer(sb, &wa, WriterNestingLevels);
|
JsonWriter writer(sb, &wa, WriterNestingLevels);
|
||||||
|
|
||||||
JsonWriteCommandStart(writer, nonce, "SET_ACTIVITY");
|
JsonWriteCommandStart(writer, nonce, "SET_ACTIVITY");
|
||||||
|
@ -132,7 +134,7 @@ size_t JsonWriteRichPresenceObj(char* dest, size_t maxLen, int nonce, int pid, c
|
||||||
size_t JsonWriteHandshakeObj(char* dest, size_t maxLen, int version, const char* applicationId)
|
size_t JsonWriteHandshakeObj(char* dest, size_t maxLen, int version, const char* applicationId)
|
||||||
{
|
{
|
||||||
DirectStringBuffer sb(dest, maxLen);
|
DirectStringBuffer sb(dest, maxLen);
|
||||||
WriterAllocator wa;
|
StackAllocator wa;
|
||||||
JsonWriter writer(sb, &wa, WriterNestingLevels);
|
JsonWriter writer(sb, &wa, WriterNestingLevels);
|
||||||
|
|
||||||
writer.StartObject();
|
writer.StartObject();
|
||||||
|
@ -148,7 +150,7 @@ size_t JsonWriteHandshakeObj(char* dest, size_t maxLen, int version, const char*
|
||||||
size_t JsonWriteSubscribeCommand(char* dest, size_t maxLen, int nonce, const char* evtName)
|
size_t JsonWriteSubscribeCommand(char* dest, size_t maxLen, int nonce, const char* evtName)
|
||||||
{
|
{
|
||||||
DirectStringBuffer sb(dest, maxLen);
|
DirectStringBuffer sb(dest, maxLen);
|
||||||
WriterAllocator wa;
|
StackAllocator wa;
|
||||||
JsonWriter writer(sb, &wa, WriterNestingLevels);
|
JsonWriter writer(sb, &wa, WriterNestingLevels);
|
||||||
|
|
||||||
writer.StartObject();
|
writer.StartObject();
|
||||||
|
|
|
@ -63,7 +63,7 @@ public:
|
||||||
static void Free(void* ptr) { /* shrug */ }
|
static void Free(void* ptr) { /* shrug */ }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<int Size>
|
template<size_t Size>
|
||||||
class FixedLinearAllocator : public LinearAllocator {
|
class FixedLinearAllocator : public LinearAllocator {
|
||||||
public:
|
public:
|
||||||
char fixedBuffer_[Size];
|
char fixedBuffer_[Size];
|
||||||
|
@ -98,9 +98,12 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
using MallocAllocator = rapidjson::CrtAllocator;
|
||||||
|
extern MallocAllocator MallocAllocatorInst;
|
||||||
|
using PoolAllocator = rapidjson::MemoryPoolAllocator<MallocAllocator>;
|
||||||
using UTF8 = rapidjson::UTF8<char>;
|
using UTF8 = rapidjson::UTF8<char>;
|
||||||
// Writer appears to need about 16 bytes per nested object level (with 64bit size_t)
|
// Writer appears to need about 16 bytes per nested object level (with 64bit size_t)
|
||||||
using WriterAllocator = FixedLinearAllocator<2048>;
|
using StackAllocator = FixedLinearAllocator<2048>;
|
||||||
constexpr size_t WriterNestingLevels = 2048 / (2 * sizeof(size_t));
|
constexpr size_t WriterNestingLevels = 2048 / (2 * sizeof(size_t));
|
||||||
using JsonWriter = rapidjson::Writer<DirectStringBuffer, UTF8, UTF8, WriterAllocator, rapidjson::kWriteNoFlags>;
|
using JsonWriter = rapidjson::Writer<DirectStringBuffer, UTF8, UTF8, StackAllocator, rapidjson::kWriteNoFlags>;
|
||||||
using JsonDocument = rapidjson::GenericDocument<UTF8>;
|
using JsonDocument = rapidjson::GenericDocument<UTF8, PoolAllocator, FixedLinearAllocator<2048>>;
|
||||||
|
|
Loading…
Reference in a new issue