changed .clang-format

This commit is contained in:
fourtf
2018-08-15 22:46:20 +02:00
parent 44c16f1b3a
commit af7b742a23
46 changed files with 1636 additions and 1611 deletions
+128 -126
View File
@@ -24,157 +24,159 @@ static std::map<QString, std::string> sentMessages;
namespace detail {
PubSubClient::PubSubClient(WebsocketClient &websocketClient,
WebsocketHandle handle)
: websocketClient_(websocketClient)
, handle_(handle)
{
}
void PubSubClient::start()
{
assert(!this->started_);
this->started_ = true;
this->ping();
}
void PubSubClient::stop()
{
assert(this->started_);
this->started_ = false;
}
bool PubSubClient::listen(rapidjson::Document &message)
{
int numRequestedListens = message["data"]["topics"].Size();
if (this->numListens_ + numRequestedListens > MAX_PUBSUB_LISTENS) {
// This PubSubClient is already at its peak listens
return false;
PubSubClient::PubSubClient(WebsocketClient &websocketClient,
WebsocketHandle handle)
: websocketClient_(websocketClient)
, handle_(handle)
{
}
this->numListens_ += numRequestedListens;
void PubSubClient::start()
{
assert(!this->started_);
for (const auto &topic : message["data"]["topics"].GetArray()) {
this->listeners_.emplace_back(
Listener{topic.GetString(), false, false, false});
this->started_ = true;
this->ping();
}
auto uuid = CreateUUID();
void PubSubClient::stop()
{
assert(this->started_);
rj::set(message, "nonce", uuid);
this->started_ = false;
}
std::string payload = rj::stringify(message);
sentMessages[uuid] = payload;
bool PubSubClient::listen(rapidjson::Document &message)
{
int numRequestedListens = message["data"]["topics"].Size();
this->send(payload.c_str());
return true;
}
void PubSubClient::unlistenPrefix(const std::string &prefix)
{
std::vector<std::string> topics;
for (auto it = this->listeners_.begin(); it != this->listeners_.end();) {
const auto &listener = *it;
if (listener.topic.find(prefix) == 0) {
topics.push_back(listener.topic);
it = this->listeners_.erase(it);
} else {
++it;
if (this->numListens_ + numRequestedListens > MAX_PUBSUB_LISTENS) {
// This PubSubClient is already at its peak listens
return false;
}
}
if (topics.empty()) {
return;
}
this->numListens_ += numRequestedListens;
auto message = createUnlistenMessage(topics);
auto uuid = CreateUUID();
rj::set(message, "nonce", CreateUUID());
std::string payload = rj::stringify(message);
sentMessages[uuid] = payload;
this->send(payload.c_str());
}
void PubSubClient::handlePong()
{
assert(this->awaitingPong_);
log("Got pong!");
this->awaitingPong_ = false;
}
bool PubSubClient::isListeningToTopic(const std::string &payload)
{
for (const auto &listener : this->listeners_) {
if (listener.topic == payload) {
return true;
for (const auto &topic : message["data"]["topics"].GetArray()) {
this->listeners_.emplace_back(
Listener{topic.GetString(), false, false, false});
}
auto uuid = CreateUUID();
rj::set(message, "nonce", uuid);
std::string payload = rj::stringify(message);
sentMessages[uuid] = payload;
this->send(payload.c_str());
return true;
}
return false;
}
void PubSubClient::unlistenPrefix(const std::string &prefix)
{
std::vector<std::string> topics;
void PubSubClient::ping()
{
assert(this->started_);
for (auto it = this->listeners_.begin();
it != this->listeners_.end();) {
const auto &listener = *it;
if (listener.topic.find(prefix) == 0) {
topics.push_back(listener.topic);
it = this->listeners_.erase(it);
} else {
++it;
}
}
if (!this->send(pingPayload)) {
return;
if (topics.empty()) {
return;
}
auto message = createUnlistenMessage(topics);
auto uuid = CreateUUID();
rj::set(message, "nonce", CreateUUID());
std::string payload = rj::stringify(message);
sentMessages[uuid] = payload;
this->send(payload.c_str());
}
this->awaitingPong_ = true;
void PubSubClient::handlePong()
{
assert(this->awaitingPong_);
auto self = this->shared_from_this();
log("Got pong!");
runAfter(this->websocketClient_.get_io_service(), std::chrono::seconds(15),
[self](auto timer) {
if (!self->started_) {
return;
}
this->awaitingPong_ = false;
}
if (self->awaitingPong_) {
log("No pong respnose, disconnect!");
// TODO(pajlada): Label this connection as "disconnect me"
}
});
runAfter(this->websocketClient_.get_io_service(), std::chrono::minutes(5),
[self](auto timer) {
if (!self->started_) {
return;
}
self->ping(); //
});
}
bool PubSubClient::send(const char *payload)
{
WebsocketErrorCode ec;
this->websocketClient_.send(this->handle_, payload,
websocketpp::frame::opcode::text, ec);
if (ec) {
log("Error sending message {}: {}", payload, ec.message());
// TODO(pajlada): Check which error code happened and maybe gracefully
// handle it
bool PubSubClient::isListeningToTopic(const std::string &payload)
{
for (const auto &listener : this->listeners_) {
if (listener.topic == payload) {
return true;
}
}
return false;
}
return true;
}
void PubSubClient::ping()
{
assert(this->started_);
if (!this->send(pingPayload)) {
return;
}
this->awaitingPong_ = true;
auto self = this->shared_from_this();
runAfter(this->websocketClient_.get_io_service(),
std::chrono::seconds(15), [self](auto timer) {
if (!self->started_) {
return;
}
if (self->awaitingPong_) {
log("No pong respnose, disconnect!");
// TODO(pajlada): Label this connection as "disconnect
// me"
}
});
runAfter(this->websocketClient_.get_io_service(),
std::chrono::minutes(5), [self](auto timer) {
if (!self->started_) {
return;
}
self->ping(); //
});
}
bool PubSubClient::send(const char *payload)
{
WebsocketErrorCode ec;
this->websocketClient_.send(this->handle_, payload,
websocketpp::frame::opcode::text, ec);
if (ec) {
log("Error sending message {}: {}", payload, ec.message());
// TODO(pajlada): Check which error code happened and maybe
// gracefully handle it
return false;
}
return true;
}
} // namespace detail
+27 -26
View File
@@ -32,41 +32,42 @@ using WebsocketErrorCode = websocketpp::lib::error_code;
namespace detail {
struct Listener {
std::string topic;
bool authed;
bool persistent;
bool confirmed = false;
};
struct Listener {
std::string topic;
bool authed;
bool persistent;
bool confirmed = false;
};
class PubSubClient : public std::enable_shared_from_this<PubSubClient>
{
public:
PubSubClient(WebsocketClient &_websocketClient, WebsocketHandle _handle);
class PubSubClient : public std::enable_shared_from_this<PubSubClient>
{
public:
PubSubClient(WebsocketClient &_websocketClient,
WebsocketHandle _handle);
void start();
void stop();
void start();
void stop();
bool listen(rapidjson::Document &message);
void unlistenPrefix(const std::string &prefix);
bool listen(rapidjson::Document &message);
void unlistenPrefix(const std::string &prefix);
void handlePong();
void handlePong();
bool isListeningToTopic(const std::string &topic);
bool isListeningToTopic(const std::string &topic);
private:
void ping();
bool send(const char *payload);
private:
void ping();
bool send(const char *payload);
WebsocketClient &websocketClient_;
WebsocketHandle handle_;
uint16_t numListens_ = 0;
WebsocketClient &websocketClient_;
WebsocketHandle handle_;
uint16_t numListens_ = 0;
std::vector<Listener> listeners_;
std::vector<Listener> listeners_;
std::atomic<bool> awaitingPong_{false};
std::atomic<bool> started_{false};
};
std::atomic<bool> awaitingPong_{false};
std::atomic<bool> started_{false};
};
} // namespace detail
+2 -3
View File
@@ -1,11 +1,10 @@
#pragma once
#include "debug/Log.hpp"
#include "util/RapidjsonHelpers.hpp"
#include "debug/Log.hpp"
#include <boost/asio.hpp>
#include <boost/asio/steady_timer.hpp>
#include <memory>
#include "debug/Log.hpp"
#include "util/RapidjsonHelpers.hpp"
namespace chatterino {
+23 -23
View File
@@ -15,32 +15,32 @@ namespace chatterino {
namespace {
EmoteName cleanUpCode(const EmoteName &dirtyEmoteCode)
{
auto cleanCode = dirtyEmoteCode.string;
cleanCode.detach();
EmoteName cleanUpCode(const EmoteName &dirtyEmoteCode)
{
auto cleanCode = dirtyEmoteCode.string;
cleanCode.detach();
static QMap<QString, QString> emoteNameReplacements{
{"[oO](_|\\.)[oO]", "O_o"}, {"\\&gt\\;\\(", "&gt;("},
{"\\&lt\\;3", "&lt;3"}, {"\\:-?(o|O)", ":O"},
{"\\:-?(p|P)", ":P"}, {"\\:-?[\\\\/]", ":/"},
{"\\:-?[z|Z|\\|]", ":Z"}, {"\\:-?\\(", ":("},
{"\\:-?\\)", ":)"}, {"\\:-?D", ":D"},
{"\\;-?(p|P)", ";P"}, {"\\;-?\\)", ";)"},
{"R-?\\)", "R)"}, {"B-?\\)", "B)"},
};
static QMap<QString, QString> emoteNameReplacements{
{"[oO](_|\\.)[oO]", "O_o"}, {"\\&gt\\;\\(", "&gt;("},
{"\\&lt\\;3", "&lt;3"}, {"\\:-?(o|O)", ":O"},
{"\\:-?(p|P)", ":P"}, {"\\:-?[\\\\/]", ":/"},
{"\\:-?[z|Z|\\|]", ":Z"}, {"\\:-?\\(", ":("},
{"\\:-?\\)", ":)"}, {"\\:-?D", ":D"},
{"\\;-?(p|P)", ";P"}, {"\\;-?\\)", ";)"},
{"R-?\\)", "R)"}, {"B-?\\)", "B)"},
};
auto it = emoteNameReplacements.find(dirtyEmoteCode.string);
if (it != emoteNameReplacements.end()) {
cleanCode = it.value();
auto it = emoteNameReplacements.find(dirtyEmoteCode.string);
if (it != emoteNameReplacements.end()) {
cleanCode = it.value();
}
cleanCode.replace("&lt;", "<");
cleanCode.replace("&gt;", ">");
return {cleanCode};
}
cleanCode.replace("&lt;", "<");
cleanCode.replace("&gt;", ">");
return {cleanCode};
}
} // namespace
TwitchAccount::TwitchAccount(const QString &username, const QString &oauthToken,
@@ -417,7 +417,7 @@ void TwitchAccount::loadEmotes()
}
AccessGuard<const TwitchAccount::TwitchAccountEmoteData>
TwitchAccount::accessEmotes() const
TwitchAccount::accessEmotes() const
{
return this->emotes_.accessConst();
}
+34 -33
View File
@@ -25,48 +25,49 @@
namespace chatterino {
namespace {
auto parseRecentMessages(const QJsonObject &jsonRoot, TwitchChannel &channel)
{
QJsonArray jsonMessages = jsonRoot.value("messages").toArray();
std::vector<MessagePtr> messages;
auto parseRecentMessages(const QJsonObject &jsonRoot,
TwitchChannel &channel)
{
QJsonArray jsonMessages = jsonRoot.value("messages").toArray();
std::vector<MessagePtr> messages;
if (jsonMessages.empty()) return messages;
if (jsonMessages.empty()) return messages;
for (const auto jsonMessage : jsonMessages) {
auto content = jsonMessage.toString().toUtf8();
// passing nullptr as the channel makes the message invalid but we don't
// check for that anyways
auto message = Communi::IrcMessage::fromData(content, nullptr);
auto privMsg = dynamic_cast<Communi::IrcPrivateMessage *>(message);
assert(privMsg);
for (const auto jsonMessage : jsonMessages) {
auto content = jsonMessage.toString().toUtf8();
// passing nullptr as the channel makes the message invalid but we
// don't check for that anyways
auto message = Communi::IrcMessage::fromData(content, nullptr);
auto privMsg = dynamic_cast<Communi::IrcPrivateMessage *>(message);
assert(privMsg);
MessageParseArgs args;
TwitchMessageBuilder builder(&channel, privMsg, args);
if (!builder.isIgnored()) {
messages.push_back(builder.build());
MessageParseArgs args;
TwitchMessageBuilder builder(&channel, privMsg, args);
if (!builder.isIgnored()) {
messages.push_back(builder.build());
}
}
return messages;
}
std::pair<Outcome, UsernameSet> parseChatters(const QJsonObject &jsonRoot)
{
static QStringList categories = {"moderators", "staff", "admins",
"global_mods", "viewers"};
return messages;
}
std::pair<Outcome, UsernameSet> parseChatters(const QJsonObject &jsonRoot)
{
static QStringList categories = {"moderators", "staff", "admins",
"global_mods", "viewers"};
auto usernames = UsernameSet();
auto usernames = UsernameSet();
// parse json
QJsonObject jsonCategories = jsonRoot.value("chatters").toObject();
// parse json
QJsonObject jsonCategories = jsonRoot.value("chatters").toObject();
for (const auto &category : categories) {
for (auto jsonCategory : jsonCategories.value(category).toArray()) {
usernames.insert(jsonCategory.toString());
for (const auto &category : categories) {
for (auto jsonCategory : jsonCategories.value(category).toArray()) {
usernames.insert(jsonCategory.toString());
}
}
}
return {Success, std::move(usernames)};
}
return {Success, std::move(usernames)};
}
} // namespace
TwitchChannel::TwitchChannel(const QString &name,
@@ -309,7 +310,7 @@ bool TwitchChannel::isLive() const
}
AccessGuard<const TwitchChannel::StreamStatus>
TwitchChannel::accessStreamStatus() const
TwitchChannel::accessStreamStatus() const
{
return this->streamStatus_.accessConst();
}
+177 -177
View File
@@ -8,235 +8,235 @@ namespace chatterino {
namespace {
template <typename Type>
inline bool ReadValue(const rapidjson::Value &object, const char *key,
Type &out)
{
if (!object.HasMember(key)) {
return false;
}
const auto &value = object[key];
if (!value.Is<Type>()) {
return false;
}
out = value.Get<Type>();
return true;
}
template <>
inline bool ReadValue<QString>(const rapidjson::Value &object, const char *key,
QString &out)
{
if (!object.HasMember(key)) {
return false;
}
const auto &value = object[key];
if (!value.IsString()) {
return false;
}
out = value.GetString();
return true;
}
template <>
inline bool ReadValue<std::vector<QString>>(const rapidjson::Value &object,
const char *key,
std::vector<QString> &out)
{
if (!object.HasMember(key)) {
return false;
}
const auto &value = object[key];
if (!value.IsArray()) {
return false;
}
for (const rapidjson::Value &innerValue : value.GetArray()) {
if (!innerValue.IsString()) {
template <typename Type>
inline bool ReadValue(const rapidjson::Value &object, const char *key,
Type &out)
{
if (!object.HasMember(key)) {
return false;
}
out.emplace_back(innerValue.GetString());
}
const auto &value = object[key];
return true;
}
// Parse a single cheermote set (or "action") from the twitch api
inline bool ParseSingleCheermoteSet(JSONCheermoteSet &set,
const rapidjson::Value &action)
{
if (!action.IsObject()) {
return false;
}
if (!ReadValue(action, "prefix", set.prefix)) {
return false;
}
if (!ReadValue(action, "scales", set.scales)) {
return false;
}
if (!ReadValue(action, "backgrounds", set.backgrounds)) {
return false;
}
if (!ReadValue(action, "states", set.states)) {
return false;
}
if (!ReadValue(action, "type", set.type)) {
return false;
}
if (!ReadValue(action, "updated_at", set.updatedAt)) {
return false;
}
if (!ReadValue(action, "priority", set.priority)) {
return false;
}
// Tiers
if (!action.HasMember("tiers")) {
return false;
}
const auto &tiersValue = action["tiers"];
if (!tiersValue.IsArray()) {
return false;
}
for (const rapidjson::Value &tierValue : tiersValue.GetArray()) {
JSONCheermoteSet::CheermoteTier tier;
if (!tierValue.IsObject()) {
if (!value.Is<Type>()) {
return false;
}
if (!ReadValue(tierValue, "min_bits", tier.minBits)) {
out = value.Get<Type>();
return true;
}
template <>
inline bool ReadValue<QString>(const rapidjson::Value &object,
const char *key, QString &out)
{
if (!object.HasMember(key)) {
return false;
}
if (!ReadValue(tierValue, "id", tier.id)) {
const auto &value = object[key];
if (!value.IsString()) {
return false;
}
if (!ReadValue(tierValue, "color", tier.color)) {
out = value.GetString();
return true;
}
template <>
inline bool ReadValue<std::vector<QString>>(const rapidjson::Value &object,
const char *key,
std::vector<QString> &out)
{
if (!object.HasMember(key)) {
return false;
}
// Images
if (!tierValue.HasMember("images")) {
const auto &value = object[key];
if (!value.IsArray()) {
return false;
}
const auto &imagesValue = tierValue["images"];
if (!imagesValue.IsObject()) {
return false;
}
// Read images object
for (const auto &imageBackgroundValue : imagesValue.GetObject()) {
QString background = imageBackgroundValue.name.GetString();
bool backgroundExists = false;
for (const auto &bg : set.backgrounds) {
if (background == bg) {
backgroundExists = true;
break;
}
for (const rapidjson::Value &innerValue : value.GetArray()) {
if (!innerValue.IsString()) {
return false;
}
if (!backgroundExists) {
continue;
out.emplace_back(innerValue.GetString());
}
return true;
}
// Parse a single cheermote set (or "action") from the twitch api
inline bool ParseSingleCheermoteSet(JSONCheermoteSet &set,
const rapidjson::Value &action)
{
if (!action.IsObject()) {
return false;
}
if (!ReadValue(action, "prefix", set.prefix)) {
return false;
}
if (!ReadValue(action, "scales", set.scales)) {
return false;
}
if (!ReadValue(action, "backgrounds", set.backgrounds)) {
return false;
}
if (!ReadValue(action, "states", set.states)) {
return false;
}
if (!ReadValue(action, "type", set.type)) {
return false;
}
if (!ReadValue(action, "updated_at", set.updatedAt)) {
return false;
}
if (!ReadValue(action, "priority", set.priority)) {
return false;
}
// Tiers
if (!action.HasMember("tiers")) {
return false;
}
const auto &tiersValue = action["tiers"];
if (!tiersValue.IsArray()) {
return false;
}
for (const rapidjson::Value &tierValue : tiersValue.GetArray()) {
JSONCheermoteSet::CheermoteTier tier;
if (!tierValue.IsObject()) {
return false;
}
const rapidjson::Value &imageBackgroundStates =
imageBackgroundValue.value;
if (!imageBackgroundStates.IsObject()) {
continue;
if (!ReadValue(tierValue, "min_bits", tier.minBits)) {
return false;
}
// Read each key which represents a background
for (const auto &imageBackgroundState :
imageBackgroundStates.GetObject()) {
QString state = imageBackgroundState.name.GetString();
bool stateExists = false;
for (const auto &_state : set.states) {
if (state == _state) {
stateExists = true;
if (!ReadValue(tierValue, "id", tier.id)) {
return false;
}
if (!ReadValue(tierValue, "color", tier.color)) {
return false;
}
// Images
if (!tierValue.HasMember("images")) {
return false;
}
const auto &imagesValue = tierValue["images"];
if (!imagesValue.IsObject()) {
return false;
}
// Read images object
for (const auto &imageBackgroundValue : imagesValue.GetObject()) {
QString background = imageBackgroundValue.name.GetString();
bool backgroundExists = false;
for (const auto &bg : set.backgrounds) {
if (background == bg) {
backgroundExists = true;
break;
}
}
if (!stateExists) {
if (!backgroundExists) {
continue;
}
const rapidjson::Value &imageScalesValue =
imageBackgroundState.value;
if (!imageScalesValue.IsObject()) {
const rapidjson::Value &imageBackgroundStates =
imageBackgroundValue.value;
if (!imageBackgroundStates.IsObject()) {
continue;
}
// Read each key which represents a scale
for (const auto &imageScaleValue :
imageScalesValue.GetObject()) {
QString scale = imageScaleValue.name.GetString();
bool scaleExists = false;
for (const auto &_scale : set.scales) {
if (scale == _scale) {
scaleExists = true;
// Read each key which represents a background
for (const auto &imageBackgroundState :
imageBackgroundStates.GetObject()) {
QString state = imageBackgroundState.name.GetString();
bool stateExists = false;
for (const auto &_state : set.states) {
if (state == _state) {
stateExists = true;
break;
}
}
if (!scaleExists) {
if (!stateExists) {
continue;
}
const rapidjson::Value &imageScaleURLValue =
imageScaleValue.value;
if (!imageScaleURLValue.IsString()) {
const rapidjson::Value &imageScalesValue =
imageBackgroundState.value;
if (!imageScalesValue.IsObject()) {
continue;
}
QString url = imageScaleURLValue.GetString();
// Read each key which represents a scale
for (const auto &imageScaleValue :
imageScalesValue.GetObject()) {
QString scale = imageScaleValue.name.GetString();
bool scaleExists = false;
for (const auto &_scale : set.scales) {
if (scale == _scale) {
scaleExists = true;
break;
}
}
bool ok = false;
qreal scaleNumber = scale.toFloat(&ok);
if (!ok) {
continue;
if (!scaleExists) {
continue;
}
const rapidjson::Value &imageScaleURLValue =
imageScaleValue.value;
if (!imageScaleURLValue.IsString()) {
continue;
}
QString url = imageScaleURLValue.GetString();
bool ok = false;
qreal scaleNumber = scale.toFloat(&ok);
if (!ok) {
continue;
}
qreal chatterinoScale = 1 / scaleNumber;
auto image = Image::fromUrl({url}, chatterinoScale);
// TODO(pajlada): Fill in name and tooltip
tier.images[background][state][scale] = image;
}
qreal chatterinoScale = 1 / scaleNumber;
auto image = Image::fromUrl({url}, chatterinoScale);
// TODO(pajlada): Fill in name and tooltip
tier.images[background][state][scale] = image;
}
}
set.tiers.emplace_back(tier);
}
set.tiers.emplace_back(tier);
return true;
}
return true;
}
} // namespace
// Look through the results of
+33 -33
View File
@@ -34,43 +34,43 @@ struct TwitchUser {
namespace pajlada {
namespace Settings {
template <>
struct Deserialize<chatterino::TwitchUser> {
static chatterino::TwitchUser get(const rapidjson::Value &value,
bool *error = nullptr)
{
using namespace chatterino;
template <>
struct Deserialize<chatterino::TwitchUser> {
static chatterino::TwitchUser get(const rapidjson::Value &value,
bool *error = nullptr)
{
using namespace chatterino;
TwitchUser user;
TwitchUser user;
if (!value.IsObject()) {
PAJLADA_REPORT_ERROR(error)
PAJLADA_THROW_EXCEPTION(
"Deserialized rapidjson::Value is wrong type");
return user;
}
if (!rj::getSafe(value, "_id", user.id)) {
PAJLADA_REPORT_ERROR(error)
PAJLADA_THROW_EXCEPTION("Missing ID key");
return user;
}
if (!rj::getSafe(value, "name", user.name)) {
PAJLADA_REPORT_ERROR(error)
PAJLADA_THROW_EXCEPTION("Missing name key");
return user;
}
if (!rj::getSafe(value, "display_name", user.displayName)) {
PAJLADA_REPORT_ERROR(error)
PAJLADA_THROW_EXCEPTION("Missing display name key");
return user;
}
if (!value.IsObject()) {
PAJLADA_REPORT_ERROR(error)
PAJLADA_THROW_EXCEPTION(
"Deserialized rapidjson::Value is wrong type");
return user;
}
if (!rj::getSafe(value, "_id", user.id)) {
PAJLADA_REPORT_ERROR(error)
PAJLADA_THROW_EXCEPTION("Missing ID key");
return user;
}
if (!rj::getSafe(value, "name", user.name)) {
PAJLADA_REPORT_ERROR(error)
PAJLADA_THROW_EXCEPTION("Missing name key");
return user;
}
if (!rj::getSafe(value, "display_name", user.displayName)) {
PAJLADA_REPORT_ERROR(error)
PAJLADA_THROW_EXCEPTION("Missing display name key");
return user;
}
return user;
}
};
};
} // namespace Settings
} // namespace pajlada