refactor: DebugCount (#6753)

Reviewed-by: Rasmus Karlsson <rasmus.karlsson@pajlada.com>
Reviewed-by: Nerixyz <nerixdev@outlook.de>
This commit is contained in:
Mm2PL
2026-01-28 11:37:06 +01:00
committed by GitHub
parent b69ab9315f
commit 60ecf1a8d7
25 changed files with 198 additions and 129 deletions
+1
View File
@@ -101,6 +101,7 @@
- Dev: Updated prettier version to 3.8.1 and migrated away from using an unmaintained GH Action, instead relying on `npx`. (#6769)
- Dev: Updated `miniaudio` to 0.11.24. (#6754)
- Dev: Remove unused `reloadChannelAndSubscriberEmotes`. (#6756)
- Dev: Refactored `DebugCount`. (#6753)
- Dev: Moved `PluginMeta` to its own file. (#6757)
## 2.5.4
+3 -3
View File
@@ -48,7 +48,7 @@ void runCallback(bool concurrent, auto &&fn)
void loadUncached(std::shared_ptr<NetworkData> &&data)
{
DebugCount::increase("http request started");
DebugCount::increase(DebugObject::HTTPRequestStarted);
NetworkRequester requester;
auto *worker = new NetworkTask(std::move(data));
@@ -105,12 +105,12 @@ namespace chatterino {
NetworkData::NetworkData()
{
DebugCount::increase("NetworkData");
DebugCount::increase(DebugObject::NetworkData);
}
NetworkData::~NetworkData()
{
DebugCount::decrease("NetworkData");
DebugCount::decrease(DebugObject::NetworkData);
}
QString NetworkData::getHash()
+1
View File
@@ -6,6 +6,7 @@
#include "common/Common.hpp"
#include "common/network/NetworkCommon.hpp"
#include "util/DebugCount.hpp"
#include <QHttpMultiPart>
#include <QNetworkRequest>
+1 -1
View File
@@ -243,7 +243,7 @@ void NetworkTask::finished()
this->writeToCache(bytes);
}
DebugCount::increase("http request success");
DebugCount::increase(DebugObject::HTTPRequestSuccess);
this->logReply();
this->data_->emitSuccess({reply->error(), status, bytes});
this->data_->emitFinally();
+2 -4
View File
@@ -182,14 +182,12 @@ HTTPRequest::HTTPRequest(HTTPRequest::ConstructorAccessTag /*ignored*/,
NetworkRequest req)
: req_(std::move(req))
{
DebugCount::increase("lua::api::HTTPRequest");
DebugCount::increase(DebugObject::LuaHTTPRequest);
}
HTTPRequest::~HTTPRequest()
{
DebugCount::decrease("lua::api::HTTPRequest");
// We might leak a Lua function or two here if the request isn't executed
// but that's better than accessing a possibly invalid lua_State pointer.
DebugCount::decrease(DebugObject::LuaHTTPRequest);
}
QString HTTPRequest::to_string()
+2 -1
View File
@@ -6,6 +6,7 @@
#ifdef CHATTERINO_HAVE_PLUGINS
# include "common/network/NetworkRequest.hpp"
# include "controllers/plugins/LuaUtilities.hpp"
# include "util/DebugCount.hpp"
# include <sol/forward.hpp>
# include <sol/types.hpp>
@@ -34,7 +35,7 @@ class HTTPRequest : public std::enable_shared_from_this<HTTPRequest>
public:
HTTPRequest(HTTPRequest::ConstructorAccessTag, NetworkRequest req);
HTTPRequest(HTTPRequest &&other) = default;
HTTPRequest(HTTPRequest &&other) = default; // TODO: this breaks DebugCount
HTTPRequest &operator=(HTTPRequest &&) = default;
HTTPRequest &operator=(HTTPRequest &) = delete;
HTTPRequest(const HTTPRequest &other) = delete;
@@ -33,11 +33,6 @@ void HTTPResponse::createUserType(sol::table &c2)
HTTPResponse::HTTPResponse(NetworkResult res)
: result_(std::move(res))
{
DebugCount::increase("lua::api::HTTPResponse");
}
HTTPResponse::~HTTPResponse()
{
DebugCount::decrease("lua::api::HTTPResponse");
}
QByteArray HTTPResponse::data()
+1 -1
View File
@@ -31,7 +31,7 @@ public:
HTTPResponse &operator=(HTTPResponse &&) = default;
HTTPResponse &operator=(HTTPResponse &) = delete;
HTTPResponse(const HTTPResponse &other) = delete;
~HTTPResponse();
~HTTPResponse() = default;
private:
static void createUserType(sol::table &c2);
+17 -24
View File
@@ -36,7 +36,7 @@ namespace chatterino::detail {
Frames::Frames()
{
DebugCount::increase("images");
DebugCount::increase(DebugObject::Image);
}
Frames::Frames(QList<Frame> &&frames)
@@ -51,15 +51,15 @@ Frames::Frames(QList<Frame> &&frames)
return;
}
DebugCount::increase("images");
DebugCount::increase(DebugObject::Image);
if (!this->empty())
{
DebugCount::increase("loaded images");
DebugCount::increase(DebugObject::LoadedImage);
}
if (this->animated())
{
DebugCount::increase("animated images");
DebugCount::increase(DebugObject::AnimatedImage);
this->gifTimerConnection_ =
app->getEmotes()->getGIFTimer()->signal.connect([this] {
@@ -85,25 +85,25 @@ Frames::Frames(QList<Frame> &&frames)
this->processOffset();
}
DebugCount::increase("image bytes", this->memoryUsage());
DebugCount::increase("image bytes (ever loaded)", this->memoryUsage());
DebugCount::increase(DebugObject::BytesImageCurrent, this->memoryUsage());
DebugCount::increase(DebugObject::BytesImageLoaded, this->memoryUsage());
}
Frames::~Frames()
{
assertInGuiThread();
DebugCount::decrease("images");
DebugCount::decrease(DebugObject::Image);
if (!this->empty())
{
DebugCount::decrease("loaded images");
DebugCount::decrease(DebugObject::LoadedImage);
}
if (this->animated())
{
DebugCount::decrease("animated images");
DebugCount::decrease(DebugObject::AnimatedImage);
}
DebugCount::decrease("image bytes", this->memoryUsage());
DebugCount::increase("image bytes (ever unloaded)", this->memoryUsage());
DebugCount::decrease(DebugObject::BytesImageCurrent, this->memoryUsage());
DebugCount::increase(DebugObject::BytesImageUnloaded, this->memoryUsage());
this->gifTimerConnection_.disconnect();
}
@@ -156,10 +156,10 @@ void Frames::clear()
assertInGuiThread();
if (!this->empty())
{
DebugCount::decrease("loaded images");
DebugCount::decrease(DebugObject::LoadedImage);
}
DebugCount::decrease("image bytes", this->memoryUsage());
DebugCount::increase("image bytes (ever unloaded)", this->memoryUsage());
DebugCount::decrease(DebugObject::BytesImageCurrent, this->memoryUsage());
DebugCount::increase(DebugObject::BytesImageUnloaded, this->memoryUsage());
this->items_.clear();
this->index_ = 0;
@@ -608,13 +608,6 @@ ImageExpirationPool::ImageExpirationPool()
this->freeTimer_->start(
std::chrono::duration_cast<std::chrono::milliseconds>(
IMAGE_POOL_CLEANUP_INTERVAL));
// configure all debug counts used by images
DebugCount::configure("image bytes", DebugCount::Flag::DataSize);
DebugCount::configure("image bytes (ever loaded)",
DebugCount::Flag::DataSize);
DebugCount::configure("image bytes (ever unloaded)",
DebugCount::Flag::DataSize);
}
ImageExpirationPool &ImageExpirationPool::instance()
@@ -695,9 +688,9 @@ void ImageExpirationPool::freeOld()
qCDebug(chatterinoImage) << "freed frame data for" << numExpired << "/"
<< eligible << "eligible images";
# endif
DebugCount::set("last image gc: expired", numExpired);
DebugCount::set("last image gc: eligible", eligible);
DebugCount::set("last image gc: left after gc", this->allImages_.size());
DebugCount::set(DebugObject::LastImageGcExpired, numExpired);
DebugCount::set(DebugObject::LastImageGcEligible, eligible);
DebugCount::set(DebugObject::LastImageGcLeft, this->allImages_.size());
}
#endif
+1
View File
@@ -5,6 +5,7 @@
#pragma once
#include "common/Aliases.hpp"
#include "util/DebugCount.hpp"
#include <boost/variant.hpp>
#include <pajlada/signals/signal.hpp>
+2 -2
View File
@@ -25,12 +25,12 @@ using namespace literals;
Message::Message()
: parseTime(QTime::currentTime())
{
DebugCount::increase("messages");
DebugCount::increase(DebugObject::Message);
}
Message::~Message()
{
DebugCount::decrease("messages");
DebugCount::decrease(DebugObject::Message);
}
ScrollbarHighlight Message::getScrollBarHighlight() const
+1
View File
@@ -6,6 +6,7 @@
#include "messages/MessageFlag.hpp"
#include "providers/twitch/ChannelPointReward.hpp"
#include "util/DebugCount.hpp"
#include "util/QStringHash.hpp"
#include <QColor>
+2 -2
View File
@@ -55,12 +55,12 @@ QSizeF getBoundingBoxSize(const std::vector<ImagePtr> &images)
MessageElement::MessageElement(MessageElementFlags flags)
: flags_(flags)
{
DebugCount::increase("message elements");
DebugCount::increase(DebugObject::MessageElement);
}
MessageElement::~MessageElement()
{
DebugCount::decrease("message elements");
DebugCount::decrease(DebugObject::MessageElement);
}
MessageElement *MessageElement::setLink(const Link &link)
+1
View File
@@ -10,6 +10,7 @@
#include "messages/MessageColor.hpp"
#include "providers/links/LinkInfo.hpp"
#include "singletons/Fonts.hpp"
#include "util/DebugCount.hpp"
#include <magic_enum/magic_enum.hpp>
#include <pajlada/signals/signalholder.hpp>
+2 -2
View File
@@ -23,12 +23,12 @@ MessageThread::MessageThread(std::shared_ptr<const Message> rootMessage)
: rootMessageId_(rootMessage->id)
, rootMessage_(std::move(rootMessage))
{
DebugCount::increase("message threads");
DebugCount::increase(DebugObject::MessageThread);
}
MessageThread::~MessageThread()
{
DebugCount::decrease("message threads");
DebugCount::decrease(DebugObject::MessageThread);
}
void MessageThread::addToThread(const std::shared_ptr<const Message> &message)
+4 -4
View File
@@ -41,12 +41,12 @@ QColor blendColors(const QColor &base, const QColor &apply)
MessageLayout::MessageLayout(MessagePtr message)
: message_(std::move(message))
{
DebugCount::increase("message layout");
DebugCount::increase(DebugObject::MessageLayout);
}
MessageLayout::~MessageLayout()
{
DebugCount::decrease("message layout");
DebugCount::decrease(DebugObject::MessageLayout);
}
const Message *MessageLayout::getMessage()
@@ -359,7 +359,7 @@ QPixmap *MessageLayout::ensureBuffer(QPainter &painter, qreal width, bool clear)
}
this->bufferValid_ = false;
DebugCount::increase("message drawing buffers");
DebugCount::increase(DebugObject::MessageDrawingBuffer);
return this->buffer_.get();
}
@@ -487,7 +487,7 @@ void MessageLayout::deleteBuffer()
{
if (this->buffer_ != nullptr)
{
DebugCount::decrease("message drawing buffers");
DebugCount::decrease(DebugObject::MessageDrawingBuffer);
this->buffer_ = nullptr;
}
@@ -40,12 +40,12 @@ MessageLayoutElement::MessageLayoutElement(MessageElement &creator, QSizeF size)
: rect_(QPointF{}, size)
, creator_(creator)
{
DebugCount::increase("message layout elements");
DebugCount::increase(DebugObject::MessageLayoutElement);
}
MessageLayoutElement::~MessageLayoutElement()
{
DebugCount::decrease("message layout elements");
DebugCount::decrease(DebugObject::MessageLayoutElement);
}
MessageElement &MessageLayoutElement::getCreator() const
@@ -105,7 +105,7 @@ protected:
}
qCDebug(chatterinoLiveupdates) << "Subscribing to" << subscription;
DebugCount::increase("LiveUpdates subscriptions");
DebugCount::increase(DebugObject::LiveUpdatesSubscription);
QByteArray encoded =
static_cast<Derived *>(this)->encodeSubscription(subscription);
@@ -126,7 +126,7 @@ protected:
}
qCDebug(chatterinoLiveupdates) << "Unsubscribing from" << subscription;
DebugCount::decrease("LiveUpdates subscriptions");
DebugCount::decrease(DebugObject::LiveUpdatesSubscription);
QByteArray encoded =
static_cast<Derived *>(this)->encodeUnsubscription(subscription);
@@ -129,7 +129,7 @@ protected:
this->addClient();
this->pendingSubscriptions_.emplace_back(subscription);
DebugCount::increase("LiveUpdates subscription backlog");
DebugCount::increase(DebugObject::LiveUpdatesSubscriptionBacklog);
}
const std::unordered_map<size_t, std::shared_ptr<Client>> &clients() const
@@ -147,7 +147,7 @@ private:
{
assertInGuiThread();
DebugCount::increase("LiveUpdates connections");
DebugCount::increase(DebugObject::LiveUpdatesConnection);
this->addingClient_ = false;
this->diag.connectionsOpened.fetch_add(1, std::memory_order_acq_rel);
@@ -173,7 +173,7 @@ private:
this->pendingSubscriptions_.emplace_back(std::move(last));
break;
}
DebugCount::decrease("LiveUpdates subscription backlog");
DebugCount::decrease(DebugObject::LiveUpdatesSubscriptionBacklog);
pendingSubsToTake--;
}
@@ -200,7 +200,7 @@ private:
return;
}
DebugCount::decrease("LiveUpdates connections");
DebugCount::decrease(DebugObject::LiveUpdatesConnection);
qCDebug(chatterinoLiveupdates) << "Connection" << id << "closed";
auto subs = std::move(it->second->subscriptions_);
@@ -228,7 +228,7 @@ private:
qCWarning(chatterinoLiveupdates)
<< "Retrying after" << id << "failed";
auto nSubs = subs.size();
DebugCount::increase("LiveUpdates subscription backlog",
DebugCount::increase(DebugObject::LiveUpdatesSubscriptionBacklog,
static_cast<int64_t>(nSubs));
this->pendingSubscriptions_.insert(
this->pendingSubscriptions_.end(),
+33 -51
View File
@@ -5,11 +5,13 @@
#include "util/DebugCount.hpp"
#include "common/UniqueAccess.hpp"
#include "util/QMagicEnum.hpp"
#include <magic_enum/magic_enum.hpp>
#include <QLocale>
#include <QStringBuilder>
#include <map>
#include <array>
namespace {
@@ -17,74 +19,51 @@ using namespace chatterino;
struct Count {
int64_t value = 0;
DebugCount::Flags flags = DebugCount::Flag::None;
};
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
UniqueAccess<std::map<QString, Count>> COUNTS;
UniqueAccess<std::array<Count, static_cast<size_t>(DebugObject::Count)>> COUNTS;
constexpr bool isBytes(DebugObject target)
{
switch (target)
{
default:
return false;
case DebugObject::BytesImageCurrent:
case DebugObject::BytesImageLoaded:
case DebugObject::BytesImageUnloaded:
return true;
}
}
} // namespace
namespace chatterino {
void DebugCount::configure(const QString &name, Flags flags)
void DebugCount::set(DebugObject target, int64_t amount)
{
auto counts = COUNTS.access();
auto it = counts->find(name);
if (it == counts->end())
{
counts->emplace(name, Count{.flags = flags});
}
else
{
it->second.flags = flags;
}
auto &it = counts->at(static_cast<size_t>(target));
it.value = amount;
}
void DebugCount::set(const QString &name, const int64_t &amount)
void DebugCount::increase(DebugObject target, int64_t amount)
{
auto counts = COUNTS.access();
auto it = counts->find(name);
if (it == counts->end())
{
counts->emplace(name, Count{amount});
}
else
{
it->second.value = amount;
}
auto &it = counts->at(static_cast<size_t>(target));
it.value += amount;
}
void DebugCount::increase(const QString &name, const int64_t &amount)
void DebugCount::decrease(DebugObject target, int64_t amount)
{
auto counts = COUNTS.access();
auto it = counts->find(name);
if (it == counts->end())
{
counts->emplace(name, Count{amount});
}
else
{
it->second.value += amount;
}
}
void DebugCount::decrease(const QString &name, const int64_t &amount)
{
auto counts = COUNTS.access();
auto it = counts->find(name);
if (it == counts->end())
{
counts->emplace(name, Count{-amount});
}
else
{
it->second.value -= amount;
}
auto &it = counts->at(static_cast<size_t>(target));
it.value -= amount;
}
QString DebugCount::getDebugText()
@@ -94,10 +73,12 @@ QString DebugCount::getDebugText()
auto counts = COUNTS.access();
QString text;
for (const auto &[key, count] : *counts)
for (size_t key = 0; key < static_cast<size_t>(DebugObject::Count); key++)
{
auto &count = counts->at(key);
QString formatted;
if (count.flags.has(Flag::DataSize))
if (isBytes(static_cast<DebugObject>(key)))
{
formatted = locale.formattedDataSize(count.value);
}
@@ -106,7 +87,8 @@ QString DebugCount::getDebugText()
formatted = locale.toString(static_cast<qlonglong>(count.value));
}
text += key % ": " % formatted % '\n';
text += qmagicenum::enumName(static_cast<DebugObject>(key)) % ": " %
formatted % '\n';
}
return text;
}
+109 -16
View File
@@ -6,37 +6,130 @@
#include "common/FlagsEnum.hpp"
#include <magic_enum/magic_enum.hpp>
#include <QString>
#include <cstddef>
namespace chatterino {
enum class DebugObject : size_t {
// windowing
AttachedWindow,
BaseWindow,
// live updates
LiveUpdatesSubscription,
LiveUpdatesSubscriptionBacklog,
LiveUpdatesConnection,
// http/other networking
HTTPRequestStarted,
HTTPRequestSuccess,
NetworkData,
// images
Image,
LoadedImage,
AnimatedImage,
BytesImageCurrent,
BytesImageLoaded,
BytesImageUnloaded,
LastImageGcExpired,
LastImageGcEligible,
LastImageGcLeft,
// Lua
LuaHTTPResponse,
LuaHTTPRequest,
// Messages
MessageDrawingBuffer,
MessageElement,
MessageLayout,
MessageLayoutElement,
MessageThread,
Message,
Count,
};
class DebugCount
{
public:
enum class Flag : uint16_t {
None = 0,
/// The value is a data size in bytes
DataSize = 1 << 0,
};
using Flags = FlagsEnum<Flag>;
static void set(DebugObject target, int64_t amount);
static void configure(const QString &name, Flags flags);
static void set(const QString &name, const int64_t &amount);
static void increase(const QString &name, const int64_t &amount);
static void increase(const QString &name)
static void increase(DebugObject target, int64_t amount);
static void increase(DebugObject target)
{
DebugCount::increase(name, 1);
DebugCount::increase(target, 1);
}
static void decrease(const QString &name, const int64_t &amount);
static void decrease(const QString &name)
static void decrease(DebugObject target, int64_t amount);
static void decrease(DebugObject target)
{
DebugCount::decrease(name, 1);
DebugCount::decrease(target, 1);
}
static QString getDebugText();
};
} // namespace chatterino
template <>
constexpr magic_enum::customize::customize_t
magic_enum::customize::enum_name<chatterino::DebugObject>(
chatterino::DebugObject value) noexcept
{
using chatterino::DebugObject;
switch (value)
{
// class names
case chatterino::DebugObject::AttachedWindow:
case chatterino::DebugObject::BaseWindow:
case chatterino::DebugObject::NetworkData:
case chatterino::DebugObject::MessageElement:
case chatterino::DebugObject::MessageLayout:
case chatterino::DebugObject::MessageLayoutElement:
case chatterino::DebugObject::MessageThread:
case chatterino::DebugObject::Message:
default:
return default_tag;
case chatterino::DebugObject::AnimatedImage:
return "animated images";
case chatterino::DebugObject::LiveUpdatesSubscription:
return "LiveUpdates subscriptions";
case chatterino::DebugObject::LiveUpdatesSubscriptionBacklog:
return "LiveUpdates subscription backlog";
case chatterino::DebugObject::LiveUpdatesConnection:
return "LiveUpdates connections";
case chatterino::DebugObject::HTTPRequestStarted:
return "http requests started";
case chatterino::DebugObject::HTTPRequestSuccess:
return "http requests succeeded";
case chatterino::DebugObject::Image:
return "images";
case chatterino::DebugObject::LoadedImage:
return "loaded images";
case chatterino::DebugObject::BytesImageCurrent:
return "image bytes";
case chatterino::DebugObject::BytesImageLoaded:
return "image bytes (ever loaded)";
case chatterino::DebugObject::BytesImageUnloaded:
return "image bytes (ever unloaded)";
case chatterino::DebugObject::LastImageGcExpired:
return "last image gc: expired";
case chatterino::DebugObject::LastImageGcEligible:
return "last image gc: eligible";
case chatterino::DebugObject::LastImageGcLeft:
return "last image gc: left after gc";
case chatterino::DebugObject::LuaHTTPResponse:
return "lua::api::HTTPResponse";
case chatterino::DebugObject::LuaHTTPRequest:
return "lua::api::HTTPRequest";
case chatterino::DebugObject::MessageDrawingBuffer:
return "message drawing buffers";
}
}
+2 -2
View File
@@ -61,7 +61,7 @@ AttachedWindow::AttachedWindow(void *_target)
split->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::MinimumExpanding);
layout->addWidget(split);
DebugCount::increase("attached window");
DebugCount::increase(DebugObject::AttachedWindow);
}
AttachedWindow::~AttachedWindow()
@@ -75,7 +75,7 @@ AttachedWindow::~AttachedWindow()
}
}
DebugCount::decrease("attached window");
DebugCount::decrease(DebugObject::AttachedWindow);
}
AttachedWindow *AttachedWindow::get(void *target, const GetArgs &args)
+2 -2
View File
@@ -272,12 +272,12 @@ BaseWindow::BaseWindow(FlagsEnum<Flags> _flags, QWidget *parent)
#endif
this->themeChangedEvent();
DebugCount::increase("BaseWindow");
DebugCount::increase(DebugObject::BaseWindow);
}
BaseWindow::~BaseWindow()
{
DebugCount::decrease("BaseWindow");
DebugCount::decrease(DebugObject::BaseWindow);
}
void BaseWindow::setInitialBounds(QRect bounds, widgets::BoundsChecking mode)
+1
View File
@@ -6,6 +6,7 @@
#include "Application.hpp"
#include "messages/layouts/MessageLayout.hpp"
#include "messages/layouts/MessageLayoutElement.hpp"
#include "messages/MessageElement.hpp"
#include "messages/Selection.hpp"
#include "providers/colors/ColorProvider.hpp"
+1
View File
@@ -7,6 +7,7 @@
#include "Application.hpp"
#include "controllers/accounts/AccountController.hpp"
#include "messages/layouts/MessageLayoutContext.hpp"
#include "messages/layouts/MessageLayoutElement.hpp"
#include "messages/MessageBuilder.hpp"
#include "messages/MessageElement.hpp"
#include "mocks/BaseApplication.hpp"