summaryrefslogtreecommitdiff
path: root/Source/Core/DolphinQt/DiscordHandler.cpp
blob: f52d31b2ce8962bd094ecc91c9131f6470d8fb90 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
// Copyright 2018 Dolphin Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later

#ifdef USE_DISCORD_PRESENCE

#include "DolphinQt/DiscordHandler.h"

#include <chrono>

#include <QApplication>

#include "Common/Thread.h"

#include "UICommon/DiscordPresence.h"

#include "DolphinQt/DiscordJoinRequestDialog.h"
#include "DolphinQt/QtUtils/RunOnObject.h"

DiscordHandler::DiscordHandler(QWidget* parent) : QObject{parent}, m_parent{parent}
{
  connect(this, &DiscordHandler::JoinRequest, this, &DiscordHandler::ShowNewJoinRequest);
}

DiscordHandler::~DiscordHandler()
{
  Stop();
}

void DiscordHandler::Start()
{
  m_stop_requested.Set(false);
  m_thread = std::thread(&DiscordHandler::Run, this);
}

void DiscordHandler::Stop()
{
  if (!m_thread.joinable())
    return;

  m_stop_requested.Set(true);
  m_wakeup_event.Set();
  m_thread.join();
}

void DiscordHandler::DiscordJoinRequest(const char* id, const std::string& discord_tag,
                                        const char* avatar)
{
  emit DiscordHandler::JoinRequest(id, discord_tag, avatar);
}

void DiscordHandler::DiscordJoin()
{
  emit DiscordHandler::Join();
}

void DiscordHandler::ShowNewJoinRequest(const std::string& id, const std::string& discord_tag,
                                        const std::string& avatar)
{
  std::lock_guard<std::mutex> lock(m_request_dialogs_mutex);
  m_request_dialogs.emplace_front(m_parent, id, discord_tag, avatar);
  DiscordJoinRequestDialog& request_dialog = m_request_dialogs.front();
  request_dialog.show();
  request_dialog.raise();
  request_dialog.activateWindow();
  QApplication::alert(nullptr, DiscordJoinRequestDialog::s_max_lifetime_seconds * 1000);
}

void DiscordHandler::Run()
{
  Common::SetCurrentThreadName("DiscordHandler");

  while (!m_stop_requested.IsSet())
  {
    Discord::CallPendingCallbacks();

    // close and remove dead requests
    {
      std::lock_guard<std::mutex> lock(m_request_dialogs_mutex);
      for (auto request_dialog = m_request_dialogs.begin();
           request_dialog != m_request_dialogs.end();)
      {
        if (std::time(nullptr) < request_dialog->GetCloseTimestamp())
        {
          ++request_dialog;
          continue;
        }

        RunOnObject(m_parent, [this, &request_dialog] {
          request_dialog->close();
          request_dialog = m_request_dialogs.erase(request_dialog);
          return nullptr;
        });
      }
    }

    m_wakeup_event.WaitFor(std::chrono::seconds{2});
  }
}

#endif