Remove QObjectRef in favor of QPointer (#4666)

* replace usage of QObjectRef with QPointer

* delete QObjectRef class

* inlucde QPointer header

* Add changelog entry

* use isNull() instead of ! data()

---------

Co-authored-by: Rasmus Karlsson <rasmus.karlsson@pajlada.com>
This commit is contained in:
Arne 2023-06-04 13:24:04 +02:00 committed by GitHub
parent e803b6de95
commit 6681ed5bfb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 20 additions and 105 deletions

View file

@ -13,6 +13,7 @@
- Dev: Expanded upon `$$$` test channels. (#4655) - Dev: Expanded upon `$$$` test channels. (#4655)
- Dev: Added tools to help debug image GC. (#4578) - Dev: Added tools to help debug image GC. (#4578)
- Dev: Removed duplicate license when having plugins enabled. (#4665) - Dev: Removed duplicate license when having plugins enabled. (#4665)
- Dev: Replace our QObjectRef class with Qt's QPointer class. (#4666)
## 2.4.4 ## 2.4.4

View file

@ -174,7 +174,7 @@ void loadUncached(std::shared_ptr<NetworkData> &&data)
} }
auto handleReply = [data, reply]() mutable { auto handleReply = [data, reply]() mutable {
if (data->hasCaller_ && !data->caller_.get()) if (data->hasCaller_ && data->caller_.isNull())
{ {
return; return;
} }
@ -350,7 +350,7 @@ void loadCached(std::shared_ptr<NetworkData> &&data)
// XXX: If outcome is Failure, we should invalidate the cache file // XXX: If outcome is Failure, we should invalidate the cache file
// somehow/somewhere // somehow/somewhere
/*auto outcome =*/ /*auto outcome =*/
if (data->hasCaller_ && !data->caller_.get()) if (data->hasCaller_ && data->caller_.isNull())
{ {
return; return;
} }
@ -359,7 +359,7 @@ void loadCached(std::shared_ptr<NetworkData> &&data)
else else
{ {
postToThread([data, result]() { postToThread([data, result]() {
if (data->hasCaller_ && !data->caller_.get()) if (data->hasCaller_ && data->caller_.isNull())
{ {
return; return;
} }
@ -373,7 +373,7 @@ void loadCached(std::shared_ptr<NetworkData> &&data)
{ {
if (data->executeConcurrently_ || isGuiThread()) if (data->executeConcurrently_ || isGuiThread())
{ {
if (data->hasCaller_ && !data->caller_.get()) if (data->hasCaller_ && data->caller_.isNull())
{ {
return; return;
} }
@ -383,7 +383,7 @@ void loadCached(std::shared_ptr<NetworkData> &&data)
else else
{ {
postToThread([data]() { postToThread([data]() {
if (data->hasCaller_ && !data->caller_.get()) if (data->hasCaller_ && data->caller_.isNull())
{ {
return; return;
} }

View file

@ -1,10 +1,10 @@
#pragma once #pragma once
#include "common/NetworkCommon.hpp" #include "common/NetworkCommon.hpp"
#include "util/QObjectRef.hpp"
#include <QHttpMultiPart> #include <QHttpMultiPart>
#include <QNetworkRequest> #include <QNetworkRequest>
#include <QPointer>
#include <QTimer> #include <QTimer>
#include <functional> #include <functional>
@ -38,7 +38,7 @@ struct NetworkData {
QNetworkRequest request_; QNetworkRequest request_;
bool hasCaller_{}; bool hasCaller_{};
QObjectRef<QObject> caller_; QPointer<QObject> caller_;
bool cache_{}; bool cache_{};
bool executeConcurrently_{}; bool executeConcurrently_{};

View file

@ -11,9 +11,9 @@
#include "providers/twitch/TwitchIrcServer.hpp" // NOTE: Included to access the mentions channel #include "providers/twitch/TwitchIrcServer.hpp" // NOTE: Included to access the mentions channel
#include "singletons/Settings.hpp" #include "singletons/Settings.hpp"
#include "util/IrcHelpers.hpp" #include "util/IrcHelpers.hpp"
#include "util/QObjectRef.hpp"
#include <QMetaEnum> #include <QMetaEnum>
#include <QPointer>
#include <cassert> #include <cassert>
#include <cstdlib> #include <cstdlib>
@ -151,7 +151,7 @@ void IrcServer::initializeConnection(IrcConnection *connection,
[[fallthrough]]; [[fallthrough]];
case IrcAuthType::Pass: case IrcAuthType::Pass:
this->data_->getPassword( this->data_->getPassword(
this, [conn = new QObjectRef(connection) /* can't copy */, this, [conn = new QPointer(connection) /* can't copy */,
this](const QString &password) mutable { this](const QString &password) mutable {
if (*conn) if (*conn)
{ {

View file

@ -1,86 +0,0 @@
#pragma once
#include <QApplication>
#include <QObject>
#include <type_traits>
namespace chatterino {
/// Holds a pointer to a QObject and resets it to nullptr if the QObject
/// gets destroyed.
template <typename T>
class QObjectRef
{
public:
QObjectRef()
{
static_assert(std::is_base_of_v<QObject, T>);
}
explicit QObjectRef(T *t)
{
static_assert(std::is_base_of_v<QObject, T>);
this->set(t);
}
QObjectRef(const QObjectRef &other)
{
this->set(other.t_);
}
~QObjectRef()
{
this->set(nullptr);
}
QObjectRef &operator=(T *t)
{
this->set(t);
return *this;
}
operator bool()
{
return t_;
}
T *operator->()
{
return t_;
}
T *get()
{
return t_;
}
private:
void set(T *other)
{
// old
if (this->conn_)
{
QObject::disconnect(this->conn_);
}
// new
if (other)
{
// the cast here should absolutely not be necessary, but gcc still requires it
this->conn_ =
QObject::connect((QObject *)other, &QObject::destroyed, qApp,
[this](QObject *) {
this->set(nullptr);
},
Qt::DirectConnection);
}
this->t_ = other;
}
std::atomic<T *> t_{};
QMetaObject::Connection conn_;
};
} // namespace chatterino

View file

@ -630,7 +630,7 @@ bool SplitInput::eventFilter(QObject *obj, QEvent *event)
if (event->type() == QEvent::ShortcutOverride || if (event->type() == QEvent::ShortcutOverride ||
event->type() == QEvent::Shortcut) event->type() == QEvent::Shortcut)
{ {
if (auto popup = this->inputCompletionPopup_.get()) if (auto popup = this->inputCompletionPopup_.data())
{ {
if (popup->isVisible()) if (popup->isVisible())
{ {
@ -650,7 +650,7 @@ void SplitInput::installKeyPressedEvent()
{ {
this->ui_.textEdit->keyPressed.disconnectAll(); this->ui_.textEdit->keyPressed.disconnectAll();
this->ui_.textEdit->keyPressed.connect([this](QKeyEvent *event) { this->ui_.textEdit->keyPressed.connect([this](QKeyEvent *event) {
if (auto *popup = this->inputCompletionPopup_.get()) if (auto *popup = this->inputCompletionPopup_.data())
{ {
if (popup->isVisible()) if (popup->isVisible())
{ {
@ -764,12 +764,12 @@ void SplitInput::updateCompletionPopup()
void SplitInput::showCompletionPopup(const QString &text, bool emoteCompletion) void SplitInput::showCompletionPopup(const QString &text, bool emoteCompletion)
{ {
if (!this->inputCompletionPopup_.get()) if (this->inputCompletionPopup_.isNull())
{ {
this->inputCompletionPopup_ = new InputCompletionPopup(this); this->inputCompletionPopup_ = new InputCompletionPopup(this);
this->inputCompletionPopup_->setInputAction( this->inputCompletionPopup_->setInputAction(
[that = QObjectRef(this)](const QString &text) mutable { [that = QPointer(this)](const QString &text) mutable {
if (auto *this2 = that.get()) if (auto *this2 = that.data())
{ {
this2->insertCompletionText(text); this2->insertCompletionText(text);
this2->hideCompletionPopup(); this2->hideCompletionPopup();
@ -777,7 +777,7 @@ void SplitInput::showCompletionPopup(const QString &text, bool emoteCompletion)
}); });
} }
auto *popup = this->inputCompletionPopup_.get(); auto *popup = this->inputCompletionPopup_.data();
assert(popup); assert(popup);
if (emoteCompletion) if (emoteCompletion)
@ -798,7 +798,7 @@ void SplitInput::showCompletionPopup(const QString &text, bool emoteCompletion)
void SplitInput::hideCompletionPopup() void SplitInput::hideCompletionPopup()
{ {
if (auto *popup = this->inputCompletionPopup_.get()) if (auto *popup = this->inputCompletionPopup_.data())
{ {
popup->hide(); popup->hide();
} }

View file

@ -1,12 +1,12 @@
#pragma once #pragma once
#include "util/QObjectRef.hpp"
#include "widgets/BaseWidget.hpp" #include "widgets/BaseWidget.hpp"
#include <QHBoxLayout> #include <QHBoxLayout>
#include <QLabel> #include <QLabel>
#include <QLineEdit> #include <QLineEdit>
#include <QPaintEvent> #include <QPaintEvent>
#include <QPointer>
#include <QTextEdit> #include <QTextEdit>
#include <QVBoxLayout> #include <QVBoxLayout>
#include <QWidget> #include <QWidget>
@ -113,8 +113,8 @@ protected:
Split *const split_; Split *const split_;
ChannelView *const channelView_; ChannelView *const channelView_;
QObjectRef<EmotePopup> emotePopup_; QPointer<EmotePopup> emotePopup_;
QObjectRef<InputCompletionPopup> inputCompletionPopup_; QPointer<InputCompletionPopup> inputCompletionPopup_;
struct { struct {
ResizingTextEdit *textEdit; ResizingTextEdit *textEdit;