diff options
author | Noel Grandin <noel.grandin@collabora.co.uk> | 2023-10-26 13:36:46 +0200 |
---|---|---|
committer | Noel Grandin <noel.grandin@collabora.co.uk> | 2023-10-26 19:02:53 +0200 |
commit | d2fccf0117a37f8aab8bb50ece419987f06af6b9 (patch) | |
tree | 5949fc5e4d130d91916400240ab519617c7fce4d | |
parent | 96b91357fb93028d35d70bdb52b4bac3ecbfbf57 (diff) |
cool#6893 improve listeners in SfxBaseModel
reduces CPU spent in UNO query'ing, and adds type-safety, which exposed
a bug in SfxBaseModel::disposing
Change-Id: I4b973f7dc38f491ce7a6281ad378e439b5450add
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/158500
Tested-by: Jenkins
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
-rw-r--r-- | sfx2/source/doc/sfxbasemodel.cxx | 106 |
1 files changed, 56 insertions, 50 deletions
diff --git a/sfx2/source/doc/sfxbasemodel.cxx b/sfx2/source/doc/sfxbasemodel.cxx index b085342b1912..03a511fc2fe4 100644 --- a/sfx2/source/doc/sfxbasemodel.cxx +++ b/sfx2/source/doc/sfxbasemodel.cxx @@ -62,6 +62,7 @@ #include <com/sun/star/util/CloseVetoException.hpp> #include <comphelper/enumhelper.hxx> #include <comphelper/indexedpropertyvalues.hxx> +#include <comphelper/interfacecontainer3.hxx> #include <comphelper/string.hxx> #include <cppuhelper/implbase.hxx> @@ -202,7 +203,13 @@ struct IMPL_SfxBaseModel_DataContainer : public ::sfx2::IModifiableDocument OUString m_sURL ; OUString m_sRuntimeUID ; OUString m_aPreusedFilterName ; - comphelper::OMultiTypeInterfaceContainerHelper2 m_aInterfaceContainer ; + comphelper::OInterfaceContainerHelper3<view::XPrintJobListener> m_aPrintJobListeners; + comphelper::OInterfaceContainerHelper3<lang::XEventListener> m_aEventListeners; + comphelper::OInterfaceContainerHelper3<util::XModifyListener> m_aModifyListeners; + comphelper::OInterfaceContainerHelper3<document::XEventListener> m_aDocumentEventListeners1; + comphelper::OInterfaceContainerHelper3<document::XDocumentEventListener> m_aDocumentEventListeners2; + comphelper::OInterfaceContainerHelper3<document::XStorageChangeListener> m_aStorageChangeListeners; + comphelper::OInterfaceContainerHelper3<util::XCloseListener> m_aCloseListeners; std::unordered_map<css::uno::Reference< css::drawing::XShape >, std::vector<css::uno::Reference< css::document::XShapeEventListener >>> maShapeListeners; Reference< XInterface > m_xParent ; @@ -234,8 +241,14 @@ struct IMPL_SfxBaseModel_DataContainer : public ::sfx2::IModifiableDocument IMPL_SfxBaseModel_DataContainer( ::osl::Mutex& rMutex, SfxObjectShell* pObjectShell ) : m_pObjectShell ( pObjectShell ) - , m_aInterfaceContainer ( rMutex ) - , m_nControllerLockCount ( 0 ) + , m_aPrintJobListeners ( rMutex ) + , m_aEventListeners ( rMutex ) + , m_aModifyListeners ( rMutex ) + , m_aDocumentEventListeners1( rMutex ) + , m_aDocumentEventListeners2( rMutex ) + , m_aStorageChangeListeners ( rMutex ) + , m_aCloseListeners ( rMutex ) + , m_nControllerLockCount ( 0 ) , m_bClosed ( false ) , m_bClosing ( false ) , m_bSaving ( false ) @@ -354,12 +367,9 @@ void SAL_CALL SfxPrintHelperListener_Impl::disposing( const lang::EventObject& ) void SAL_CALL SfxPrintHelperListener_Impl::printJobEvent( const view::PrintJobEvent& rEvent ) { - ::comphelper::OInterfaceContainerHelper2* pContainer = m_pData->m_aInterfaceContainer.getContainer( cppu::UnoType<view::XPrintJobListener>::get()); - if ( pContainer!=nullptr ) + if ( m_pData->m_aPrintJobListeners.getLength() ) { - ::comphelper::OInterfaceIteratorHelper2 pIterator(*pContainer); - while (pIterator.hasMoreElements()) - static_cast<view::XPrintJobListener*>(pIterator.next())->printJobEvent( rEvent ); + m_pData->m_aPrintJobListeners.notifyEach(&view::XPrintJobListener::printJobEvent, rEvent); } } @@ -763,7 +773,13 @@ void SAL_CALL SfxBaseModel::dispose() } lang::EventObject aEvent( static_cast<frame::XModel *>(this) ); - m_pData->m_aInterfaceContainer.disposeAndClear( aEvent ); + m_pData->m_aPrintJobListeners.disposeAndClear( aEvent ); + m_pData->m_aEventListeners.disposeAndClear( aEvent ); + m_pData->m_aModifyListeners.disposeAndClear( aEvent ); + m_pData->m_aDocumentEventListeners1.disposeAndClear( aEvent ); + m_pData->m_aDocumentEventListeners2.disposeAndClear( aEvent ); + m_pData->m_aStorageChangeListeners.disposeAndClear( aEvent ); + m_pData->m_aCloseListeners.disposeAndClear( aEvent ); m_pData->m_xDocumentProperties.clear(); @@ -790,7 +806,7 @@ void SAL_CALL SfxBaseModel::dispose() void SAL_CALL SfxBaseModel::addEventListener( const Reference< lang::XEventListener >& aListener ) { SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING ); - m_pData->m_aInterfaceContainer.addInterface( cppu::UnoType<lang::XEventListener>::get(), aListener ); + m_pData->m_aEventListeners.addInterface( aListener ); } @@ -800,7 +816,7 @@ void SAL_CALL SfxBaseModel::addEventListener( const Reference< lang::XEventListe void SAL_CALL SfxBaseModel::removeEventListener( const Reference< lang::XEventListener >& aListener ) { SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING ); - m_pData->m_aInterfaceContainer.removeInterface( cppu::UnoType<lang::XEventListener>::get(), aListener ); + m_pData->m_aEventListeners.removeInterface( aListener ); } void @@ -846,11 +862,11 @@ void SAL_CALL SfxBaseModel::disposing( const lang::EventObject& aObject ) Reference< document::XEventListener > xDocListener( aObject.Source, UNO_QUERY ); if ( xMod.is() ) - m_pData->m_aInterfaceContainer.removeInterface( cppu::UnoType<util::XModifyListener>::get(), xMod ); + m_pData->m_aModifyListeners.removeInterface( xMod ); else if ( xListener.is() ) - m_pData->m_aInterfaceContainer.removeInterface( cppu::UnoType<lang::XEventListener>::get(), xListener ); + m_pData->m_aEventListeners.removeInterface( xListener ); else if ( xDocListener.is() ) - m_pData->m_aInterfaceContainer.removeInterface( cppu::UnoType<document::XEventListener>::get(), xListener ); + m_pData->m_aDocumentEventListeners1.removeInterface( xDocListener ); } @@ -1437,7 +1453,7 @@ void SAL_CALL SfxBaseModel::addModifyListener(const Reference< util::XModifyList { SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING ); - m_pData->m_aInterfaceContainer.addInterface( cppu::UnoType<util::XModifyListener>::get(),xListener ); + m_pData->m_aModifyListeners.addInterface( xListener ); } @@ -1448,7 +1464,7 @@ void SAL_CALL SfxBaseModel::removeModifyListener(const Reference< util::XModifyL { SfxModelGuard aGuard( *this ); - m_pData->m_aInterfaceContainer.removeInterface( cppu::UnoType<util::XModifyListener>::get(), xListener ); + m_pData->m_aModifyListeners.removeInterface( xListener ); } @@ -1463,15 +1479,14 @@ void SAL_CALL SfxBaseModel::close( sal_Bool bDeliverOwnership ) Reference< XInterface > xSelfHold( getXWeak() ); lang::EventObject aSource ( getXWeak() ); - comphelper::OInterfaceContainerHelper2* pContainer = m_pData->m_aInterfaceContainer.getContainer( cppu::UnoType<util::XCloseListener>::get()); - if (pContainer!=nullptr) + if (m_pData->m_aCloseListeners.getLength()) { - comphelper::OInterfaceIteratorHelper2 pIterator(*pContainer); + comphelper::OInterfaceIteratorHelper3 pIterator(m_pData->m_aCloseListeners); while (pIterator.hasMoreElements()) { try { - static_cast<util::XCloseListener*>(pIterator.next())->queryClosing( aSource, bDeliverOwnership ); + pIterator.next()->queryClosing( aSource, bDeliverOwnership ); } catch( RuntimeException& ) { @@ -1491,15 +1506,14 @@ void SAL_CALL SfxBaseModel::close( sal_Bool bDeliverOwnership ) // no own objections against closing! m_pData->m_bClosing = true; - pContainer = m_pData->m_aInterfaceContainer.getContainer( cppu::UnoType<util::XCloseListener>::get()); - if (pContainer!=nullptr) + if (m_pData->m_aCloseListeners.getLength()) { - comphelper::OInterfaceIteratorHelper2 pCloseIterator(*pContainer); + comphelper::OInterfaceIteratorHelper3 pCloseIterator(m_pData->m_aCloseListeners); while (pCloseIterator.hasMoreElements()) { try { - static_cast<util::XCloseListener*>(pCloseIterator.next())->notifyClosing( aSource ); + pCloseIterator.next()->notifyClosing( aSource ); } catch( RuntimeException& ) { @@ -1522,7 +1536,7 @@ void SAL_CALL SfxBaseModel::addCloseListener( const Reference< util::XCloseListe { SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING ); - m_pData->m_aInterfaceContainer.addInterface( cppu::UnoType<util::XCloseListener>::get(), xListener ); + m_pData->m_aCloseListeners.addInterface( xListener ); } @@ -1533,7 +1547,7 @@ void SAL_CALL SfxBaseModel::removeCloseListener( const Reference< util::XCloseLi { SfxModelGuard aGuard( *this ); - m_pData->m_aInterfaceContainer.removeInterface( cppu::UnoType<util::XCloseListener>::get(), xListener ); + m_pData->m_aCloseListeners.removeInterface( xListener ); } @@ -2485,7 +2499,7 @@ void SAL_CALL SfxBaseModel::addEventListener( const Reference< document::XEventL { SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING ); - m_pData->m_aInterfaceContainer.addInterface( cppu::UnoType<document::XEventListener>::get(), aListener ); + m_pData->m_aDocumentEventListeners1.addInterface( aListener ); } @@ -2496,7 +2510,7 @@ void SAL_CALL SfxBaseModel::removeEventListener( const Reference< document::XEve { SfxModelGuard aGuard( *this ); - m_pData->m_aInterfaceContainer.removeInterface( cppu::UnoType<document::XEventListener>::get(), aListener ); + m_pData->m_aEventListeners.removeInterface( aListener ); } // XShapeEventBroadcaster @@ -2537,14 +2551,14 @@ void SAL_CALL SfxBaseModel::removeShapeEventListener( const css::uno::Reference< void SAL_CALL SfxBaseModel::addDocumentEventListener( const Reference< document::XDocumentEventListener >& aListener ) { SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING ); - m_pData->m_aInterfaceContainer.addInterface( cppu::UnoType<document::XDocumentEventListener>::get(), aListener ); + m_pData->m_aDocumentEventListeners2.addInterface( aListener ); } void SAL_CALL SfxBaseModel::removeDocumentEventListener( const Reference< document::XDocumentEventListener >& aListener ) { SfxModelGuard aGuard( *this ); - m_pData->m_aInterfaceContainer.removeInterface( cppu::UnoType<document::XDocumentEventListener>::get(), aListener ); + m_pData->m_aDocumentEventListeners2.removeInterface( aListener ); } @@ -2963,11 +2977,10 @@ void SfxBaseModel::Notify( SfxBroadcaster& rBC , void SfxBaseModel::NotifyModifyListeners_Impl() const { - comphelper::OInterfaceContainerHelper2* pIC = m_pData->m_aInterfaceContainer.getContainer( cppu::UnoType<util::XModifyListener>::get()); - if ( pIC ) + if ( m_pData->m_aModifyListeners.getLength() ) { lang::EventObject aEvent( static_cast<frame::XModel *>(const_cast<SfxBaseModel *>(this)) ); - pIC->notifyEach( &util::XModifyListener::modified, aEvent ); + m_pData->m_aModifyListeners.notifyEach( &util::XModifyListener::modified, aEvent ); } // this notification here is done too generously, we cannot simply assume that we're really modified @@ -3305,28 +3318,25 @@ void SfxBaseModel::postEvent_Impl( const OUString& aName, const Reference< frame if (aName.isEmpty()) return; - comphelper::OInterfaceContainerHelper2* pIC = - xKeepAlive->m_aInterfaceContainer.getContainer( cppu::UnoType<document::XDocumentEventListener>::get()); - if ( pIC ) + if ( xKeepAlive->m_aDocumentEventListeners2.getLength() ) { SAL_INFO("sfx.doc", "SfxDocumentEvent: " + aName); document::DocumentEvent aDocumentEvent( static_cast<frame::XModel*>(this), aName, xController, supplement ); - pIC->forEach< document::XDocumentEventListener, NotifySingleListenerIgnoreRE< document::XDocumentEventListener, document::DocumentEvent > >( + xKeepAlive->m_aDocumentEventListeners2.forEach( NotifySingleListenerIgnoreRE< document::XDocumentEventListener, document::DocumentEvent >( &document::XDocumentEventListener::documentEventOccured, aDocumentEvent ) ); } - pIC = xKeepAlive->m_aInterfaceContainer.getContainer( cppu::UnoType<document::XEventListener>::get()); - if ( pIC ) + if ( xKeepAlive->m_aDocumentEventListeners1.getLength() ) { SAL_INFO("sfx.doc", "SfxEvent: " + aName); document::EventObject aEvent( static_cast<frame::XModel*>(this), aName ); - pIC->forEach< document::XEventListener, NotifySingleListenerIgnoreRE< document::XEventListener, document::EventObject > >( + xKeepAlive->m_aDocumentEventListeners1.forEach( NotifySingleListenerIgnoreRE< document::XEventListener, document::EventObject >( &document::XEventListener::notifyEvent, aEvent ) ); @@ -3386,18 +3396,16 @@ void SfxBaseModel::notifyEvent( const document::EventObject& aEvent ) const if ( impl_isDisposed() ) return; - comphelper::OInterfaceContainerHelper2* pIC = m_pData->m_aInterfaceContainer.getContainer( - cppu::UnoType<document::XEventListener>::get()); - if( !pIC ) + if( !m_pData->m_aDocumentEventListeners1.getLength() ) return; - comphelper::OInterfaceIteratorHelper2 aIt( *pIC ); + comphelper::OInterfaceIteratorHelper3 aIt( m_pData->m_aDocumentEventListeners1 ); while( aIt.hasMoreElements() ) { try { - static_cast<document::XEventListener *>(aIt.next())->notifyEvent( aEvent ); + aIt.next()->notifyEvent( aEvent ); } catch( RuntimeException& ) { @@ -3422,7 +3430,7 @@ void SfxBaseModel::notifyEvent( const document::EventObject& aEvent ) const bool SfxBaseModel::hasEventListeners() const { return !impl_isDisposed() - && ( (nullptr != m_pData->m_aInterfaceContainer.getContainer( cppu::UnoType<document::XEventListener>::get()) ) + && ( m_pData->m_aDocumentEventListeners1.getLength() != 0 || !m_pData->maShapeListeners.empty()); } @@ -3936,8 +3944,7 @@ void SAL_CALL SfxBaseModel::addStorageChangeListener( { SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING ); - m_pData->m_aInterfaceContainer.addInterface( - cppu::UnoType<document::XStorageChangeListener>::get(), xListener ); + m_pData->m_aStorageChangeListeners.addInterface( xListener ); } void SAL_CALL SfxBaseModel::removeStorageChangeListener( @@ -3945,8 +3952,7 @@ void SAL_CALL SfxBaseModel::removeStorageChangeListener( { SfxModelGuard aGuard( *this ); - m_pData->m_aInterfaceContainer.removeInterface( - cppu::UnoType<document::XStorageChangeListener>::get(), xListener ); + m_pData->m_aStorageChangeListeners.removeInterface( xListener ); } void SfxBaseModel::impl_getPrintHelper() |