diff --git a/chatterino.pro b/chatterino.pro index 18d67f250..99a0d7259 100644 --- a/chatterino.pro +++ b/chatterino.pro @@ -266,7 +266,8 @@ HEADERS += \ src/widgets/streamview.hpp \ src/util/networkrequest.hpp \ src/util/networkworker.hpp \ - src/util/networkrequester.hpp + src/util/networkrequester.hpp \ + src/util/flagsenum.h RESOURCES += \ resources/resources.qrc diff --git a/src/channel.hpp b/src/channel.hpp index ac06a2a04..9581ba5dc 100644 --- a/src/channel.hpp +++ b/src/channel.hpp @@ -16,7 +16,7 @@ namespace chatterino { namespace messages { -class Message; +struct Message; } class Channel : public std::enable_shared_from_this diff --git a/src/logging/loggingchannel.cpp b/src/logging/loggingchannel.cpp index 95df696c1..249fbd5d5 100644 --- a/src/logging/loggingchannel.cpp +++ b/src/logging/loggingchannel.cpp @@ -39,7 +39,7 @@ void Channel::append(std::shared_ptr message) str.append("] "); str.append(message->loginName); str.append(": "); - str.append(message->getSearchText()); + str.append(message->searchText); str.append('\n'); this->appendLine(str); } diff --git a/src/messages/layouts/messagelayout.cpp b/src/messages/layouts/messagelayout.cpp index 489dc1724..39bc9c420 100644 --- a/src/messages/layouts/messagelayout.cpp +++ b/src/messages/layouts/messagelayout.cpp @@ -22,7 +22,7 @@ MessageLayout::MessageLayout(MessagePtr _message) : message(_message) , buffer(nullptr) { - if (_message->hasFlags(Message::Collapsed)) { + if (_message->flags & Message::Collapsed) { this->addFlags(MessageLayout::Collapsed); } } @@ -167,7 +167,7 @@ void MessageLayout::paint(QPainter &painter, int y, int messageIndex, Selection painter.drawPixmap(0, y, this->container.width, this->container.getHeight(), *pixmap); // draw disabled - if (this->message->hasFlags(Message::Disabled)) { + if (this->message->flags & Message::Disabled) { painter.fillRect(0, y, pixmap->width(), pixmap->height(), themeManager.messages.disabled); } @@ -186,7 +186,7 @@ void MessageLayout::updateBuffer(QPixmap *buffer, int messageIndex, Selection &s painter.setRenderHint(QPainter::SmoothPixmapTransform); // draw background - painter.fillRect(buffer->rect(), this->message->hasFlags(Message::Highlighted) + painter.fillRect(buffer->rect(), this->message->flags & Message::Highlighted ? themeManager.messages.backgrounds.highlighted : themeManager.messages.backgrounds.regular); diff --git a/src/messages/layouts/messagelayout.hpp b/src/messages/layouts/messagelayout.hpp index 8772e3764..792876513 100644 --- a/src/messages/layouts/messagelayout.hpp +++ b/src/messages/layouts/messagelayout.hpp @@ -15,11 +15,11 @@ namespace chatterino { namespace messages { namespace layouts { -class MessageLayout; +struct MessageLayout; typedef std::shared_ptr MessageLayoutPtr; typedef uint8_t MessageLayoutFlagsType; -class MessageLayout : boost::noncopyable +struct MessageLayout : boost::noncopyable { public: enum Flags : MessageLayoutFlagsType { Collapsed, RequiresBufferUpdate, RequiresLayout }; diff --git a/src/messages/layouts/messagelayoutcontainer.hpp b/src/messages/layouts/messagelayoutcontainer.hpp index 501ff06fd..d39e53fc1 100644 --- a/src/messages/layouts/messagelayoutcontainer.hpp +++ b/src/messages/layouts/messagelayoutcontainer.hpp @@ -14,7 +14,7 @@ namespace chatterino { namespace messages { namespace layouts { -class MessageLayoutElement; +struct MessageLayoutElement; struct Margin { int top; @@ -41,7 +41,7 @@ struct Margin { } }; -class MessageLayoutContainer +struct MessageLayoutContainer { public: MessageLayoutContainer(); diff --git a/src/messages/layouts/messagelayoutelement.hpp b/src/messages/layouts/messagelayoutelement.hpp index 38f8ae3a6..38b981722 100644 --- a/src/messages/layouts/messagelayoutelement.hpp +++ b/src/messages/layouts/messagelayoutelement.hpp @@ -15,12 +15,12 @@ class QPainter; namespace chatterino { namespace messages { -class MessageElement; +struct MessageElement; class Image; namespace layouts { -class MessageLayoutElement : boost::noncopyable +struct MessageLayoutElement : boost::noncopyable { public: MessageLayoutElement(MessageElement &creator, const QSize &size); diff --git a/src/messages/message.cpp b/src/messages/message.cpp index 7049a4ce6..2e95b6fad 100644 --- a/src/messages/message.cpp +++ b/src/messages/message.cpp @@ -6,8 +6,6 @@ typedef chatterino::widgets::ScrollbarHighlight SBHighlight; namespace chatterino { namespace messages { - -// elements void Message::addElement(MessageElement *element) { this->elements.push_back(std::unique_ptr(element)); @@ -18,64 +16,9 @@ const std::vector> &Message::getElements() const return this->elements; } -// Flags -Message::MessageFlags Message::getFlags() const -{ - return this->flags; -} - -bool Message::hasFlags(MessageFlags _flags) const -{ - return this->flags & _flags; -} - -// void Message::setFlags(MessageFlags _flags) -//{ -// this->flags = flags; -//} - -void Message::addFlags(MessageFlags _flags) -{ - this->flags = (MessageFlags)((MessageFlagsType)this->flags | (MessageFlagsType)_flags); -} - -void Message::removeFlags(MessageFlags _flags) -{ - this->flags = (MessageFlags)((MessageFlagsType)this->flags & ~((MessageFlagsType)_flags)); -} - -// Parse Time -const QTime &Message::getParseTime() const -{ - return this->parseTime; -} - -// Id -const QString &Message::getId() const -{ - return this->id; -} - -void Message::setId(const QString &_id) -{ - this->id = _id; -} - -// Search -const QString &Message::getSearchText() const -{ - return this->searchText; -} - -void Message::setSearchText(const QString &value) -{ - this->searchText = value; -} - -// Highlight SBHighlight Message::getScrollBarHighlight() const { - if (this->hasFlags(Message::Highlighted)) { + if (this->flags & Message::Highlighted) { return SBHighlight(SBHighlight::Highlight); } return SBHighlight(); @@ -88,8 +31,8 @@ MessagePtr Message::createSystemMessage(const QString &text) message->addElement(new TimestampElement(QTime::currentTime())); message->addElement(new TextElement(text, MessageElement::Text, MessageColor::System)); - message->addFlags(Message::System); - message->setSearchText(text); + message->flags &= Message::System; + message->searchText = text; return MessagePtr(message); } @@ -129,7 +72,7 @@ MessagePtr Message::createTimeoutMessage(const QString &username, const QString } MessagePtr message = Message::createSystemMessage(text); - message->addFlags(Message::Timeout); + message->flags &= Message::Timeout; message->timeoutUser = username; return message; } diff --git a/src/messages/message.hpp b/src/messages/message.hpp index 1fa4b3ea0..d33be6634 100644 --- a/src/messages/message.hpp +++ b/src/messages/message.hpp @@ -1,6 +1,7 @@ #pragma once #include "messages/messageelement.hpp" +#include "util/flagsenum.h" #include "widgets/helper/scrollbarhighlight.hpp" #include @@ -11,15 +12,8 @@ namespace chatterino { namespace messages { -class Message; - -typedef std::shared_ptr MessagePtr; -typedef uint16_t MessageFlagsType; - -class Message -{ -public: - enum MessageFlags : MessageFlagsType { +struct Message { + enum MessageFlags : uint16_t { None = 0, System = (1 << 0), Timeout = (1 << 1), @@ -32,60 +26,33 @@ public: DisconnectedMessage = (1 << 8), }; - // Elements + util::FlagsEnum flags; + QTime parseTime; + QString id; + QString searchText; + QString loginName; + QString displayName; + QString localizedName; + QString timeoutUser; + // Messages should not be added after the message is done initializing. void addElement(MessageElement *element); const std::vector> &getElements() const; - // Message flags - MessageFlags getFlags() const; - bool hasFlags(MessageFlags flags) const; - // void setFlags(MessageFlags flags); - void addFlags(MessageFlags flags); - void removeFlags(MessageFlags flags); - - // Parse Time - const QTime &getParseTime() const; - - // Id - const QString &getId() const; - void setId(const QString &id); - - // Searching - const QString &getSearchText() const; - void setSearchText(const QString &value); - // Scrollbar widgets::ScrollbarHighlight getScrollBarHighlight() const; - // Usernames - QString loginName; - QString displayName; - QString localizedName; - - // Timeouts - const QString &getTimeoutUser(const QString &value) const; - void setTimeoutUser(); - - // Static - static MessagePtr createSystemMessage(const QString &text); - - static MessagePtr createTimeoutMessage(const QString &username, - const QString &durationInSeconds, const QString &reason, - bool multipleTimes); - private: - static QRegularExpression *cheerRegex; - - MessageFlags flags = MessageFlags::None; - QString timeoutUser; - bool collapsedDefault = false; - QTime parseTime; - mutable QString searchText; - QString id = ""; - std::vector> elements; + +public: + static std::shared_ptr createSystemMessage(const QString &text); + + static std::shared_ptr createTimeoutMessage(const QString &username, + const QString &durationInSeconds, + const QString &reason, bool multipleTimes); }; +typedef std::shared_ptr MessagePtr; } // namespace messages } // namespace chatterino diff --git a/src/messages/messagebuilder.cpp b/src/messages/messagebuilder.cpp index 4c34300c6..2116ac76e 100644 --- a/src/messages/messagebuilder.cpp +++ b/src/messages/messagebuilder.cpp @@ -31,9 +31,9 @@ void MessageBuilder::appendTimestamp() void MessageBuilder::setHighlight(bool value) { if (value) { - this->message->addFlags(Message::Highlighted); + this->message->flags |= Message::Highlighted; } else { - this->message->removeFlags(Message::Highlighted); + this->message->flags &= ~Message::Highlighted; } } diff --git a/src/messages/messagebuilder.hpp b/src/messages/messagebuilder.hpp index 43bc9f87b..2965cc0c3 100644 --- a/src/messages/messagebuilder.hpp +++ b/src/messages/messagebuilder.hpp @@ -9,7 +9,7 @@ namespace chatterino { namespace messages { -class MessageBuilder +struct MessageBuilder { public: MessageBuilder(); diff --git a/src/messages/messagecolor.hpp b/src/messages/messagecolor.hpp index ba07f2f9b..0e7b54af3 100644 --- a/src/messages/messagecolor.hpp +++ b/src/messages/messagecolor.hpp @@ -7,7 +7,7 @@ namespace chatterino { namespace messages { -class MessageColor +struct MessageColor { public: enum Type { Custom, Text, Link, System }; diff --git a/src/messages/messageelement.hpp b/src/messages/messageelement.hpp index dd3e7c482..ab8e36d82 100644 --- a/src/messages/messageelement.hpp +++ b/src/messages/messageelement.hpp @@ -20,12 +20,12 @@ struct EmoteData; } namespace messages { namespace layouts { -class MessageLayoutContainer; +struct MessageLayoutContainer; } using namespace chatterino::messages::layouts; -class MessageElement : boost::noncopyable +struct MessageElement : boost::noncopyable { public: enum Flags : uint32_t { diff --git a/src/singletons/helper/ircmessagehandler.cpp b/src/singletons/helper/ircmessagehandler.cpp index 9d169a92b..a74e9fda3 100644 --- a/src/singletons/helper/ircmessagehandler.cpp +++ b/src/singletons/helper/ircmessagehandler.cpp @@ -97,7 +97,7 @@ void IrcMessageHandler::handleClearChatMessage(Communi::IrcMessage *message) int snapshotLength = snapshot.getLength(); for (int i = std::max(0, snapshotLength - 20); i < snapshotLength; i++) { - if (snapshot[i]->hasFlags(Message::Timeout) && snapshot[i]->loginName == username) { + if (snapshot[i]->flags & Message::Timeout && snapshot[i]->loginName == username) { MessagePtr replacement( Message::createTimeoutMessage(username, durationInSeconds, reason, true)); c->replaceMessage(snapshot[i], replacement); @@ -112,8 +112,8 @@ void IrcMessageHandler::handleClearChatMessage(Communi::IrcMessage *message) // disable the messages from the user for (int i = 0; i < snapshotLength; i++) { - if (!snapshot[i]->hasFlags(Message::Timeout) && snapshot[i]->loginName == username) { - snapshot[i]->addFlags(Message::Disabled); + if (!(snapshot[i]->flags & Message::Timeout) && snapshot[i]->loginName == username) { + snapshot[i]->flags &= Message::Disabled; } } diff --git a/src/singletons/ircmanager.cpp b/src/singletons/ircmanager.cpp index d14530765..4f5573be8 100644 --- a/src/singletons/ircmanager.cpp +++ b/src/singletons/ircmanager.cpp @@ -381,29 +381,31 @@ void IrcManager::removeIgnoredUser(QString const &username) void IrcManager::onConnected() { - MessagePtr msg = Message::createSystemMessage("connected to chat"); - MessagePtr remsg = Message::createSystemMessage("reconnected to chat"); + MessagePtr connMsg = Message::createSystemMessage("connected to chat"); + MessagePtr reconnMsg = Message::createSystemMessage("reconnected to chat"); - this->channelManager.doOnAll([msg, remsg](SharedChannel channel) { + this->channelManager.doOnAll([connMsg, reconnMsg](SharedChannel channel) { assert(channel); LimitedQueueSnapshot snapshot = channel->getMessageSnapshot(); - if (snapshot.getLength() > 0 && - snapshot[snapshot.getLength() - 1]->hasFlags(Message::DisconnectedMessage)) // - { - channel->replaceMessage(snapshot[snapshot.getLength() - 1], remsg); + bool replaceMessage = + snapshot.getLength() > 0 && + snapshot[snapshot.getLength() - 1]->flags & Message::DisconnectedMessage; + + if (replaceMessage) { + channel->replaceMessage(snapshot[snapshot.getLength() - 1], reconnMsg); return; } - channel->addMessage(msg); + channel->addMessage(connMsg); }); } void IrcManager::onDisconnected() { MessagePtr msg = Message::createSystemMessage("disconnected from chat"); - msg->addFlags(Message::DisconnectedMessage); + msg->flags &= Message::DisconnectedMessage; this->channelManager.doOnAll([msg](SharedChannel channel) { assert(channel); diff --git a/src/twitch/twitchmessagebuilder.cpp b/src/twitch/twitchmessagebuilder.cpp index e99a0db33..36cffbb8c 100644 --- a/src/twitch/twitchmessagebuilder.cpp +++ b/src/twitch/twitchmessagebuilder.cpp @@ -188,7 +188,7 @@ MessagePtr TwitchMessageBuilder::parse() i++; } - this->message->setSearchText(this->userName + ": " + this->originalMessage); + this->message->searchText = this->userName + ": " + this->originalMessage; return this->getMessage(); } @@ -400,7 +400,7 @@ void TwitchMessageBuilder::parseHighlights() } if (doHighlight) { - this->message->addFlags(Message::Highlighted); + this->message->flags &= Message::Highlighted; } } } diff --git a/src/util/flagsenum.h b/src/util/flagsenum.h new file mode 100644 index 000000000..d8e4c2988 --- /dev/null +++ b/src/util/flagsenum.h @@ -0,0 +1,55 @@ +#pragma once + +#include + +namespace chatterino { +namespace util { + +template ::value>::type, + typename Q = std::underlying_type::type> +class FlagsEnum +{ +public: + FlagsEnum() + : value((T)0) + { + } + + FlagsEnum(T _value) + : value(_value) + { + } + + inline T operator~() const + { + return (T) ~(Q)this->value; + } + inline T operator|(Q a) const + { + return (T)((Q)a | (Q)this->value); + } + inline T operator&(Q a) const + { + return (T)((Q)a & (Q)this->value); + } + inline T operator^(Q a) const + { + return (T)((Q)a ^ (Q)this->value); + } + inline T &operator|=(const Q &a) + { + return (T &)((Q &)a |= (Q)this->value); + } + inline T &operator&=(const Q &a) + { + return (T &)((Q &)a &= (Q)this->value); + } + inline T &operator^=(const Q &a) + { + return (T &)((Q &)a ^= (Q)this->value); + } + + T value; +}; +} // namespace util +} // namespace chatterino diff --git a/src/widgets/emotepopup.cpp b/src/widgets/emotepopup.cpp index 8e8ee1118..0998120ea 100644 --- a/src/widgets/emotepopup.cpp +++ b/src/widgets/emotepopup.cpp @@ -48,13 +48,13 @@ void EmotePopup::loadChannel(SharedChannel _channel) builder1.appendElement(new TextElement(title, MessageElement::Text)); - builder1.getMessage()->addFlags(Message::Centered); + builder1.getMessage()->flags &= Message::Centered; emoteChannel->addMessage(builder1.getMessage()); // EMOTES messages::MessageBuilder builder2; - builder2.getMessage()->addFlags(Message::Centered); - builder2.getMessage()->addFlags(Message::DisableCompactEmotes); + builder2.getMessage()->flags &= Message::Centered; + builder2.getMessage()->flags &= Message::DisableCompactEmotes; map.each([&](const QString &key, const util::EmoteData &value) { builder2.appendElement((new EmoteElement(value, MessageElement::Flags::AlwaysShow)) // @@ -87,13 +87,13 @@ void EmotePopup::loadEmojis() messages::MessageBuilder builder1; builder1.appendElement(new TextElement("emojis", MessageElement::Text)); - builder1.getMessage()->addFlags(Message::Centered); + builder1.getMessage()->flags &= Message::Centered; emojiChannel->addMessage(builder1.getMessage()); // emojis messages::MessageBuilder builder; - builder.getMessage()->addFlags(Message::Centered); - builder.getMessage()->addFlags(Message::DisableCompactEmotes); + builder.getMessage()->flags &= Message::Centered; + builder.getMessage()->flags &= Message::DisableCompactEmotes; emojis.each([this, &builder](const QString &key, const util::EmoteData &value) { builder.appendElement((new EmoteElement(value, MessageElement::Flags::AlwaysShow)) // diff --git a/src/widgets/helper/channelview.cpp b/src/widgets/helper/channelview.cpp index 586415d86..c34bf4955 100644 --- a/src/widgets/helper/channelview.cpp +++ b/src/widgets/helper/channelview.cpp @@ -314,7 +314,7 @@ void ChannelView::setChannel(SharedChannel newChannel) } } - if (!message->hasFlags(Message::DoNotTriggerNotification)) { + if (message->flags & ~Message::DoNotTriggerNotification) { this->highlightedMessageReceived.invoke(); } diff --git a/src/widgets/helper/searchpopup.cpp b/src/widgets/helper/searchpopup.cpp index 048f00a5a..f5ae9b5e4 100644 --- a/src/widgets/helper/searchpopup.cpp +++ b/src/widgets/helper/searchpopup.cpp @@ -75,8 +75,8 @@ void SearchPopup::performSearch() for (size_t i = 0; i < this->snapshot.getLength(); i++) { messages::MessagePtr message = this->snapshot[i]; - if (text.isEmpty() || message->getSearchText().indexOf(this->searchInput->text(), 0, - Qt::CaseInsensitive) != -1) { + if (text.isEmpty() || + message->searchText.indexOf(this->searchInput->text(), 0, Qt::CaseInsensitive) != -1) { channel->addMessage(message); } }