Register for events for our three callbacks

This commit is contained in:
Chris Marsh 2017-07-21 15:42:59 -07:00
parent 063a329a0b
commit 449584b9c9
3 changed files with 103 additions and 23 deletions

View file

@ -12,8 +12,8 @@
#include <thread> #include <thread>
#endif #endif
constexpr size_t MaxMessageSize = 16 * 1024; constexpr size_t MaxMessageSize{16 * 1024};
constexpr size_t MessageQueueSize = 8; constexpr size_t MessageQueueSize{8};
struct QueuedMessage { struct QueuedMessage {
size_t length; size_t length;
@ -25,6 +25,11 @@ static char ApplicationId[64]{};
static DiscordEventHandlers Handlers{}; static DiscordEventHandlers Handlers{};
static std::atomic_bool WasJustConnected{false}; static std::atomic_bool WasJustConnected{false};
static std::atomic_bool WasJustDisconnected{false}; static std::atomic_bool WasJustDisconnected{false};
static std::atomic_bool WasPresenceRequested{false};
static std::atomic_bool WasJoinGame{false};
static std::atomic_bool WasSpectateGame{false};
static char JoinGameSecret[256];
static char SpectateGameSecret[256];
static int LastErrorCode{0}; static int LastErrorCode{0};
static char LastErrorMessage[256]; static char LastErrorMessage[256];
static QueuedMessage SendQueue[MessageQueueSize]{}; static QueuedMessage SendQueue[MessageQueueSize]{};
@ -33,11 +38,11 @@ static std::atomic_uint SendQueueNextSend{0};
static std::atomic_uint SendQueuePendingSends{0}; static std::atomic_uint SendQueuePendingSends{0};
static Backoff ReconnectTimeMs(500, 60 * 1000); static Backoff ReconnectTimeMs(500, 60 * 1000);
static auto NextConnect{std::chrono::system_clock::now()}; static auto NextConnect{std::chrono::system_clock::now()};
static int Pid = 0; static int Pid{0};
static int Nonce = 1; static int Nonce{1};
#ifndef DISCORD_DISABLE_IO_THREAD #ifndef DISCORD_DISABLE_IO_THREAD
static std::atomic_bool KeepRunning{ true }; static std::atomic_bool KeepRunning{true};
static std::mutex WaitForIOMutex; static std::mutex WaitForIOMutex;
static std::condition_variable WaitForIOActivity; static std::condition_variable WaitForIOActivity;
static std::thread IoThread; static std::thread IoThread;
@ -76,21 +81,35 @@ extern "C" void Discord_UpdateConnection()
// reads // reads
rapidjson::Document message; rapidjson::Document message;
while (Connection->Read(message)) { while (Connection->Read(message)) {
// todo: do something... auto nonce = message.FindMember("nonce");
printf("Hey, I got a message\n"); if (nonce != message.MemberEnd() && nonce->value.IsString()) {
// in responses only -- should use to match up response when needed.
//auto cmd = message.FindMember("cmd"); needed?
}
else {
// should have evt == name of event, optional data
auto evt = message.FindMember("evt");
if (evt != message.MemberEnd() && evt->value.IsString()) {
const char* evtName = evt->value.GetString();
// expect cmd, data, evt, nonce here? // todo ug
if (strcmp(evtName, "PRESENCE_REQUESTED") == 0) {
/* WasPresenceRequested.store(true);
message.FindMember("cmd"); }
message.FindMember("data"); else if (strcmp(evtName, "JOIN_GAME") == 0) {
message.FindMember("evt"); auto data = message.FindMember("data");
message.FindMember("nonce"); // in responses only auto secret = data->value["secret"].GetString();
StringCopy(JoinGameSecret, secret);
void(*presenceRequested)(); WasJoinGame.store(true);
void(*joinGame)(const char* joinSecret); }
void(*spectateGame)(const char* spectateSecret); else if (strcmp(evtName, "SPECTATE_GAME") == 0) {
*/ auto data = message.FindMember("data");
auto secret = data->value["secret"].GetString();
StringCopy(SpectateGameSecret, secret);
WasSpectateGame.store(true);
}
}
}
} }
// writes // writes
@ -123,6 +142,18 @@ void SignalIOActivity()
#endif #endif
} }
bool RegisterForEvent(const char* evtName)
{
auto qmessage = SendQueueGetNextAddMessage();
if (qmessage) {
qmessage->length = JsonWriteSubscribeCommand(qmessage->buffer, sizeof(qmessage->buffer), Nonce++, evtName);
SendQueueCommitMessage();
SignalIOActivity();
return true;
}
return false;
}
extern "C" void Discord_Initialize(const char* applicationId, DiscordEventHandlers* handlers) extern "C" void Discord_Initialize(const char* applicationId, DiscordEventHandlers* handlers)
{ {
Pid = GetProcessId(); Pid = GetProcessId();
@ -138,6 +169,18 @@ extern "C" void Discord_Initialize(const char* applicationId, DiscordEventHandle
Connection->onConnect = []() { Connection->onConnect = []() {
WasJustConnected.exchange(true); WasJustConnected.exchange(true);
ReconnectTimeMs.reset(); ReconnectTimeMs.reset();
if (Handlers.presenceRequested) {
RegisterForEvent("PRESENCE_REQUESTED");
}
if (Handlers.joinGame) {
RegisterForEvent("JOIN_GAME");
}
if (Handlers.spectateGame) {
RegisterForEvent("SPECTATE_GAME");
}
}; };
Connection->onDisconnect = [](int err, const char* message) { Connection->onDisconnect = [](int err, const char* message) {
LastErrorCode = err; LastErrorCode = err;
@ -185,4 +228,16 @@ extern "C" void Discord_RunCallbacks()
if (WasJustConnected.exchange(false) && Handlers.ready) { if (WasJustConnected.exchange(false) && Handlers.ready) {
Handlers.ready(); Handlers.ready();
} }
if (WasPresenceRequested.exchange(false) && Handlers.presenceRequested) {
Handlers.presenceRequested();
}
if (WasJoinGame.exchange(false) && Handlers.joinGame) {
Handlers.joinGame(JoinGameSecret);
}
if (WasSpectateGame.exchange(false) && Handlers.spectateGame) {
Handlers.spectateGame(SpectateGameSecret);
}
} }

View file

@ -94,14 +94,19 @@ void WriteOptionalString(JsonWriter& w, T& k, const char* value) {
} }
} }
void JsonWriteCommandStart(JsonWriter& writer, int nonce, const char* cmd) void JsonWriteNonce(JsonWriter& writer, int nonce)
{ {
writer.StartObject();
WriteKey(writer, "nonce"); WriteKey(writer, "nonce");
char nonceBuffer[32]{}; char nonceBuffer[32]{};
rapidjson::internal::i32toa(nonce, nonceBuffer); rapidjson::internal::i32toa(nonce, nonceBuffer);
writer.String(nonceBuffer); writer.String(nonceBuffer);
}
void JsonWriteCommandStart(JsonWriter& writer, int nonce, const char* cmd)
{
writer.StartObject();
JsonWriteNonce(writer, nonce);
WriteKey(writer, "cmd"); WriteKey(writer, "cmd");
writer.String(cmd); writer.String(cmd);
@ -218,3 +223,23 @@ size_t JsonWriteHandshakeObj(char* dest, size_t maxLen, int version, const char*
return sb.GetSize(); return sb.GetSize();
} }
size_t JsonWriteSubscribeCommand(char* dest, size_t maxLen, int nonce, const char* evtName)
{
DirectStringBuffer sb(dest, maxLen);
WriterAllocator wa;
JsonWriter writer(sb, &wa, WriterNestingLevels);
writer.StartObject();
JsonWriteNonce(writer, nonce);
WriteKey(writer, "cmd");
writer.String("SUBSCRIBE");
WriteKey(writer, "evt");
writer.String(evtName);
writer.EndObject();
return sb.GetSize();
}

View file

@ -22,4 +22,4 @@ 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);