diff options
author | Tobias Lippert <drtl@fastmail.fm> | 2014-07-18 15:36:30 +0200 |
---|---|---|
committer | Noel Grandin <noelgrandin@gmail.com> | 2014-07-22 06:26:06 +0000 |
commit | 798379313dca8de97e431ef2fe68129aaa1dcf04 (patch) | |
tree | dd9e0a372e2fa1f59608a125c04faecb416bf9a6 | |
parent | 312926823dc6da7e87eb60c98ba084f14f0aa676 (diff) |
fdo#76754 Speed up registration of new listeners to SfxBroadcaster
Also change behavior for the GetListenerCount() method which now
returns the count of listeners.
The previous behavior is available in method GetSizeOfVector().
Change-Id: I5b03fa55a309f4ff5aea5e8830c137786fc07e89
Reviewed-on: https://gerrit.libreoffice.org/10344
Reviewed-by: Noel Grandin <noelgrandin@gmail.com>
Tested-by: Noel Grandin <noelgrandin@gmail.com>
-rw-r--r-- | include/svl/SfxBroadcaster.hxx | 19 | ||||
-rw-r--r-- | sd/source/core/stlpool.cxx | 2 | ||||
-rw-r--r-- | sd/source/core/stlsheet.cxx | 2 | ||||
-rw-r--r-- | svl/qa/unit/notify/test_SfxBroadcaster.cxx | 2 | ||||
-rw-r--r-- | svl/source/notify/SfxBroadcaster.cxx | 33 | ||||
-rw-r--r-- | svx/source/svdraw/svdmark.cxx | 2 | ||||
-rw-r--r-- | svx/source/svdraw/svdviter.cxx | 2 | ||||
-rw-r--r-- | sw/source/core/unocore/unostyle.cxx | 2 |
8 files changed, 39 insertions, 25 deletions
diff --git a/include/svl/SfxBroadcaster.hxx b/include/svl/SfxBroadcaster.hxx index 5c135b5dfca2..a29a5c008798 100644 --- a/include/svl/SfxBroadcaster.hxx +++ b/include/svl/SfxBroadcaster.hxx @@ -31,6 +31,8 @@ class SVL_DLLPUBLIC SfxBroadcaster { typedef std::vector<SfxListener*> SfxListenerArr_Impl; + /** Contains the positions of removed listeners. */ + std::vector<size_t> m_RemovedPositions; SfxListenerArr_Impl m_Listeners; private: @@ -51,12 +53,21 @@ public: void Broadcast( const SfxHint &rHint ); bool HasListeners() const; - size_t GetListenerCount() const - { + + /** Get the number of listeners which are registered at this broadcaster */ + size_t GetListenerCount() const; + + /** Get the size of the internally stored vector. + * Use it to iterate over all listeners. + */ + size_t GetSizeOfVector() const { return m_Listeners.size(); } - SfxListener* GetListener( size_t nNo ) const - { + + /** Get a listener by its position in the internally stored vector. + * Note that this method may return NULL + */ + SfxListener* GetListener( size_t nNo ) const { return m_Listeners[nNo]; } diff --git a/sd/source/core/stlpool.cxx b/sd/source/core/stlpool.cxx index bee0b1efd394..cb11f738ccea 100644 --- a/sd/source/core/stlpool.cxx +++ b/sd/source/core/stlpool.cxx @@ -1440,7 +1440,7 @@ SdStyleSheetVector SdStyleSheetPool::CreateChildList( SdStyleSheet* pSheet ) { SdStyleSheetVector aResult; - const size_t nListenerCount = pSheet->GetListenerCount(); + const size_t nListenerCount = pSheet->GetSizeOfVector(); for (size_t n = 0; n < nListenerCount; ++n) { SdStyleSheet* pChild = dynamic_cast< SdStyleSheet* >( pSheet->GetListener(n) ); diff --git a/sd/source/core/stlsheet.cxx b/sd/source/core/stlsheet.cxx index 54925994da00..4246e31b12ff 100644 --- a/sd/source/core/stlsheet.cxx +++ b/sd/source/core/stlsheet.cxx @@ -325,7 +325,7 @@ bool SdStyleSheet::IsUsed() const { bool bResult = false; - const size_t nListenerCount = GetListenerCount(); + const size_t nListenerCount = GetSizeOfVector(); for (size_t n = 0; n < nListenerCount; ++n) { SfxListener* pListener = GetListener(n); diff --git a/svl/qa/unit/notify/test_SfxBroadcaster.cxx b/svl/qa/unit/notify/test_SfxBroadcaster.cxx index 8139ed1eba2d..60960295ccc7 100644 --- a/svl/qa/unit/notify/test_SfxBroadcaster.cxx +++ b/svl/qa/unit/notify/test_SfxBroadcaster.cxx @@ -26,7 +26,7 @@ class SfxBroadcasterTest : public CppUnit::TestFixture // Adds code needed to register the test suite CPPUNIT_TEST_SUITE(SfxBroadcasterTest); CPPUNIT_TEST(AddingListenersIncreasesCount); - //CPPUNIT_TEST(RemovingListenersDecreasesCount); + CPPUNIT_TEST(RemovingListenersDecreasesCount); CPPUNIT_TEST(HintsAreNotForwardedToRemovedListeners); CPPUNIT_TEST_SUITE_END(); diff --git a/svl/source/notify/SfxBroadcaster.cxx b/svl/source/notify/SfxBroadcaster.cxx index 2fe79033b3b7..3aa493d19a84 100644 --- a/svl/source/notify/SfxBroadcaster.cxx +++ b/svl/source/notify/SfxBroadcaster.cxx @@ -88,15 +88,15 @@ SfxBroadcaster::SfxBroadcaster( const SfxBroadcaster &rBC ) void SfxBroadcaster::AddListener( SfxListener& rListener ) { - for (size_t i = 0; i < m_Listeners.size(); ++i) - { - if (!m_Listeners[i]) // removed by RemoveListener? - { - m_Listeners[i] = &rListener; - return; - } + if (m_RemovedPositions.empty()) { + m_Listeners.push_back(&rListener); + } + else { + size_t targetPosition = m_RemovedPositions.back(); + m_RemovedPositions.pop_back(); + assert(m_Listeners[targetPosition] == NULL); + m_Listeners[targetPosition] = &rListener; } - m_Listeners.push_back(&rListener); } @@ -131,6 +131,8 @@ void SfxBroadcaster::RemoveListener( SfxListener& rListener ) // DO NOT erase the listener, set the pointer to 0 // because the current continuation may contain this->Broadcast *aIter = 0; + size_t positionOfRemovedElement = std::distance(m_Listeners.begin(), aIter); + m_RemovedPositions.push_back(positionOfRemovedElement); if ( !HasListeners() ) ListenersGone(); @@ -138,13 +140,14 @@ void SfxBroadcaster::RemoveListener( SfxListener& rListener ) bool SfxBroadcaster::HasListeners() const { - for (size_t i = 0; i < m_Listeners.size(); ++i) - { - if (m_Listeners[i]) { - return true; - } - } - return false; + return (GetListenerCount() != 0); +} + +size_t SfxBroadcaster::GetListenerCount() const +{ + assert(m_Listeners.size() >= m_RemovedPositions.size()); + return m_Listeners.size() - m_RemovedPositions.size(); } + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/svdraw/svdmark.cxx b/svx/source/svdraw/svdmark.cxx index 212fdeecf3f1..2908b83070e4 100644 --- a/svx/source/svdraw/svdmark.cxx +++ b/svx/source/svdraw/svdmark.cxx @@ -873,7 +873,7 @@ namespace sdr if(pBC) { - const size_t nLstAnz(pBC->GetListenerCount()); + const size_t nLstAnz(pBC->GetSizeOfVector()); for(size_t nl=0; nl < nLstAnz; ++nl) { diff --git a/svx/source/svdraw/svdviter.cxx b/svx/source/svdraw/svdviter.cxx index 12db065a0d98..f7bc7005d9a9 100644 --- a/svx/source/svdraw/svdviter.cxx +++ b/svx/source/svdraw/svdviter.cxx @@ -140,7 +140,7 @@ SdrView* SdrViewIter::ImpFindView() { if(mpModel) { - const size_t nLsAnz(mpModel->GetListenerCount()); + const size_t nLsAnz(mpModel->GetSizeOfVector()); while(mnListenerNum < nLsAnz) { diff --git a/sw/source/core/unocore/unostyle.cxx b/sw/source/core/unocore/unostyle.cxx index c3ec4a4f4895..a58cf4c08140 100644 --- a/sw/source/core/unocore/unostyle.cxx +++ b/sw/source/core/unocore/unostyle.cxx @@ -987,7 +987,7 @@ void SwXStyleFamily::Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) SwXStyle* SwXStyleFamily::_FindStyle(const OUString& rStyleName)const { - const size_t nLCount = pBasePool->GetListenerCount(); + const size_t nLCount = pBasePool->GetSizeOfVector(); for( size_t i = 0; i < nLCount; ++i) { SfxListener* pListener = pBasePool->GetListener( i ); |