hiding code in QskObjectCounter.cpp
This commit is contained in:
parent
18dfd907fe
commit
22e75daf6a
|
@ -28,108 +28,171 @@ static inline bool qskIsItem( const QObject* object )
|
||||||
return dynamic_cast< QQuickItemPrivate* >( o_p ) != nullptr;
|
return dynamic_cast< QQuickItemPrivate* >( o_p ) != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void qskStartupHook();
|
namespace
|
||||||
static void qskAddObjectHook( QObject* );
|
|
||||||
static void qskRemoveObjectHook( QObject* );
|
|
||||||
|
|
||||||
class QskObjectCounterHook
|
|
||||||
{
|
{
|
||||||
public:
|
class Counter
|
||||||
QskObjectCounterHook()
|
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
Counter()
|
||||||
|
{
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset()
|
||||||
|
{
|
||||||
|
created = destroyed = current = maximum = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void increment()
|
||||||
|
{
|
||||||
|
created++;
|
||||||
|
current++;
|
||||||
|
|
||||||
|
if ( current > maximum )
|
||||||
|
maximum = current;
|
||||||
|
}
|
||||||
|
|
||||||
|
void decrement()
|
||||||
|
{
|
||||||
|
destroyed++;
|
||||||
|
current--;
|
||||||
|
}
|
||||||
|
|
||||||
|
int created;
|
||||||
|
int destroyed;
|
||||||
|
int current;
|
||||||
|
int maximum;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CounterHook
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CounterHook();
|
||||||
|
~CounterHook();
|
||||||
|
|
||||||
|
void registerCounters( Counter[], bool on );
|
||||||
|
bool isCountersRegistered( const Counter[] ) const;
|
||||||
|
|
||||||
|
bool isActive() const;
|
||||||
|
|
||||||
|
void startup();
|
||||||
|
void addObject( QObject* );
|
||||||
|
void removeObject( QObject* );
|
||||||
|
|
||||||
|
static void cleanupHook();
|
||||||
|
|
||||||
|
private:
|
||||||
|
static void startupHook();
|
||||||
|
static void addObjectHook( QObject* );
|
||||||
|
static void removeObjectHook( QObject* );
|
||||||
|
|
||||||
|
QSet< Counter* > m_countersSet;
|
||||||
|
|
||||||
|
quintptr m_otherStartup;
|
||||||
|
quintptr m_otherAddObject;
|
||||||
|
quintptr m_otherRemoveObject;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool qskAutoDeleteHook = false;
|
||||||
|
static CounterHook* qskCounterHook = nullptr;
|
||||||
|
|
||||||
|
CounterHook::CounterHook()
|
||||||
|
{
|
||||||
m_otherStartup = qtHookData[ QHooks::Startup ];
|
m_otherStartup = qtHookData[ QHooks::Startup ];
|
||||||
m_otherAddObject = qtHookData[ QHooks::AddQObject ];
|
m_otherAddObject = qtHookData[ QHooks::AddQObject ];
|
||||||
m_otherRemoveObject = qtHookData[ QHooks::RemoveQObject ];
|
m_otherRemoveObject = qtHookData[ QHooks::RemoveQObject ];
|
||||||
|
|
||||||
qtHookData[ QHooks::Startup ] = reinterpret_cast< quintptr >( &qskStartupHook );
|
qtHookData[ QHooks::Startup ] = reinterpret_cast< quintptr >( &startupHook );
|
||||||
qtHookData[ QHooks::AddQObject ] = reinterpret_cast< quintptr >( &qskAddObjectHook );
|
qtHookData[ QHooks::AddQObject ] = reinterpret_cast< quintptr >( &addObjectHook );
|
||||||
qtHookData[ QHooks::RemoveQObject ] = reinterpret_cast< quintptr >( &qskRemoveObjectHook );
|
qtHookData[ QHooks::RemoveQObject ] = reinterpret_cast< quintptr >( &removeObjectHook );
|
||||||
}
|
}
|
||||||
|
|
||||||
~QskObjectCounterHook()
|
CounterHook::~CounterHook()
|
||||||
{
|
{
|
||||||
qtHookData[ QHooks::Startup ] = m_otherStartup;
|
qtHookData[ QHooks::Startup ] = m_otherStartup;
|
||||||
qtHookData[ QHooks::AddQObject ] = m_otherAddObject;
|
qtHookData[ QHooks::AddQObject ] = m_otherAddObject;
|
||||||
qtHookData[ QHooks::RemoveQObject ] = m_otherRemoveObject;
|
qtHookData[ QHooks::RemoveQObject ] = m_otherRemoveObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
void registerCounter( QskObjectCounter* counter, bool on )
|
void CounterHook::registerCounters( Counter counters[], bool on )
|
||||||
{
|
{
|
||||||
if ( on )
|
if ( on )
|
||||||
m_counterSet.insert( counter );
|
m_countersSet.insert( counters );
|
||||||
else
|
else
|
||||||
m_counterSet.remove( counter );
|
m_countersSet.remove( counters );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isCounterRegistered( const QskObjectCounter* counter ) const
|
bool CounterHook::isCountersRegistered( const Counter counters[] ) const
|
||||||
{
|
{
|
||||||
return m_counterSet.contains( const_cast< QskObjectCounter* >( counter ) );
|
return m_countersSet.contains( const_cast< Counter* >( counters ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isActive() const
|
bool CounterHook::isActive() const
|
||||||
{
|
{
|
||||||
return !m_counterSet.isEmpty();
|
return !m_countersSet.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
void startup()
|
void CounterHook::startup()
|
||||||
{
|
{
|
||||||
#if 0
|
#if 0
|
||||||
qDebug() << "** QskObjectCounterHook enabled";
|
qDebug() << "** QskObjectCounterHook enabled";
|
||||||
#endif
|
#endif
|
||||||
if ( m_otherStartup )
|
if ( m_otherStartup )
|
||||||
reinterpret_cast< QHooks::StartupCallback >( m_otherStartup )();
|
reinterpret_cast< QHooks::StartupCallback >( m_otherStartup )();
|
||||||
}
|
}
|
||||||
|
|
||||||
void addObject( QObject* object )
|
void CounterHook::addObject( QObject* object )
|
||||||
|
{
|
||||||
|
const bool isItem = qskIsItem( object );
|
||||||
|
|
||||||
|
for ( auto counters : qskAsConst( m_countersSet ) )
|
||||||
{
|
{
|
||||||
for ( auto counter : qskAsConst( m_counterSet ) )
|
counters[ QskObjectCounter::Objects ].increment();
|
||||||
counter->addObject( object );
|
|
||||||
|
if ( isItem )
|
||||||
|
counters[ QskObjectCounter::Items ].increment();
|
||||||
|
}
|
||||||
|
|
||||||
if ( m_otherAddObject )
|
if ( m_otherAddObject )
|
||||||
reinterpret_cast< QHooks::AddQObjectCallback >( m_otherAddObject )( object );
|
reinterpret_cast< QHooks::AddQObjectCallback >( m_otherAddObject )( object );
|
||||||
}
|
}
|
||||||
|
|
||||||
void removeObject( QObject* object )
|
void CounterHook::removeObject( QObject* object )
|
||||||
|
{
|
||||||
|
const bool isItem = qskIsItem( object );
|
||||||
|
|
||||||
|
for ( auto counters : qskAsConst( m_countersSet ) )
|
||||||
{
|
{
|
||||||
for ( auto counter : qskAsConst( m_counterSet ) )
|
counters[ QskObjectCounter::Objects ].decrement();
|
||||||
counter->removeObject( object );
|
|
||||||
|
if ( isItem )
|
||||||
|
counters[ QskObjectCounter::Items ].decrement();
|
||||||
|
}
|
||||||
|
|
||||||
if ( m_otherRemoveObject )
|
if ( m_otherRemoveObject )
|
||||||
reinterpret_cast< QHooks::RemoveQObjectCallback >( m_otherRemoveObject )( object );
|
reinterpret_cast< QHooks::RemoveQObjectCallback >( m_otherRemoveObject )( object );
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool autoDelete;
|
void CounterHook::startupHook()
|
||||||
|
|
||||||
private:
|
|
||||||
QSet< QskObjectCounter* > m_counterSet;
|
|
||||||
|
|
||||||
quintptr m_otherStartup;
|
|
||||||
quintptr m_otherAddObject;
|
|
||||||
quintptr m_otherRemoveObject;
|
|
||||||
};
|
|
||||||
|
|
||||||
bool QskObjectCounterHook::autoDelete = false;
|
|
||||||
static QskObjectCounterHook* qskCounterHook = nullptr;
|
|
||||||
|
|
||||||
static void qskStartupHook()
|
|
||||||
{
|
{
|
||||||
if ( qskCounterHook )
|
if ( qskCounterHook )
|
||||||
qskCounterHook->startup();
|
qskCounterHook->startup();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void qskAddObjectHook( QObject* object )
|
void CounterHook::addObjectHook( QObject* object )
|
||||||
{
|
{
|
||||||
if ( qskCounterHook )
|
if ( qskCounterHook )
|
||||||
qskCounterHook->addObject( object );
|
qskCounterHook->addObject( object );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void qskRemoveObjectHook( QObject* object )
|
void CounterHook::removeObjectHook( QObject* object )
|
||||||
{
|
{
|
||||||
if ( qskCounterHook )
|
if ( qskCounterHook )
|
||||||
qskCounterHook->removeObject( object );
|
qskCounterHook->removeObject( object );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void qskCleanupHook()
|
void CounterHook::cleanupHook()
|
||||||
{
|
{
|
||||||
if ( qskCounterHook && !qskCounterHook->isActive() )
|
if ( qskCounterHook && !qskCounterHook->isActive() )
|
||||||
{
|
{
|
||||||
|
@ -138,18 +201,31 @@ static void qskCleanupHook()
|
||||||
}
|
}
|
||||||
|
|
||||||
// From now on we remove the hooks as soon as there are no counters
|
// From now on we remove the hooks as soon as there are no counters
|
||||||
QskObjectCounterHook::autoDelete = true;
|
qskAutoDeleteHook = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void qskInstallCleanupHookHandler()
|
static void qskInstallCleanupHookHandler()
|
||||||
{
|
{
|
||||||
qAddPostRoutine( qskCleanupHook );
|
qAddPostRoutine( CounterHook::cleanupHook );
|
||||||
}
|
}
|
||||||
|
|
||||||
Q_COREAPP_STARTUP_FUNCTION( qskInstallCleanupHookHandler )
|
Q_COREAPP_STARTUP_FUNCTION( qskInstallCleanupHookHandler )
|
||||||
|
|
||||||
|
class QskObjectCounter::PrivateData
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PrivateData( bool debugAtDestruction )
|
||||||
|
: debugAtDestruction( debugAtDestruction )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Counter counter[ 2 ];
|
||||||
|
const bool debugAtDestruction;
|
||||||
|
};
|
||||||
|
|
||||||
QskObjectCounter::QskObjectCounter( bool debugAtDestruction )
|
QskObjectCounter::QskObjectCounter( bool debugAtDestruction )
|
||||||
: m_debugAtDestruction( debugAtDestruction )
|
: m_data( new PrivateData( debugAtDestruction ) )
|
||||||
{
|
{
|
||||||
setActive( true );
|
setActive( true );
|
||||||
}
|
}
|
||||||
|
@ -158,7 +234,7 @@ QskObjectCounter::~QskObjectCounter()
|
||||||
{
|
{
|
||||||
setActive( false );
|
setActive( false );
|
||||||
|
|
||||||
if ( m_debugAtDestruction )
|
if ( m_data->debugAtDestruction )
|
||||||
dump();
|
dump();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,16 +243,16 @@ void QskObjectCounter::setActive( bool on )
|
||||||
if ( on )
|
if ( on )
|
||||||
{
|
{
|
||||||
if ( qskCounterHook == nullptr )
|
if ( qskCounterHook == nullptr )
|
||||||
qskCounterHook = new QskObjectCounterHook();
|
qskCounterHook = new CounterHook();
|
||||||
|
|
||||||
qskCounterHook->registerCounter( this, on );
|
qskCounterHook->registerCounters( m_data->counter, on );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
qskCounterHook->registerCounter( this, on );
|
qskCounterHook->registerCounters( m_data->counter, on );
|
||||||
if ( !qskCounterHook->isActive() )
|
if ( !qskCounterHook->isActive() )
|
||||||
{
|
{
|
||||||
if ( QskObjectCounterHook::autoDelete )
|
if ( qskAutoDeleteHook )
|
||||||
{
|
{
|
||||||
delete qskCounterHook;
|
delete qskCounterHook;
|
||||||
qskCounterHook = nullptr;
|
qskCounterHook = nullptr;
|
||||||
|
@ -187,54 +263,38 @@ void QskObjectCounter::setActive( bool on )
|
||||||
|
|
||||||
bool QskObjectCounter::isActive() const
|
bool QskObjectCounter::isActive() const
|
||||||
{
|
{
|
||||||
return qskCounterHook && qskCounterHook->isCounterRegistered( this );
|
return qskCounterHook && qskCounterHook->isCountersRegistered( m_data->counter );
|
||||||
}
|
|
||||||
|
|
||||||
void QskObjectCounter::addObject( QObject* object )
|
|
||||||
{
|
|
||||||
m_counter[ Objects ].increment();
|
|
||||||
|
|
||||||
if ( qskIsItem( object ) )
|
|
||||||
m_counter[ Items ].increment();
|
|
||||||
}
|
|
||||||
|
|
||||||
void QskObjectCounter::removeObject( QObject* object )
|
|
||||||
{
|
|
||||||
m_counter[ Objects ].decrement();
|
|
||||||
|
|
||||||
if ( qskIsItem( object ) )
|
|
||||||
m_counter[ Items ].decrement();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void QskObjectCounter::reset()
|
void QskObjectCounter::reset()
|
||||||
{
|
{
|
||||||
m_counter[ Objects ].reset();
|
m_data->counter[ Objects ].reset();
|
||||||
m_counter[ Items ].reset();
|
m_data->counter[ Items ].reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
int QskObjectCounter::created( ObjectType objectType ) const
|
int QskObjectCounter::created( ObjectType objectType ) const
|
||||||
{
|
{
|
||||||
return m_counter[ objectType ].created;
|
return m_data->counter[ objectType ].created;
|
||||||
}
|
}
|
||||||
|
|
||||||
int QskObjectCounter::destroyed( ObjectType objectType ) const
|
int QskObjectCounter::destroyed( ObjectType objectType ) const
|
||||||
{
|
{
|
||||||
return m_counter[ objectType ].destroyed;
|
return m_data->counter[ objectType ].destroyed;
|
||||||
}
|
}
|
||||||
|
|
||||||
int QskObjectCounter::current( ObjectType objectType ) const
|
int QskObjectCounter::current( ObjectType objectType ) const
|
||||||
{
|
{
|
||||||
return m_counter[ objectType ].current;
|
return m_data->counter[ objectType ].current;
|
||||||
}
|
}
|
||||||
|
|
||||||
int QskObjectCounter::maximum( ObjectType objectType ) const
|
int QskObjectCounter::maximum( ObjectType objectType ) const
|
||||||
{
|
{
|
||||||
return m_counter[ objectType ].maximum;
|
return m_data->counter[ objectType ].maximum;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QskObjectCounter::debugStatistics( QDebug debug, ObjectType objectType ) const
|
void QskObjectCounter::debugStatistics( QDebug debug, ObjectType objectType ) const
|
||||||
{
|
{
|
||||||
const Counter& c = m_counter[ objectType ];
|
const auto& c = m_data->counter[ objectType ];
|
||||||
|
|
||||||
QDebugStateSaver saver( debug );
|
QDebugStateSaver saver( debug );
|
||||||
debug.nospace();
|
debug.nospace();
|
||||||
|
|
|
@ -7,10 +7,9 @@
|
||||||
#define QSK_OBJECT_COUNTER_H
|
#define QSK_OBJECT_COUNTER_H
|
||||||
|
|
||||||
#include "QskGlobal.h"
|
#include "QskGlobal.h"
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
class QObject;
|
class QObject;
|
||||||
class QDebug;
|
|
||||||
class QskObjectCounterHook;
|
|
||||||
|
|
||||||
class QSK_EXPORT QskObjectCounter
|
class QSK_EXPORT QskObjectCounter
|
||||||
{
|
{
|
||||||
|
@ -38,51 +37,16 @@ class QSK_EXPORT QskObjectCounter
|
||||||
void dump() const;
|
void dump() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class QskObjectCounterHook;
|
class PrivateData;
|
||||||
|
std::unique_ptr< PrivateData > m_data;
|
||||||
|
|
||||||
void addObject( QObject* );
|
|
||||||
void removeObject( QObject* );
|
|
||||||
|
|
||||||
class Counter
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Counter()
|
|
||||||
{
|
|
||||||
reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
void reset()
|
|
||||||
{
|
|
||||||
created = destroyed = current = maximum = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void increment()
|
|
||||||
{
|
|
||||||
created++;
|
|
||||||
current++;
|
|
||||||
|
|
||||||
if ( current > maximum )
|
|
||||||
maximum = current;
|
|
||||||
}
|
|
||||||
|
|
||||||
void decrement()
|
|
||||||
{
|
|
||||||
destroyed++;
|
|
||||||
current--;
|
|
||||||
}
|
|
||||||
|
|
||||||
int created;
|
|
||||||
int destroyed;
|
|
||||||
int current;
|
|
||||||
int maximum;
|
|
||||||
};
|
|
||||||
|
|
||||||
Counter m_counter[ 2 ];
|
|
||||||
const bool m_debugAtDestruction;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef QT_NO_DEBUG_STREAM
|
#ifndef QT_NO_DEBUG_STREAM
|
||||||
|
|
||||||
|
class QDebug;
|
||||||
QSK_EXPORT QDebug operator<<( QDebug, const QskObjectCounter& );
|
QSK_EXPORT QDebug operator<<( QDebug, const QskObjectCounter& );
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue