📄 chxstatistictracker.cpp
字号:
}}CHXStatisticTracker::CHXStatisticTracker( IHXRegistry* pIRegistry, CHXStatisticTracker* pParentTracker, UINT32 propID, const char* pFullPropName ) : CHXStatisticTrackerNode( pIRegistry, pParentTracker, propID, pFullPropName ) , m_pStatisticTrackerNodes( NULL ) , m_pObservers( NULL ){}CHXStatisticTracker::~CHXStatisticTracker( void ){ if ( m_pStatisticTrackerNodes ) { CHXStatisticTrackerNode* pStatisticTrackerNode = NULL; while ( m_pStatisticTrackerNodes->Pop( &pStatisticTrackerNode ) ) { pStatisticTrackerNode->Release(); pStatisticTrackerNode = NULL; } delete m_pStatisticTrackerNodes; m_pStatisticTrackerNodes = NULL; } if ( m_pObservers ) { UINT32 numOfObservers = m_pObservers->GetCount(); for ( UINT32 index = 0; index < numOfObservers; ++index ) { SHXTrackerObserverData observerData; m_pObservers->GetAt( index, &observerData ); free( observerData.m_StatisticKey ); } delete m_pObservers; m_pObservers = NULL; }}BEGIN_INTERFACE_LIST_NOCREATE( CHXStatisticTracker ) INTERFACE_LIST_ENTRY_SIMPLE( IHXInterruptSafe )END_INTERFACE_LIST_BASE( CHXStatisticTrackerNode )boolCHXStatisticTracker::StartWatchingMe( void ){ if ( IsWatchingMe() ) return true; bool isWatchingMe = CHXStatisticTrackerNode::StartWatchingMe(); if ( isWatchingMe ) { // This property may already have children. If so, we won't get an AddedProp() call for them. IHXRegistry* pRegistry = GetRegistry(); CHXASSERT( pRegistry ); SPIHXValues spRegistryValues; UINT32 parentPropID = GetPropID(); if ( SUCCEEDED( pRegistry->GetPropListById( parentPropID, *spRegistryValues.AsInOutParam() ) ) ) { const char* pChildPropertyName = NULL; ULONG32 childPropertyID; if ( SUCCEEDED( spRegistryValues->GetFirstPropertyULONG32( pChildPropertyName, childPropertyID ) ) ) { do { ( void ) AddedProp( childPropertyID, pRegistry->GetTypeById( childPropertyID ), parentPropID ); } while ( SUCCEEDED( spRegistryValues->GetNextPropertyULONG32( pChildPropertyName, childPropertyID ) ) ); } } } return isWatchingMe;}CHXStatisticTrackerNode*CHXStatisticTracker::FindStatisticTrackerNode( const UINT32 ulId, UINT32* pOutIndex ) const{ CHXASSERT( pOutIndex ); if ( !m_pStatisticTrackerNodes ) return NULL; UINT32 numOfNodes = m_pStatisticTrackerNodes->GetCount(); for ( UINT32 index = 0; index < numOfNodes; ++index ) { CHXStatisticTrackerNode* pStatisticTrackerNode = NULL; m_pStatisticTrackerNodes->GetAt( index, &pStatisticTrackerNode ); if ( ulId == pStatisticTrackerNode->GetPropID() ) { *pOutIndex = index; return pStatisticTrackerNode; } } return NULL;}STDMETHODIMP_( HXBOOL )CHXStatisticTracker::IsInterruptSafe( void ){ // XXXSEH: This should be removed. It's present to correct a problem in Helix. // If a composite node is added from another thread, the AddedProp() call will be cued unless we return 1 here. // If it's cued, then subsequent child properties added to it won't result in AddedProp()'s because the cued // AddedProp call is required to set up the watcher for them. return 1;}STDMETHODIMPCHXStatisticTracker::AddedProp( const UINT32 ulId, const HXPropType propType, const UINT32 ulParentID ){ IHXRegistry* pRegistry = GetRegistry(); CHXASSERT( pRegistry ); HXPropType actualPropType = pRegistry->GetTypeById( ulId );#ifdef LOG_STATISTICS_DEBUG_INFO char msg[ 32 ]; sprintf( msg, "Added property type %d", actualPropType ); ExamineProperty( ulId, msg );#endif // It's not uncommon for the CORE to create "Duplicate" properties. UINT32 index; if ( NULL == FindStatisticTrackerNode( ulId, &index ) ) { if ( !m_pStatisticTrackerNodes ) { m_pStatisticTrackerNodes = new CHXFlatArray(sizeof(CHXStatisticTrackerNode*)); } if ( m_pStatisticTrackerNodes ) { SPIHXBuffer spFullPropName; pRegistry->GetPropName( ulId, *spFullPropName.AsInOutParam() ); if ( spFullPropName.IsValid() && ( spFullPropName->GetSize() > 0 ) ) { CHXStatisticTrackerNode* pStatisticTrackerNode = NULL; switch ( actualPropType ) { case PT_COMPOSITE: { pStatisticTrackerNode = new CHXStatisticTracker( pRegistry, this, ulId, ( const char* ) spFullPropName->GetBuffer() ); if ( pStatisticTrackerNode ) { pStatisticTrackerNode->AddRef(); if ( !pStatisticTrackerNode->StartWatchingMe() ) { pStatisticTrackerNode->Release(); pStatisticTrackerNode = NULL; } } } break; default: { pStatisticTrackerNode = new CHXStatisticTrackerEntry( pRegistry, this, ulId, ( const char* ) spFullPropName->GetBuffer() ); if ( pStatisticTrackerNode ) { pStatisticTrackerNode->AddRef(); } } break; } if ( pStatisticTrackerNode ) { m_pStatisticTrackerNodes->Push( &pStatisticTrackerNode ); if ( m_pObservers ) { UINT32 numOfObservers = m_pObservers->GetCount(); for ( UINT32 index = 0; index < numOfObservers; ++index ) { SHXTrackerObserverData observerData; m_pObservers->GetAt( index, &observerData ); pStatisticTrackerNode->AddObserver( observerData.m_StatisticKey, observerData.m_pStatisticsCallbacks, observerData.m_ObserverInfo ); } } } } } } return HXR_OK; // XXXSEH: What's the return value mean?}STDMETHODIMPCHXStatisticTracker::ModifiedProp( const UINT32 ulId, const HXPropType propType, const UINT32 ulParentID ){ CHXASSERT( !"Why is ModifiedProp being called on a parent property?" ); return HXR_OK; // XXXSEH: What's the return value mean?}STDMETHODIMPCHXStatisticTracker::DeletedProp( const UINT32 ulId, const UINT32 ulParentID ){ if ( ulId == GetPropID() ) {#ifdef LOG_STATISTICS_DEBUG_INFO ExamineProperty( ulId, "Deleted parent property" );#endif if ( m_pStatisticTrackerNodes ) { CHXStatisticTrackerNode* pStatisticTrackerNode = NULL; while ( m_pStatisticTrackerNodes->Pop( &pStatisticTrackerNode ) ) {#ifdef LOG_STATISTICS_DEBUG_INFO pStatisticTrackerNode->ExamineProperty( pStatisticTrackerNode->GetPropID(), "Delete child property" );#endif pStatisticTrackerNode->DeletedProp( pStatisticTrackerNode->GetPropID(), GetPropID() ); pStatisticTrackerNode->Release(); pStatisticTrackerNode = NULL; } delete m_pStatisticTrackerNodes; m_pStatisticTrackerNodes = NULL; } if ( m_pObservers ) { UINT32 numOfObservers = m_pObservers->GetCount(); for ( UINT32 index = 0; index < numOfObservers; ++index ) { SHXTrackerObserverData observerData; m_pObservers->GetAt( index, &observerData ); HXOnDeletedStatisticProcPtr OnDeletedStatistic = observerData.m_pStatisticsCallbacks->OnDeletedStatistic; if ( OnDeletedStatistic && ShouldObserveProperty( observerData.m_StatisticKey, GetPropName(), true ) ) { OnDeletedStatistic( GetPropName(), observerData.m_ObserverInfo ); } } } StopWatchingMe(); } else { CHXASSERT( m_pStatisticTrackerNodes ); #ifdef LOG_STATISTICS_DEBUG_INFO ExamineProperty( ulId, "Deleted property from parent" );#endif UINT32 index; CHXStatisticTrackerNode* pStatisticTrackerNode = FindStatisticTrackerNode( ulId, &index ); if ( pStatisticTrackerNode ) { pStatisticTrackerNode->Release(); m_pStatisticTrackerNodes->Remove( index ); } } return HXR_OK; // XXXSEH: What's the return value mean?}static boolAreTrackerObserverDataElementsEqual( const void* item1Ptr, const void* item2Ptr ){ const SHXTrackerObserverData* data1 = ( const SHXTrackerObserverData* ) item1Ptr; const SHXTrackerObserverData* data2 = ( const SHXTrackerObserverData* ) item2Ptr; return( ( 0 == strcmp( data1->m_StatisticKey, data2->m_StatisticKey ) ) && ( data1->m_pStatisticsCallbacks == data2->m_pStatisticsCallbacks ) && ( data1->m_ObserverInfo == data2->m_ObserverInfo ) );}boolCHXStatisticTracker::AddObserver( const char* pStatisticKey, const HXStatisticsCallbacks* pStatisticsCallbacks, void* observerInfo ){ CHXASSERT( pStatisticsCallbacks ); CHXASSERT( pStatisticKey && *pStatisticKey ); if ( ShouldObserveProperty( pStatisticKey, GetPropName(), false ) ) { if ( !m_pObservers ) { m_pObservers = new CHXFlatArray(sizeof(SHXTrackerObserverData)); } if ( m_pObservers ) { SHXTrackerObserverData observerData = { ( char* ) pStatisticKey, pStatisticsCallbacks, observerInfo }; if ( m_pObservers->HasRecord( &observerData, AreTrackerObserverDataElementsEqual ) ) return true; observerData.m_StatisticKey = ( char* ) malloc( strlen( pStatisticKey ) + 1 ); strcpy( observerData.m_StatisticKey, pStatisticKey ); m_pObservers->Push( &observerData ); HXOnAddedStatisticProcPtr OnAddedStatistic = pStatisticsCallbacks->OnAddedStatistic; if ( OnAddedStatistic && ShouldObserveProperty( pStatisticKey, GetPropName(), true ) ) { OnAddedStatistic( GetPropName(), kValueTypeInternalUse, NULL, observerInfo ); } if ( m_pStatisticTrackerNodes ) { UINT32 numOfNodes = m_pStatisticTrackerNodes->GetCount(); for ( UINT32 index = 0; index < numOfNodes; ++index ) { CHXStatisticTrackerNode* pStatisticTrackerNode = NULL; m_pStatisticTrackerNodes->GetAt( index, &pStatisticTrackerNode ); pStatisticTrackerNode->AddObserver( pStatisticKey, pStatisticsCallbacks, observerInfo ); } } return true; } } return false;}voidCHXStatisticTracker::RemoveObserver( const char* pStatisticKey, const HXStatisticsCallbacks* pStatisticsCallbacks, void* observerInfo ){ if ( m_pObservers ) { UINT32 recordNumToRemove; SHXTrackerObserverData observerData = { ( char* ) pStatisticKey, pStatisticsCallbacks, observerInfo }; if ( m_pObservers->FindRecord( &observerData, AreTrackerObserverDataElementsEqual, 0, &recordNumToRemove, &observerData ) ) { free( observerData.m_StatisticKey ); m_pObservers->Remove( recordNumToRemove ); if ( m_pStatisticTrackerNodes ) { UINT32 numOfNodes = m_pStatisticTrackerNodes->GetCount(); for ( UINT32 index = 0; index < numOfNodes; ++index ) { CHXStatisticTrackerNode* pStatisticTrackerNode = NULL; m_pStatisticTrackerNodes->GetAt( index, &pStatisticTrackerNode ); pStatisticTrackerNode->RemoveObserver( pStatisticKey, pStatisticsCallbacks, observerInfo ); } } } }}// ***** CHXStatisticTrackerEntry *****CHXStatisticTrackerEntry::CHXStatisticTrackerEntry( IHXRegistry* pIRegistry, CHXStatisticTracker* pParentTracker, UINT32 propID, const char* pFullPropName ) : CHXStatisticTrackerNode( pIRegistry, pParentTracker, propID, pFullPropName ) , m_pEntryObservers( NULL ){}CHXStatisticTrackerEntry::~CHXStatisticTrackerEntry( void ){ delete m_pEntryObservers; m_pEntryObservers = NULL;}BEGIN_INTERFACE_LIST_NOCREATE( CHXStatisticTrackerEntry )END_INTERFACE_LIST_BASE( CHXStatisticTrackerNode )class StatisticCallbackProcessor : public CHXStatisticProcessor{private: const char* m_pStatisticName; void* m_ObserverInfo; const HXStatisticsCallbacks* m_pStatisticsCallbacks; bool m_IsNewStatistic;public: StatisticCallbackProcessor( const char* pStatisticName, const HXStatisticsCallbacks* pStatisticsCallbacks, void* observerInfo, bool isNewStatistic ) : m_pStatisticName( pStatisticName ) , m_ObserverInfo( observerInfo ) , m_pStatisticsCallbacks( pStatisticsCallbacks ) , m_IsNewStatistic( isNewStatistic ) {} virtual ~StatisticCallbackProcessor( void ) {} virtual bool operator() ( int valueType, const unsigned char* pValue ) { if ( m_pStatisticsCallbacks ) { if ( m_IsNewStatistic ) { if ( m_pStatisticsCallbacks->OnAddedStatistic ) { m_pStatisticsCallbacks->OnAddedStatistic( m_pStatisticName, valueType, pValue, m_ObserverInfo ); } } else { if ( m_pStatisticsCallbacks->OnModifiedStatistic ) { m_pStatisticsCallbacks->OnModifiedStatistic( m_pStatisticName, valueType, pValue, m_ObserverInfo ); } } } return true; }};static boolAreTrackerEntryObserverDataElementsEqual( const void* item1Ptr, const void* item2Ptr ){ const SHXTrackerEntryObserverData* data1 = ( const SHXTrackerEntryObserverData* ) item1Ptr; const SHXTrackerEntryObserverData* data2 = ( const SHXTrackerEntryObserverData* ) item2Ptr; return( ( data1->m_pStatisticsCallbacks == data2->m_pStatisticsCallbacks ) && ( data1->m_ObserverInfo == data2->m_ObserverInfo ) );}boolCHXStatisticTrackerEntry::AddObserver( const char* pStatisticKey, const HXStatisticsCallbacks* pStatisticsCallbacks, void* observerInfo ){ CHXASSERT( pStatisticsCallbacks ); if ( ShouldObserveProperty( pStatisticKey, GetPropName(), true ) ) { if ( !m_pEntryObservers ) { m_pEntryObservers = new CHXFlatArray(sizeof(SHXTrackerEntryObserverData)); } if ( m_pEntryObservers ) { if ( StartWatchingMe() ) { SHXTrackerEntryObserverData observerData = { pStatisticsCallbacks, observerInfo }; if ( m_pEntryObservers->HasRecord( &observerData, AreTrackerEntryObserverDataElementsEqual ) ) { return true; } // Add new observer. m_pEntryObservers->Push( &observerData ); StatisticCallbackProcessor Processor( GetPropName(), pStatisticsCallbacks, observerInfo, true ); ( void ) ProcessStatistic( GetRegistry(), GetPropID(), Processor ); return true; } } } return false;}voidCHXStatisticTrackerEntry::RemoveObserver( const char* pStatisticKey, const HXStatisticsCallbacks* pStatisticsCallbacks, void* observerInfo ){ // XXXSEH: Note - pStatisticKey ignored. If the observer is present, then it can be assumed that ShouldObserveProperty() returned true for it. CHXASSERT( pStatisticsCallbacks ); if ( m_pEntryObservers ) { UINT32 recordNumToRemove; SHXTrackerEntryObserverData observerData = { pStatisticsCallbacks, observerInfo }; if ( m_pEntryObservers->FindRecord( &observerData, AreTrackerEntryObserverDataElementsEqual, 0, &recordNumToRemove ) ) { m_pEntryObservers->Remove( recordNumToRemove ); if ( m_pEntryObservers->IsEmpty() ) { delete m_pEntryObservers; m_pEntryObservers = NULL; StopWatchingMe(); } } }}STDMETHODIMPCHXStatisticTrackerEntry::AddedProp( const UINT32 ulId, const HXPropType propType, const UINT32 ulParentID ){ CHXASSERT( !"Why is AddedProp being called on a non parent property?" ); return HXR_OK; // XXXSEH: What's the return value mean?}STDMETHODIMPCHXStatisticTrackerEntry::ModifiedProp( const UINT32 ulId, const HXPropType propType, const UINT32 ulParentID ){#ifdef LOG_STATISTICS_DEBUG_INFO ExamineProperty( ulId, "Modified property" );#endif if ( m_pEntryObservers ) { UINT32 numOfObservers = m_pEntryObservers->GetCount(); for ( UINT32 index = 0; index < numOfObservers; ++index ) { SHXTrackerEntryObserverData observerData; m_pEntryObservers->GetAt( index, &observerData ); StatisticCallbackProcessor Processor( GetPropName(), observerData.m_pStatisticsCallbacks, observerData.m_ObserverInfo, false ); ( void ) ProcessStatistic( GetRegistry(), GetPropID(), Processor ); } } return HXR_OK; // XXXSEH: What's the return value mean?}STDMETHODIMPCHXStatisticTrackerEntry::DeletedProp( const UINT32 ulId, const UINT32 ulParentID ){#ifdef LOG_STATISTICS_DEBUG_INFO ExamineProperty( ulId, "Deleted property" );#endif if ( m_pEntryObservers ) { UINT32 numOfObservers = m_pEntryObservers->GetCount(); for ( UINT32 index = 0; index < numOfObservers; ++index ) { SHXTrackerEntryObserverData observerData; m_pEntryObservers->GetAt( index, &observerData ); HXOnDeletedStatisticProcPtr OnDeletedStatistic = observerData.m_pStatisticsCallbacks->OnDeletedStatistic; if ( OnDeletedStatistic ) { OnDeletedStatistic( GetPropName(), observerData.m_ObserverInfo ); } } } StopWatchingMe(); return HXR_OK; // XXXSEH: What's the return value mean?}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -