Format
This commit is contained in:
parent
866e6d1104
commit
7a6172a300
10 changed files with 176 additions and 78 deletions
62
.clang-format
Normal file
62
.clang-format
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
---
|
||||||
|
Language: Cpp
|
||||||
|
AccessModifierOffset: -4
|
||||||
|
AlignAfterOpenBracket: true
|
||||||
|
AlignEscapedNewlinesLeft: true
|
||||||
|
AlignOperands: false
|
||||||
|
AlignTrailingComments: true
|
||||||
|
AllowAllParametersOfDeclarationOnNextLine: false
|
||||||
|
AllowShortBlocksOnASingleLine: false
|
||||||
|
AllowShortCaseLabelsOnASingleLine: false
|
||||||
|
AllowShortIfStatementsOnASingleLine: false
|
||||||
|
AllowShortLoopsOnASingleLine: false
|
||||||
|
AllowShortFunctionsOnASingleLine: Inline
|
||||||
|
AlwaysBreakAfterDefinitionReturnType: false
|
||||||
|
AlwaysBreakTemplateDeclarations: true
|
||||||
|
AlwaysBreakBeforeMultilineStrings: false
|
||||||
|
BreakBeforeBraces: Stroustrup
|
||||||
|
BreakBeforeBinaryOperators: None
|
||||||
|
BreakBeforeTernaryOperators: true
|
||||||
|
BreakConstructorInitializersBeforeComma: true
|
||||||
|
BinPackParameters: false
|
||||||
|
BinPackArguments: false
|
||||||
|
ColumnLimit: 100
|
||||||
|
CommentPragmas: ''
|
||||||
|
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||||
|
ConstructorInitializerIndentWidth: 2
|
||||||
|
ContinuationIndentWidth: 2
|
||||||
|
Cpp11BracedListStyle: true
|
||||||
|
DerivePointerAlignment: false
|
||||||
|
DisableFormat: false
|
||||||
|
ExperimentalAutoDetectBinPacking: false
|
||||||
|
ForEachMacros: [ foreach ]
|
||||||
|
IndentCaseLabels: false
|
||||||
|
IndentWidth: 4
|
||||||
|
IndentWrappedFunctionNames: false
|
||||||
|
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||||
|
MaxEmptyLinesToKeep: 1
|
||||||
|
NamespaceIndentation: None
|
||||||
|
ObjCBlockIndentWidth: 4
|
||||||
|
ObjCSpaceAfterProperty: true
|
||||||
|
ObjCSpaceBeforeProtocolList: true
|
||||||
|
PenaltyBreakBeforeFirstCallParameter: 1
|
||||||
|
PenaltyBreakComment: 300
|
||||||
|
PenaltyBreakString: 1000
|
||||||
|
PenaltyBreakFirstLessLess: 120
|
||||||
|
PenaltyExcessCharacter: 1000000
|
||||||
|
PenaltyReturnTypeOnItsOwnLine: 9999999
|
||||||
|
PointerAlignment: Left
|
||||||
|
SpaceAfterCStyleCast: false
|
||||||
|
SpaceBeforeAssignmentOperators: true
|
||||||
|
SpaceBeforeParens: ControlStatements
|
||||||
|
SpaceInEmptyParentheses: false
|
||||||
|
SpacesBeforeTrailingComments: 1
|
||||||
|
SpacesInAngles: false
|
||||||
|
SpacesInCStyleCastParentheses: false
|
||||||
|
SpacesInContainerLiterals: true
|
||||||
|
SpacesInParentheses: false
|
||||||
|
SpacesInSquareBrackets: false
|
||||||
|
Standard: Cpp11
|
||||||
|
TabWidth: 4
|
||||||
|
UseTab: Never
|
||||||
|
...
|
|
@ -14,7 +14,8 @@
|
||||||
static const char* APPLICATION_ID = "338030514596216832";
|
static const char* APPLICATION_ID = "338030514596216832";
|
||||||
static int FrustrationLevel = 0;
|
static int FrustrationLevel = 0;
|
||||||
|
|
||||||
static void updateDiscordPresence() {
|
static void updateDiscordPresence()
|
||||||
|
{
|
||||||
char buffer[256];
|
char buffer[256];
|
||||||
DiscordRichPresence discordPresence;
|
DiscordRichPresence discordPresence;
|
||||||
memset(&discordPresence, 0, sizeof(discordPresence));
|
memset(&discordPresence, 0, sizeof(discordPresence));
|
||||||
|
@ -24,24 +25,29 @@ static void updateDiscordPresence() {
|
||||||
Discord_UpdatePresence(&discordPresence);
|
Discord_UpdatePresence(&discordPresence);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handleDiscordReady() {
|
static void handleDiscordReady()
|
||||||
|
{
|
||||||
printf("\nDiscord: ready\n");
|
printf("\nDiscord: ready\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handleDiscordDisconnected(int errcode, const char* message) {
|
static void handleDiscordDisconnected(int errcode, const char* message)
|
||||||
|
{
|
||||||
printf("\nDiscord: disconnected (%d: %s)\n", errcode, message);
|
printf("\nDiscord: disconnected (%d: %s)\n", errcode, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handleDiscordError(int errcode, const char* message) {
|
static void handleDiscordError(int errcode, const char* message)
|
||||||
|
{
|
||||||
printf("\nDiscord: error (%d: %s)\n", errcode, message);
|
printf("\nDiscord: error (%d: %s)\n", errcode, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handleDiscordPresenceRequested() {
|
static void handleDiscordPresenceRequested()
|
||||||
|
{
|
||||||
printf("\nDiscord: requests presence\n");
|
printf("\nDiscord: requests presence\n");
|
||||||
updateDiscordPresence();
|
updateDiscordPresence();
|
||||||
}
|
}
|
||||||
|
|
||||||
static int prompt(char* line, size_t size) {
|
static int prompt(char* line, size_t size)
|
||||||
|
{
|
||||||
int res;
|
int res;
|
||||||
char* nl;
|
char* nl;
|
||||||
printf("\n> ");
|
printf("\n> ");
|
||||||
|
@ -55,7 +61,8 @@ static int prompt(char* line, size_t size) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gameLoop() {
|
static void gameLoop()
|
||||||
|
{
|
||||||
char line[512];
|
char line[512];
|
||||||
char* space;
|
char* space;
|
||||||
|
|
||||||
|
@ -63,7 +70,8 @@ static void gameLoop() {
|
||||||
while (prompt(line, sizeof(line))) {
|
while (prompt(line, sizeof(line))) {
|
||||||
if (time(NULL) & 1) {
|
if (time(NULL) & 1) {
|
||||||
printf("I don't understand that.\n");
|
printf("I don't understand that.\n");
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
space = strchr(line, ' ');
|
space = strchr(line, ' ');
|
||||||
if (space) {
|
if (space) {
|
||||||
*space = 0;
|
*space = 0;
|
||||||
|
@ -72,9 +80,9 @@ static void gameLoop() {
|
||||||
}
|
}
|
||||||
|
|
||||||
++FrustrationLevel;
|
++FrustrationLevel;
|
||||||
|
|
||||||
updateDiscordPresence();
|
updateDiscordPresence();
|
||||||
|
|
||||||
#ifdef DISCORD_DISABLE_IO_THREAD
|
#ifdef DISCORD_DISABLE_IO_THREAD
|
||||||
Discord_UpdateConnection();
|
Discord_UpdateConnection();
|
||||||
#endif
|
#endif
|
||||||
|
@ -82,7 +90,8 @@ static void gameLoop() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
int main()
|
||||||
|
{
|
||||||
DiscordEventHandlers handlers;
|
DiscordEventHandlers handlers;
|
||||||
memset(&handlers, 0, sizeof(handlers));
|
memset(&handlers, 0, sizeof(handlers));
|
||||||
handlers.ready = handleDiscordReady;
|
handlers.ready = handleDiscordReady;
|
||||||
|
@ -92,8 +101,7 @@ int main() {
|
||||||
Discord_Initialize(APPLICATION_ID, &handlers);
|
Discord_Initialize(APPLICATION_ID, &handlers);
|
||||||
|
|
||||||
gameLoop();
|
gameLoop();
|
||||||
|
|
||||||
Discord_Shutdown();
|
Discord_Shutdown();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
//#define DISCORD_DISABLE_IO_THREAD
|
//#define DISCORD_DISABLE_IO_THREAD
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -47,6 +47,6 @@ void Discord_UpdateConnection();
|
||||||
|
|
||||||
void Discord_UpdatePresence(const DiscordRichPresence* presence);
|
void Discord_UpdatePresence(const DiscordRichPresence* presence);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -4,8 +4,7 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <random>
|
#include <random>
|
||||||
|
|
||||||
struct Backoff
|
struct Backoff {
|
||||||
{
|
|
||||||
int64_t minAmount;
|
int64_t minAmount;
|
||||||
int64_t maxAmount;
|
int64_t maxAmount;
|
||||||
int64_t current;
|
int64_t current;
|
||||||
|
@ -13,16 +12,15 @@ struct Backoff
|
||||||
std::mt19937_64 randGenerator;
|
std::mt19937_64 randGenerator;
|
||||||
std::uniform_real_distribution<> randDistribution;
|
std::uniform_real_distribution<> randDistribution;
|
||||||
|
|
||||||
double rand01() {
|
double rand01() { return randDistribution(randGenerator); }
|
||||||
return randDistribution(randGenerator);
|
|
||||||
}
|
|
||||||
|
|
||||||
Backoff(int64_t min, int64_t max)
|
Backoff(int64_t min, int64_t max)
|
||||||
: minAmount(min)
|
: minAmount(min)
|
||||||
, maxAmount(max)
|
, maxAmount(max)
|
||||||
, current(min)
|
, current(min)
|
||||||
, fails(0)
|
, fails(0)
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void reset()
|
void reset()
|
||||||
{
|
{
|
||||||
|
@ -38,4 +36,3 @@ struct Backoff
|
||||||
return current;
|
return current;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ struct BaseConnectionWin : public BaseConnection {
|
||||||
};
|
};
|
||||||
|
|
||||||
static BaseConnectionWin Connection;
|
static BaseConnectionWin Connection;
|
||||||
//static const wchar_t* PipeName = L"\\\\?\\pipe\\discord-ipc";
|
// static const wchar_t* PipeName = L"\\\\?\\pipe\\discord-ipc";
|
||||||
static const wchar_t* PipeName = L"\\\\?\\pipe\\discord-ipc-0";
|
static const wchar_t* PipeName = L"\\\\?\\pipe\\discord-ipc-0";
|
||||||
|
|
||||||
/*static*/ BaseConnection* BaseConnection::Create()
|
/*static*/ BaseConnection* BaseConnection::Create()
|
||||||
|
@ -35,7 +35,8 @@ bool BaseConnection::Open()
|
||||||
{
|
{
|
||||||
auto self = reinterpret_cast<BaseConnectionWin*>(this);
|
auto self = reinterpret_cast<BaseConnectionWin*>(this);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
self->pipe = ::CreateFileW(PipeName, GENERIC_READ | GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, 0, nullptr);
|
self->pipe = ::CreateFileW(
|
||||||
|
PipeName, GENERIC_READ | GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, 0, nullptr);
|
||||||
if (self->pipe != INVALID_HANDLE_VALUE) {
|
if (self->pipe != INVALID_HANDLE_VALUE) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -77,4 +78,3 @@ bool BaseConnection::Read(void* data, size_t length)
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,10 +53,12 @@ static std::thread IoThread;
|
||||||
|
|
||||||
static void UpdateReconnectTime()
|
static void UpdateReconnectTime()
|
||||||
{
|
{
|
||||||
NextConnect = std::chrono::system_clock::now() + std::chrono::duration<int64_t, std::milli>{ReconnectTimeMs.nextDelay()};
|
NextConnect = std::chrono::system_clock::now() +
|
||||||
|
std::chrono::duration<int64_t, std::milli>{ReconnectTimeMs.nextDelay()};
|
||||||
}
|
}
|
||||||
|
|
||||||
static QueuedMessage* SendQueueGetNextAddMessage() {
|
static QueuedMessage* SendQueueGetNextAddMessage()
|
||||||
|
{
|
||||||
// if we are falling behind, bail
|
// if we are falling behind, bail
|
||||||
if (SendQueuePendingSends.load() >= MessageQueueSize) {
|
if (SendQueuePendingSends.load() >= MessageQueueSize) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -64,11 +66,13 @@ static QueuedMessage* SendQueueGetNextAddMessage() {
|
||||||
auto index = (SendQueueNextAdd++) % MessageQueueSize;
|
auto index = (SendQueueNextAdd++) % MessageQueueSize;
|
||||||
return &SendQueue[index];
|
return &SendQueue[index];
|
||||||
}
|
}
|
||||||
static QueuedMessage* SendQueueGetNextSendMessage() {
|
static QueuedMessage* SendQueueGetNextSendMessage()
|
||||||
|
{
|
||||||
auto index = (SendQueueNextSend++) % MessageQueueSize;
|
auto index = (SendQueueNextSend++) % MessageQueueSize;
|
||||||
return &SendQueue[index];
|
return &SendQueue[index];
|
||||||
}
|
}
|
||||||
static void SendQueueCommitMessage() {
|
static void SendQueueCommitMessage()
|
||||||
|
{
|
||||||
SendQueuePendingSends++;
|
SendQueuePendingSends++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,7 +149,7 @@ extern "C" void Discord_UpdateConnection()
|
||||||
void DiscordRpcIo()
|
void DiscordRpcIo()
|
||||||
{
|
{
|
||||||
const std::chrono::duration<int64_t, std::milli> maxWait{500LL};
|
const std::chrono::duration<int64_t, std::milli> maxWait{500LL};
|
||||||
|
|
||||||
while (KeepRunning.load()) {
|
while (KeepRunning.load()) {
|
||||||
Discord_UpdateConnection();
|
Discord_UpdateConnection();
|
||||||
|
|
||||||
|
@ -166,7 +170,8 @@ bool RegisterForEvent(const char* evtName)
|
||||||
{
|
{
|
||||||
auto qmessage = SendQueueGetNextAddMessage();
|
auto qmessage = SendQueueGetNextAddMessage();
|
||||||
if (qmessage) {
|
if (qmessage) {
|
||||||
qmessage->length = JsonWriteSubscribeCommand(qmessage->buffer, sizeof(qmessage->buffer), Nonce++, evtName);
|
qmessage->length =
|
||||||
|
JsonWriteSubscribeCommand(qmessage->buffer, sizeof(qmessage->buffer), Nonce++, evtName);
|
||||||
SendQueueCommitMessage();
|
SendQueueCommitMessage();
|
||||||
SignalIOActivity();
|
SignalIOActivity();
|
||||||
return true;
|
return true;
|
||||||
|
@ -233,7 +238,8 @@ extern "C" void Discord_UpdatePresence(const DiscordRichPresence* presence)
|
||||||
{
|
{
|
||||||
auto qmessage = SendQueueGetNextAddMessage();
|
auto qmessage = SendQueueGetNextAddMessage();
|
||||||
if (qmessage) {
|
if (qmessage) {
|
||||||
qmessage->length = JsonWriteRichPresenceObj(qmessage->buffer, sizeof(qmessage->buffer), Nonce++, Pid, presence);
|
qmessage->length = JsonWriteRichPresenceObj(
|
||||||
|
qmessage->buffer, sizeof(qmessage->buffer), Nonce++, Pid, presence);
|
||||||
SendQueueCommitMessage();
|
SendQueueCommitMessage();
|
||||||
SignalIOActivity();
|
SignalIOActivity();
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,8 @@ void RpcConnection::Open()
|
||||||
if (evt == message.MemberEnd() || !evt->value.IsString()) {
|
if (evt == message.MemberEnd() || !evt->value.IsString()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!strcmp(cmd->value.GetString(), "DISPATCH") && !strcmp(evt->value.GetString(), "READY")) {
|
if (!strcmp(cmd->value.GetString(), "DISPATCH") &&
|
||||||
|
!strcmp(evt->value.GetString(), "READY")) {
|
||||||
state = State::Connected;
|
state = State::Connected;
|
||||||
if (onConnect) {
|
if (onConnect) {
|
||||||
onConnect();
|
onConnect();
|
||||||
|
@ -54,7 +55,8 @@ void RpcConnection::Open()
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
sendFrame.opcode = Opcode::Handshake;
|
sendFrame.opcode = Opcode::Handshake;
|
||||||
sendFrame.length = JsonWriteHandshakeObj(sendFrame.message, sizeof(sendFrame.message), RpcVersion, appId);
|
sendFrame.length =
|
||||||
|
JsonWriteHandshakeObj(sendFrame.message, sizeof(sendFrame.message), RpcVersion, appId);
|
||||||
|
|
||||||
if (connection->Write(&sendFrame, sizeof(MessageFrameHeader) + sendFrame.length)) {
|
if (connection->Write(&sendFrame, sizeof(MessageFrameHeader) + sendFrame.length)) {
|
||||||
state = State::SentHandshake;
|
state = State::SentHandshake;
|
||||||
|
@ -110,8 +112,7 @@ bool RpcConnection::Read(JsonDocument& message)
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (readFrame.opcode) {
|
switch (readFrame.opcode) {
|
||||||
case Opcode::Close:
|
case Opcode::Close: {
|
||||||
{
|
|
||||||
message.ParseInsitu(readFrame.message);
|
message.ParseInsitu(readFrame.message);
|
||||||
lastErrorCode = message["code"].GetInt();
|
lastErrorCode = message["code"].GetInt();
|
||||||
const auto& m = message["message"];
|
const auto& m = message["message"];
|
||||||
|
|
|
@ -3,7 +3,8 @@
|
||||||
#include "connection.h"
|
#include "connection.h"
|
||||||
#include "serialization.h"
|
#include "serialization.h"
|
||||||
|
|
||||||
// I took this from the buffer size libuv uses for named pipes; I suspect ours would usually be much smaller.
|
// I took this from the buffer size libuv uses for named pipes; I suspect ours would usually be much
|
||||||
|
// smaller.
|
||||||
constexpr size_t MaxRpcFrameSize = 64 * 1024;
|
constexpr size_t MaxRpcFrameSize = 64 * 1024;
|
||||||
|
|
||||||
struct RpcConnection {
|
struct RpcConnection {
|
||||||
|
@ -43,9 +44,7 @@ struct RpcConnection {
|
||||||
static RpcConnection* Create(const char* applicationId);
|
static RpcConnection* Create(const char* applicationId);
|
||||||
static void Destroy(RpcConnection*&);
|
static void Destroy(RpcConnection*&);
|
||||||
|
|
||||||
inline bool IsOpen() const {
|
inline bool IsOpen() const { return state == State::Connected; }
|
||||||
return state == State::Connected;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Open();
|
void Open();
|
||||||
void Close();
|
void Close();
|
||||||
|
|
|
@ -5,13 +5,15 @@
|
||||||
MallocAllocator MallocAllocatorInst;
|
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)
|
||||||
|
{
|
||||||
w.Key(k, sizeof(T) - 1);
|
w.Key(k, sizeof(T) - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template <typename T>
|
||||||
void WriteOptionalString(JsonWriter& w, T& k, const char* value) {
|
void WriteOptionalString(JsonWriter& w, T& k, const char* value)
|
||||||
|
{
|
||||||
if (value) {
|
if (value) {
|
||||||
w.Key(k, sizeof(T) - 1);
|
w.Key(k, sizeof(T) - 1);
|
||||||
w.String(value);
|
w.String(value);
|
||||||
|
@ -45,7 +47,11 @@ void JsonWriteCommandEnd(JsonWriter& writer)
|
||||||
writer.EndObject(); // top level
|
writer.EndObject(); // top level
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
StackAllocator wa;
|
StackAllocator wa;
|
||||||
|
@ -79,7 +85,8 @@ size_t JsonWriteRichPresenceObj(char* dest, size_t maxLen, int nonce, int pid, c
|
||||||
writer.EndObject();
|
writer.EndObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (presence->largeImageKey || presence->largeImageText || presence->smallImageKey || presence->smallImageText) {
|
if (presence->largeImageKey || presence->largeImageText || presence->smallImageKey ||
|
||||||
|
presence->smallImageText) {
|
||||||
WriteKey(writer, "assets");
|
WriteKey(writer, "assets");
|
||||||
writer.StartObject();
|
writer.StartObject();
|
||||||
|
|
||||||
|
@ -156,13 +163,13 @@ size_t JsonWriteSubscribeCommand(char* dest, size_t maxLen, int nonce, const cha
|
||||||
writer.StartObject();
|
writer.StartObject();
|
||||||
|
|
||||||
JsonWriteNonce(writer, nonce);
|
JsonWriteNonce(writer, nonce);
|
||||||
|
|
||||||
WriteKey(writer, "cmd");
|
WriteKey(writer, "cmd");
|
||||||
writer.String("SUBSCRIBE");
|
writer.String("SUBSCRIBE");
|
||||||
|
|
||||||
WriteKey(writer, "evt");
|
WriteKey(writer, "evt");
|
||||||
writer.String(evtName);
|
writer.String(evtName);
|
||||||
|
|
||||||
writer.EndObject();
|
writer.EndObject();
|
||||||
|
|
||||||
return sb.GetSize();
|
return sb.GetSize();
|
||||||
|
|
|
@ -8,8 +8,9 @@
|
||||||
#include "rapidjson/internal/itoa.h"
|
#include "rapidjson/internal/itoa.h"
|
||||||
|
|
||||||
// if only there was a standard library function for this
|
// if only there was a standard library function for this
|
||||||
template<size_t Len>
|
template <size_t Len>
|
||||||
inline size_t StringCopy(char (&dest)[Len], const char* src) {
|
inline size_t StringCopy(char (&dest)[Len], const char* src)
|
||||||
|
{
|
||||||
if (!dest || !src || !Len) {
|
if (!dest || !src || !Len) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -26,20 +27,30 @@ size_t JsonWriteHandshakeObj(char* dest, size_t maxLen, int version, const char*
|
||||||
|
|
||||||
// Commands
|
// Commands
|
||||||
struct DiscordRichPresence;
|
struct DiscordRichPresence;
|
||||||
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);
|
||||||
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);
|
||||||
|
|
||||||
// I want to use as few allocations as I can get away with, and to do that with RapidJson, you need to supply some of
|
// I want to use as few allocations as I can get away with, and to do that with RapidJson, you need
|
||||||
|
// to supply some of
|
||||||
// your own allocators for stuff rather than use the defaults
|
// your own allocators for stuff rather than use the defaults
|
||||||
|
|
||||||
class LinearAllocator {
|
class LinearAllocator {
|
||||||
public:
|
public:
|
||||||
char* buffer_;
|
char* buffer_;
|
||||||
char* end_;
|
char* end_;
|
||||||
LinearAllocator() {
|
LinearAllocator()
|
||||||
|
{
|
||||||
assert(0); // needed for some default case in rapidjson, should not use
|
assert(0); // needed for some default case in rapidjson, should not use
|
||||||
}
|
}
|
||||||
LinearAllocator(char* buffer, size_t size) : buffer_(buffer), end_(buffer + size) {}
|
LinearAllocator(char* buffer, size_t size)
|
||||||
|
: buffer_(buffer)
|
||||||
|
, end_(buffer + size)
|
||||||
|
{
|
||||||
|
}
|
||||||
static const bool kNeedFree = false;
|
static const bool kNeedFree = false;
|
||||||
void* Malloc(size_t size)
|
void* Malloc(size_t size)
|
||||||
{
|
{
|
||||||
|
@ -60,14 +71,17 @@ public:
|
||||||
assert(!originalPtr && !originalSize);
|
assert(!originalPtr && !originalSize);
|
||||||
return Malloc(newSize);
|
return Malloc(newSize);
|
||||||
}
|
}
|
||||||
static void Free(void* ptr) { /* shrug */ }
|
static void Free(void* ptr) { /* shrug */}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<size_t Size>
|
template <size_t Size>
|
||||||
class FixedLinearAllocator : public LinearAllocator {
|
class FixedLinearAllocator : public LinearAllocator {
|
||||||
public:
|
public:
|
||||||
char fixedBuffer_[Size];
|
char fixedBuffer_[Size];
|
||||||
FixedLinearAllocator() : LinearAllocator(fixedBuffer_, Size) {}
|
FixedLinearAllocator()
|
||||||
|
: LinearAllocator(fixedBuffer_, Size)
|
||||||
|
{
|
||||||
|
}
|
||||||
static const bool kNeedFree = false;
|
static const bool kNeedFree = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -80,10 +94,11 @@ public:
|
||||||
char* current_;
|
char* current_;
|
||||||
|
|
||||||
DirectStringBuffer(char* buffer, size_t maxLen)
|
DirectStringBuffer(char* buffer, size_t maxLen)
|
||||||
: buffer_(buffer)
|
: buffer_(buffer)
|
||||||
, end_(buffer + maxLen)
|
, end_(buffer + maxLen)
|
||||||
, current_(buffer)
|
, current_(buffer)
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void Put(char c)
|
void Put(char c)
|
||||||
{
|
{
|
||||||
|
@ -92,10 +107,7 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void Flush() {}
|
void Flush() {}
|
||||||
size_t GetSize() const
|
size_t GetSize() const { return current_ - buffer_; }
|
||||||
{
|
|
||||||
return current_ - buffer_;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
using MallocAllocator = rapidjson::CrtAllocator;
|
using MallocAllocator = rapidjson::CrtAllocator;
|
||||||
|
@ -104,19 +116,25 @@ 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 StackAllocator = 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, StackAllocator, rapidjson::kWriteNoFlags>;
|
using JsonWriter =
|
||||||
|
rapidjson::Writer<DirectStringBuffer, UTF8, UTF8, StackAllocator, rapidjson::kWriteNoFlags>;
|
||||||
using JsonDocumentBase = rapidjson::GenericDocument<UTF8, PoolAllocator, StackAllocator>;
|
using JsonDocumentBase = rapidjson::GenericDocument<UTF8, PoolAllocator, StackAllocator>;
|
||||||
class JsonDocument : public JsonDocumentBase
|
class JsonDocument : public JsonDocumentBase {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
static const int kDefaultChunkCapacity = 32 * 1024;
|
static const int kDefaultChunkCapacity = 32 * 1024;
|
||||||
// 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.
|
// 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];
|
char parseBuffer_[32 * 1024];
|
||||||
MallocAllocator mallocAllocator_;
|
MallocAllocator mallocAllocator_;
|
||||||
PoolAllocator poolAllocator_;
|
PoolAllocator poolAllocator_;
|
||||||
StackAllocator stackAllocator_;
|
StackAllocator stackAllocator_;
|
||||||
JsonDocument() : JsonDocumentBase(rapidjson::kObjectType, &poolAllocator_, sizeof(stackAllocator_.fixedBuffer_), &stackAllocator_)
|
JsonDocument()
|
||||||
, poolAllocator_(parseBuffer_, sizeof(parseBuffer_), kDefaultChunkCapacity, &mallocAllocator_)
|
: JsonDocumentBase(rapidjson::kObjectType,
|
||||||
, stackAllocator_()
|
&poolAllocator_,
|
||||||
{}
|
sizeof(stackAllocator_.fixedBuffer_),
|
||||||
|
&stackAllocator_)
|
||||||
|
, poolAllocator_(parseBuffer_, sizeof(parseBuffer_), kDefaultChunkCapacity, &mallocAllocator_)
|
||||||
|
, stackAllocator_()
|
||||||
|
{
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue