Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: debug count and popup #4921

Merged
merged 10 commits into from
Oct 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
- Dev: Replace `boost::optional` with `std::optional`. (#4877)
- Dev: Improve performance by reducing repaints caused by selections. (#4889)
- Dev: Removed direct dependency on Qt 5 compatibility module. (#4906)
- Dev: Refactor `DebugCount` and add copy button to debug popup. (#4921)

## 2.4.6

Expand Down
9 changes: 8 additions & 1 deletion src/messages/Image.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ namespace detail {
{
auto sz = frame.image.size();
auto area = sz.width() * sz.height();
auto memory = area * frame.image.depth();
auto memory = area * frame.image.depth() / 8;

usage += memory;
}
Expand Down Expand Up @@ -608,6 +608,13 @@ 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()
Expand Down
111 changes: 109 additions & 2 deletions src/util/DebugCount.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,114 @@
#include "DebugCount.hpp"
#include "util/DebugCount.hpp"

#include "common/UniqueAccess.hpp"

#include <QLocale>
#include <QStringBuilder>

#include <map>

namespace {

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;

} // namespace

namespace chatterino {

UniqueAccess<QMap<QString, int64_t>> DebugCount::counts_;
void DebugCount::configure(const QString &name, Flags flags)
{
auto counts = COUNTS.access();

auto it = counts->find(name);
if (it == counts->end())
{
counts->emplace(name, Count{.flags = flags});
}
else
{
it->second.flags = flags;
}
}

void DebugCount::set(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;
}
}

void DebugCount::increase(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;
}
}

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;
}
}

QString DebugCount::getDebugText()
{
#if QT_VERSION > QT_VERSION_CHECK(5, 13, 0)
static const QLocale locale(QLocale::English);
#else
static QLocale locale(QLocale::English);
#endif

auto counts = COUNTS.access();

QString text;
for (const auto &[key, count] : *counts)
{
QString formatted;
if (count.flags.has(Flag::DataSize))
{
formatted = locale.formattedDataSize(count.value);
}
else
{
formatted = locale.toString(static_cast<qlonglong>(count.value));
}

text += key % ": " % formatted % '\n';
}
return text;
}

} // namespace chatterino
103 changes: 15 additions & 88 deletions src/util/DebugCount.hpp
Original file line number Diff line number Diff line change
@@ -1,111 +1,38 @@
#pragma once

#include "common/UniqueAccess.hpp"
#include "common/FlagsEnum.hpp"

#include <QMap>
#include <QString>

#include <mutex>
#include <typeinfo>

namespace chatterino {

class DebugCount
{
public:
static void increase(const QString &name)
{
auto counts = counts_.access();

auto it = counts->find(name);
if (it == counts->end())
{
counts->insert(name, 1);
}
else
{
reinterpret_cast<int64_t &>(it.value())++;
}
}
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(const QString &name, const int64_t &amount)
{
auto counts = counts_.access();
static void configure(const QString &name, Flags flags);

auto it = counts->find(name);
if (it == counts->end())
{
counts->insert(name, amount);
}
else
{
reinterpret_cast<int64_t &>(it.value()) = amount;
}
}
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, const int64_t &amount);
static void increase(const QString &name)
{
auto counts = counts_.access();

auto it = counts->find(name);
if (it == counts->end())
{
counts->insert(name, amount);
}
else
{
reinterpret_cast<int64_t &>(it.value()) += amount;
}
DebugCount::increase(name, 1);
}

static void decrease(const QString &name, const int64_t &amount);
static void decrease(const QString &name)
{
auto counts = counts_.access();

auto it = counts->find(name);
if (it == counts->end())
{
counts->insert(name, -1);
}
else
{
reinterpret_cast<int64_t &>(it.value())--;
}
}
static void decrease(const QString &name, const int64_t &amount)
{
auto counts = counts_.access();

auto it = counts->find(name);
if (it == counts->end())
{
counts->insert(name, -amount);
}
else
{
reinterpret_cast<int64_t &>(it.value()) -= amount;
}
}

static QString getDebugText()
{
auto counts = counts_.access();

QString text;
for (auto it = counts->begin(); it != counts->end(); it++)
{
text += it.key() + ": " + QString::number(it.value()) + "\n";
}
return text;
}

QString toString()
{
return "";
DebugCount::decrease(name, 1);
}

private:
static UniqueAccess<QMap<QString, int64_t>> counts_;
static QString getDebugText();
};

} // namespace chatterino
21 changes: 16 additions & 5 deletions src/widgets/helper/DebugPopup.cpp
Original file line number Diff line number Diff line change
@@ -1,29 +1,40 @@
#include "DebugPopup.hpp"
#include "widgets/helper/DebugPopup.hpp"

#include "common/Literals.hpp"
#include "util/Clipboard.hpp"
#include "util/DebugCount.hpp"

#include <QFontDatabase>
#include <QHBoxLayout>
#include <QLabel>
#include <QPushButton>
#include <QTimer>
#include <QVBoxLayout>

namespace chatterino {

using namespace literals;

DebugPopup::DebugPopup()
{
auto *layout = new QHBoxLayout(this);
auto *layout = new QVBoxLayout(this);
auto *text = new QLabel(this);
auto *timer = new QTimer(this);
auto *copyButton = new QPushButton(u"&Copy"_s);

timer->setInterval(300);
QObject::connect(timer, &QTimer::timeout, [text] {
text->setText(DebugCount::getDebugText());
});
timer->start();
timer->start(300);
text->setText(DebugCount::getDebugText());

text->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont));

layout->addWidget(text);
layout->addWidget(copyButton, 1);

QObject::connect(copyButton, &QPushButton::clicked, this, [text] {
crossPlatformCopy(text->text());
});
}

} // namespace chatterino
Loading