mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-03-30 20:15:35 +08:00
refs #467 Refactored CLogPatternHandler garbage collection by hooking into QObject::disconnectNotify.
This commit is contained in:
@@ -118,8 +118,6 @@ namespace BlackMisc
|
|||||||
|
|
||||||
void CLogHandler::logMessage(const CStatusMessage &statusMessage)
|
void CLogHandler::logMessage(const CStatusMessage &statusMessage)
|
||||||
{
|
{
|
||||||
collectGarbage();
|
|
||||||
|
|
||||||
auto handlers = handlersForMessage(statusMessage);
|
auto handlers = handlersForMessage(statusMessage);
|
||||||
|
|
||||||
if (isFallThroughEnabled(handlers))
|
if (isFallThroughEnabled(handlers))
|
||||||
@@ -138,14 +136,38 @@ namespace BlackMisc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CLogHandler::collectGarbage()
|
void CLogHandler::removePatternHandler(CLogPatternHandler *handler)
|
||||||
{
|
{
|
||||||
auto newEnd = std::stable_partition(m_patternHandlers.begin(), m_patternHandlers.end(), [](const PatternPair &pair)
|
auto it = std::find_if(m_patternHandlers.begin(), m_patternHandlers.end(), [handler](const PatternPair &pair)
|
||||||
{
|
{
|
||||||
return ! pair.second->canBeDeleted();
|
return pair.second == handler;
|
||||||
});
|
});
|
||||||
std::for_each(newEnd, m_patternHandlers.end(), [](const PatternPair &pair) { pair.second->deleteLater(); });
|
if (it != m_patternHandlers.end())
|
||||||
m_patternHandlers.erase(newEnd, m_patternHandlers.end());
|
{
|
||||||
|
it->second->deleteLater();
|
||||||
|
m_patternHandlers.erase(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CLogPatternHandler::CLogPatternHandler(CLogHandler *parent) :
|
||||||
|
QObject(parent), m_parent(parent)
|
||||||
|
{
|
||||||
|
connect(&m_subscriptionUpdateTimer, &QTimer::timeout, this, &CLogPatternHandler::updateSubscription);
|
||||||
|
m_subscriptionUpdateTimer.start(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CLogPatternHandler::updateSubscription()
|
||||||
|
{
|
||||||
|
if (m_subscriptionNeedsUpdate)
|
||||||
|
{
|
||||||
|
m_subscriptionNeedsUpdate = false;
|
||||||
|
bool isSubscribed = isSignalConnected(QMetaMethod::fromSignal(&CLogPatternHandler::messageLogged));
|
||||||
|
|
||||||
|
if (m_inheritFallThrough && ! isSubscribed)
|
||||||
|
{
|
||||||
|
m_parent->removePatternHandler(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CLogSubscriber::changeSubscription(const CLogPattern &pattern)
|
void CLogSubscriber::changeSubscription(const CLogPattern &pattern)
|
||||||
|
|||||||
@@ -20,6 +20,8 @@
|
|||||||
#include <QPointer>
|
#include <QPointer>
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
#include <QMetaMethod>
|
#include <QMetaMethod>
|
||||||
|
#include <QTimer>
|
||||||
|
#include <atomic>
|
||||||
|
|
||||||
namespace BlackMisc
|
namespace BlackMisc
|
||||||
{
|
{
|
||||||
@@ -79,14 +81,15 @@ namespace BlackMisc
|
|||||||
void enableConsoleOutput(bool enable);
|
void enableConsoleOutput(bool enable);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
friend class CLogPatternHandler;
|
||||||
void logMessage(const BlackMisc::CStatusMessage &message);
|
void logMessage(const BlackMisc::CStatusMessage &message);
|
||||||
void collectGarbage();
|
|
||||||
QtMessageHandler m_oldHandler = nullptr;
|
QtMessageHandler m_oldHandler = nullptr;
|
||||||
bool m_enableFallThrough = true;
|
bool m_enableFallThrough = true;
|
||||||
bool isFallThroughEnabled(const QList<CLogPatternHandler *> &handlers) const;
|
bool isFallThroughEnabled(const QList<CLogPatternHandler *> &handlers) const;
|
||||||
using PatternPair = std::pair<CLogPattern, CLogPatternHandler *>;
|
using PatternPair = std::pair<CLogPattern, CLogPatternHandler *>;
|
||||||
QList<PatternPair> m_patternHandlers;
|
QList<PatternPair> m_patternHandlers;
|
||||||
QList<CLogPatternHandler *> handlersForMessage(const CStatusMessage &message) const;
|
QList<CLogPatternHandler *> handlersForMessage(const CStatusMessage &message) const;
|
||||||
|
void removePatternHandler(CLogPatternHandler *);
|
||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -110,6 +113,7 @@ namespace BlackMisc
|
|||||||
Q_ASSERT(thread() == QThread::currentThread());
|
Q_ASSERT(thread() == QThread::currentThread());
|
||||||
m_inheritFallThrough = false;
|
m_inheritFallThrough = false;
|
||||||
m_enableFallThrough = enable;
|
m_enableFallThrough = enable;
|
||||||
|
m_subscriptionNeedsUpdate = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -123,6 +127,7 @@ namespace BlackMisc
|
|||||||
{
|
{
|
||||||
Q_ASSERT(thread() == QThread::currentThread());
|
Q_ASSERT(thread() == QThread::currentThread());
|
||||||
m_inheritFallThrough = true;
|
m_inheritFallThrough = true;
|
||||||
|
m_subscriptionNeedsUpdate = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
@@ -158,18 +163,28 @@ namespace BlackMisc
|
|||||||
return connect(this, &CLogPatternHandler::messageLogged, slot);
|
return connect(this, &CLogPatternHandler::messageLogged, slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
//! \copydoc QObject::connectNotify
|
||||||
|
virtual void connectNotify(const QMetaMethod &signal) override
|
||||||
|
{
|
||||||
|
if (signal == QMetaMethod::fromSignal(&CLogPatternHandler::messageLogged)) { m_subscriptionNeedsUpdate = true; }
|
||||||
|
}
|
||||||
|
|
||||||
|
//! \copydoc QObject::disconnectNotify
|
||||||
|
virtual void disconnectNotify(const QMetaMethod &signal) override
|
||||||
|
{
|
||||||
|
if (signal == QMetaMethod::fromSignal(&CLogPatternHandler::messageLogged)) { m_subscriptionNeedsUpdate = true; }
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class CLogHandler;
|
friend class CLogHandler;
|
||||||
CLogPatternHandler(QObject *parent) : QObject(parent) {}
|
CLogPatternHandler(CLogHandler *parent);
|
||||||
|
CLogHandler *m_parent = nullptr;
|
||||||
bool m_inheritFallThrough = true;
|
bool m_inheritFallThrough = true;
|
||||||
bool m_enableFallThrough = true;
|
bool m_enableFallThrough = true;
|
||||||
|
std::atomic<bool> m_subscriptionNeedsUpdate = false;
|
||||||
bool canBeDeleted()
|
QTimer m_subscriptionUpdateTimer;
|
||||||
{
|
void updateSubscription();
|
||||||
if (! m_inheritFallThrough) { return false; }
|
|
||||||
static const auto signal = QMetaMethod::fromSignal(&CLogPatternHandler::messageLogged);
|
|
||||||
return ! isSignalConnected(signal);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|||||||
Reference in New Issue
Block a user