code improved

This commit is contained in:
Uwe Rathmann 2018-02-07 15:40:05 +01:00
parent 8553ecc354
commit 38ed90b659
1 changed files with 84 additions and 40 deletions

View File

@ -14,14 +14,6 @@ QSK_QT_PRIVATE_BEGIN
#include <private/qobject_p.h> #include <private/qobject_p.h>
QSK_QT_PRIVATE_END QSK_QT_PRIVATE_END
static struct
{
QHooks::StartupCallback startup;
QHooks::AddQObjectCallback addObject;
QHooks::RemoveQObjectCallback removeObject;
} qskOtherHooks;
static inline bool qskIsItem( const QObject* object ) static inline bool qskIsItem( const QObject* object )
{ {
QObjectPrivate* o_p = QObjectPrivate::get( const_cast< QObject* >( object ) ); QObjectPrivate* o_p = QObjectPrivate::get( const_cast< QObject* >( object ) );
@ -36,9 +28,31 @@ static inline bool qskIsItem( const QObject* object )
return dynamic_cast< QQuickItemPrivate* >( o_p ) != nullptr; return dynamic_cast< QQuickItemPrivate* >( o_p ) != nullptr;
} }
static void qskStartupHook();
static void qskAddObjectHook( QObject* );
static void qskRemoveObjectHook( QObject* );
class QskObjectCounterHook class QskObjectCounterHook
{ {
public: public:
QskObjectCounterHook()
{
m_otherStartup = qtHookData[QHooks::Startup];
m_otherAddObject = qtHookData[QHooks::AddQObject];
m_otherRemoveObject = qtHookData[QHooks::RemoveQObject];
qtHookData[QHooks::Startup] = reinterpret_cast< quintptr >( &qskStartupHook );
qtHookData[QHooks::AddQObject] = reinterpret_cast< quintptr >( &qskAddObjectHook );
qtHookData[QHooks::RemoveQObject] = reinterpret_cast< quintptr >( &qskRemoveObjectHook );
}
~QskObjectCounterHook()
{
qtHookData[QHooks::Startup] = m_otherStartup;
qtHookData[QHooks::AddQObject] = m_otherAddObject;
qtHookData[QHooks::RemoveQObject] = m_otherRemoveObject;
}
void registerCounter( QskObjectCounter* counter, bool on ) void registerCounter( QskObjectCounter* counter, bool on )
{ {
if ( on ) if ( on )
@ -52,76 +66,88 @@ public:
return m_counterSet.contains( const_cast< QskObjectCounter* >( counter ) ); return m_counterSet.contains( const_cast< QskObjectCounter* >( counter ) );
} }
void startup() const bool isActive() const
{
return !m_counterSet.isEmpty();
}
void startup()
{ {
#if 0 #if 0
qDebug() << "** QskObjectCounterHook enabled"; qDebug() << "** QskObjectCounterHook enabled";
#endif #endif
if ( m_otherStartup )
reinterpret_cast< QHooks::StartupCallback >( m_otherStartup )();
} }
void addObject( QObject* object ) void addObject( QObject* object )
{ {
for ( auto counter : qskAsConst( m_counterSet ) ) for ( auto counter : qskAsConst( m_counterSet ) )
counter->addObject( object ); counter->addObject( object );
if ( m_otherAddObject )
reinterpret_cast< QHooks::AddQObjectCallback >( m_otherAddObject )( object );
} }
void removeObject( QObject* object ) void removeObject( QObject* object )
{ {
for ( auto counter : qskAsConst( m_counterSet ) ) for ( auto counter : qskAsConst( m_counterSet ) )
counter->removeObject( object ); counter->removeObject( object );
if ( m_otherRemoveObject )
reinterpret_cast< QHooks::RemoveQObjectCallback >( m_otherRemoveObject )( object );
} }
static bool autoDelete;
private: private:
QSet< QskObjectCounter* > m_counterSet; QSet< QskObjectCounter* > m_counterSet;
quintptr m_otherStartup;
quintptr m_otherAddObject;
quintptr m_otherRemoveObject;
}; };
static QskObjectCounterHook* qskCounterHook(); bool QskObjectCounterHook::autoDelete = false;
static QskObjectCounterHook* qskCounterHook = nullptr;
static void qskStartupHook() static void qskStartupHook()
{ {
qskCounterHook()->startup(); if ( qskCounterHook )
qskCounterHook->startup();
if ( qskOtherHooks.startup )
qskOtherHooks.startup();
} }
static void qskAddObjectHook( QObject* object ) static void qskAddObjectHook( QObject* object )
{ {
qskCounterHook()->addObject( object ); if ( qskCounterHook )
qskCounterHook->addObject( object );
if ( qskOtherHooks.addObject )
qskOtherHooks.addObject( object );
} }
static void qskRemoveObjectHook( QObject* object ) static void qskRemoveObjectHook( QObject* object )
{ {
qskCounterHook()->removeObject( object ); if ( qskCounterHook )
qskCounterHook->removeObject( object );
if ( qskOtherHooks.removeObject )
qskOtherHooks.removeObject( object );
} }
static QskObjectCounterHook* qskCounterHook() static void qskCleanupHook()
{ {
static bool isInitialized = false; if ( qskCounterHook && !qskCounterHook->isActive() )
if ( !isInitialized )
{ {
qskOtherHooks.startup = reinterpret_cast< QHooks::StartupCallback >( qtHookData[QHooks::Startup] ); delete qskCounterHook;
qskOtherHooks.addObject = reinterpret_cast< QHooks::AddQObjectCallback >( qtHookData[QHooks::AddQObject] ); qskCounterHook = nullptr;
qskOtherHooks.removeObject = reinterpret_cast< QHooks::RemoveQObjectCallback >( qtHookData[QHooks::RemoveQObject] );
qtHookData[QHooks::Startup] = reinterpret_cast< quintptr >( &qskStartupHook );
qtHookData[QHooks::AddQObject] = reinterpret_cast< quintptr >( &qskAddObjectHook );
qtHookData[QHooks::RemoveQObject] = reinterpret_cast< quintptr >( &qskRemoveObjectHook );
isInitialized = true;
} }
static QskObjectCounterHook counterHook; // From now on we remove the hooks as soon as there are no counters
return &counterHook; QskObjectCounterHook::autoDelete = true;
} }
static void qskInstallCleanupHookHandler()
{
qAddPostRoutine( qskCleanupHook );
}
Q_COREAPP_STARTUP_FUNCTION( qskInstallCleanupHookHandler )
QskObjectCounter::QskObjectCounter( bool debugAtDestruction ): QskObjectCounter::QskObjectCounter( bool debugAtDestruction ):
m_debugAtDestruction( debugAtDestruction ) m_debugAtDestruction( debugAtDestruction )
{ {
@ -138,12 +164,30 @@ QskObjectCounter::~QskObjectCounter()
void QskObjectCounter::setActive( bool on ) void QskObjectCounter::setActive( bool on )
{ {
qskCounterHook()->registerCounter( this, on ); if ( on )
{
if ( qskCounterHook == nullptr )
qskCounterHook = new QskObjectCounterHook();
qskCounterHook->registerCounter( this, on );
}
else
{
qskCounterHook->registerCounter( this, on );
if ( !qskCounterHook->isActive() )
{
if ( QskObjectCounterHook::autoDelete )
{
delete qskCounterHook;
qskCounterHook = nullptr;
}
}
}
} }
bool QskObjectCounter::isActive() const bool QskObjectCounter::isActive() const
{ {
return qskCounterHook()->isCounterRegistered( this ); return qskCounterHook && qskCounterHook->isCounterRegistered( this );
} }
void QskObjectCounter::addObject( QObject* object ) void QskObjectCounter::addObject( QObject* object )