Kaydet (Commit) 4eb38114 authored tarafından Kohei Yoshida's avatar Kohei Yoshida

pIimplize SfxBroadcaster and SfxListener.

Change-Id: I0d1d73402f11cc61ea9e7629bea34e24c22f5beb
üst a09a7095
...@@ -21,7 +21,6 @@ ...@@ -21,7 +21,6 @@
#include <svl/svldllapi.h> #include <svl/svldllapi.h>
#include <tools/rtti.hxx> #include <tools/rtti.hxx>
#include <vector>
class SfxListener; class SfxListener;
class SfxHint; class SfxHint;
...@@ -29,11 +28,8 @@ class SfxBroadcasterTest; ...@@ -29,11 +28,8 @@ class SfxBroadcasterTest;
class SVL_DLLPUBLIC SfxBroadcaster class SVL_DLLPUBLIC SfxBroadcaster
{ {
typedef std::vector<SfxListener*> SfxListenerArr_Impl; struct Impl;
Impl* mpImpl;
/** Contains the positions of removed listeners. */
std::vector<size_t> m_RemovedPositions;
SfxListenerArr_Impl m_Listeners;
private: private:
void AddListener( SfxListener& rListener ); void AddListener( SfxListener& rListener );
...@@ -60,16 +56,12 @@ public: ...@@ -60,16 +56,12 @@ public:
/** Get the size of the internally stored vector. /** Get the size of the internally stored vector.
* Use it to iterate over all listeners. * Use it to iterate over all listeners.
*/ */
size_t GetSizeOfVector() const { size_t GetSizeOfVector() const;
return m_Listeners.size();
}
/** Get a listener by its position in the internally stored vector. /** Get a listener by its position in the internally stored vector.
* Note that this method may return NULL * Note that this method may return NULL
*/ */
SfxListener* GetListener( size_t nNo ) const { SfxListener* GetListener( size_t nNo ) const;
return m_Listeners[nNo];
}
friend class SfxListener; friend class SfxListener;
friend class ::SfxBroadcasterTest; friend class ::SfxBroadcasterTest;
......
...@@ -21,21 +21,17 @@ ...@@ -21,21 +21,17 @@
#include <svl/svldllapi.h> #include <svl/svldllapi.h>
#include <tools/rtti.hxx> #include <tools/rtti.hxx>
#include <deque>
class SfxBroadcaster; class SfxBroadcaster;
class SfxHint; class SfxHint;
typedef std::deque<SfxBroadcaster*> SfxBroadcasterArr_Impl;
#define SFX_NOTIFY( rBC, rBCT, rHint, rHintT ) \ #define SFX_NOTIFY( rBC, rBCT, rHint, rHintT ) \
Notify( rBC, rHint ) Notify( rBC, rHint )
class SVL_DLLPUBLIC SfxListener class SVL_DLLPUBLIC SfxListener
{ {
SfxBroadcasterArr_Impl aBCs; struct Impl;
Impl* mpImpl;
private: private:
const SfxListener& operator=(const SfxListener &); // n.i., ist verboten const SfxListener& operator=(const SfxListener &); // n.i., ist verboten
...@@ -52,10 +48,8 @@ public: ...@@ -52,10 +48,8 @@ public:
void EndListeningAll(); void EndListeningAll();
bool IsListening( SfxBroadcaster& rBroadcaster ) const; bool IsListening( SfxBroadcaster& rBroadcaster ) const;
sal_uInt16 GetBroadcasterCount() const sal_uInt16 GetBroadcasterCount() const;
{ return aBCs.size(); } SfxBroadcaster* GetBroadcasterJOE( sal_uInt16 nNo ) const;
SfxBroadcaster* GetBroadcasterJOE( sal_uInt16 nNo ) const
{ return aBCs[nNo]; }
virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ); virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
......
...@@ -17,29 +17,38 @@ ...@@ -17,29 +17,38 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 . * the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/ */
#include <assert.h> #include <svl/SfxBroadcaster.hxx>
#include <svl/hint.hxx> #include <svl/hint.hxx>
#include <svl/smplhint.hxx> #include <svl/smplhint.hxx>
#include <svl/lstner.hxx> #include <svl/lstner.hxx>
#include <tools/debug.hxx>
#include <svl/SfxBroadcaster.hxx>
#include <algorithm> #include <algorithm>
#include <tools/debug.hxx> #include <cassert>
#include <vector>
TYPEINIT0(SfxBroadcaster); TYPEINIT0(SfxBroadcaster);
typedef std::vector<SfxListener*> SfxListenerArr_Impl;
struct SfxBroadcaster::Impl
{
/** Contains the positions of removed listeners. */
std::vector<size_t> m_RemovedPositions;
SfxListenerArr_Impl m_Listeners;
};
// broadcast immediately // broadcast immediately
void SfxBroadcaster::Broadcast( const SfxHint &rHint ) void SfxBroadcaster::Broadcast( const SfxHint &rHint )
{ {
// notify all registered listeners exactly once // notify all registered listeners exactly once
for (size_t n = 0; n < m_Listeners.size(); ++n) for (size_t i = 0; i < mpImpl->m_Listeners.size(); ++i)
{ {
SfxListener *const pListener = m_Listeners[n]; SfxListener *const pListener = mpImpl->m_Listeners[i];
if (pListener) { if (pListener)
pListener->Notify( *this, rHint ); pListener->Notify( *this, rHint );
}
} }
} }
...@@ -50,19 +59,20 @@ SfxBroadcaster::~SfxBroadcaster() ...@@ -50,19 +59,20 @@ SfxBroadcaster::~SfxBroadcaster()
Broadcast( SfxSimpleHint(SFX_HINT_DYING) ); Broadcast( SfxSimpleHint(SFX_HINT_DYING) );
// remove all still registered listeners // remove all still registered listeners
for (size_t nPos = 0; nPos < m_Listeners.size(); ++nPos) for (size_t i = 0; i < mpImpl->m_Listeners.size(); ++i)
{ {
SfxListener *const pListener = m_Listeners[nPos]; SfxListener *const pListener = mpImpl->m_Listeners[i];
if (pListener) { if (pListener)
pListener->RemoveBroadcaster_Impl(*this); pListener->RemoveBroadcaster_Impl(*this);
}
} }
delete mpImpl;
} }
// simple ctor of class SfxBroadcaster // simple ctor of class SfxBroadcaster
SfxBroadcaster::SfxBroadcaster() SfxBroadcaster::SfxBroadcaster() : mpImpl(new Impl)
{ {
} }
...@@ -70,14 +80,13 @@ SfxBroadcaster::SfxBroadcaster() ...@@ -70,14 +80,13 @@ SfxBroadcaster::SfxBroadcaster()
// copy ctor of class SfxBroadcaster // copy ctor of class SfxBroadcaster
SfxBroadcaster::SfxBroadcaster( const SfxBroadcaster &rBC ) SfxBroadcaster::SfxBroadcaster( const SfxBroadcaster &rBC ) : mpImpl(new Impl)
{ {
for (size_t n = 0; n < rBC.m_Listeners.size(); ++n) for (size_t i = 0; i < rBC.mpImpl->m_Listeners.size(); ++i)
{ {
SfxListener *const pListener = rBC.m_Listeners[n]; SfxListener *const pListener = rBC.mpImpl->m_Listeners[i];
if (pListener) { if (pListener)
pListener->StartListening( *this ); pListener->StartListening( *this );
}
} }
} }
...@@ -87,14 +96,16 @@ SfxBroadcaster::SfxBroadcaster( const SfxBroadcaster &rBC ) ...@@ -87,14 +96,16 @@ SfxBroadcaster::SfxBroadcaster( const SfxBroadcaster &rBC )
void SfxBroadcaster::AddListener( SfxListener& rListener ) void SfxBroadcaster::AddListener( SfxListener& rListener )
{ {
DBG_TESTSOLARMUTEX(); DBG_TESTSOLARMUTEX();
if (m_RemovedPositions.empty()) { if (mpImpl->m_RemovedPositions.empty())
m_Listeners.push_back(&rListener); {
mpImpl->m_Listeners.push_back(&rListener);
} }
else { else
size_t targetPosition = m_RemovedPositions.back(); {
m_RemovedPositions.pop_back(); size_t targetPosition = mpImpl->m_RemovedPositions.back();
assert(m_Listeners[targetPosition] == NULL); mpImpl->m_RemovedPositions.pop_back();
m_Listeners[targetPosition] = &rListener; assert(mpImpl->m_Listeners[targetPosition] == NULL);
mpImpl->m_Listeners[targetPosition] = &rListener;
} }
} }
...@@ -110,12 +121,11 @@ void SfxBroadcaster::ListenersGone() ...@@ -110,12 +121,11 @@ void SfxBroadcaster::ListenersGone()
void SfxBroadcaster::Forward(SfxBroadcaster& rBC, const SfxHint& rHint) void SfxBroadcaster::Forward(SfxBroadcaster& rBC, const SfxHint& rHint)
{ {
for (size_t i = 0; i < m_Listeners.size(); ++i) for (size_t i = 0; i < mpImpl->m_Listeners.size(); ++i)
{ {
SfxListener *const pListener = m_Listeners[i]; SfxListener *const pListener = mpImpl->m_Listeners[i];
if (pListener) { if (pListener)
pListener->Notify( rBC, rHint ); pListener->Notify( rBC, rHint );
}
} }
} }
...@@ -126,13 +136,13 @@ void SfxBroadcaster::RemoveListener( SfxListener& rListener ) ...@@ -126,13 +136,13 @@ void SfxBroadcaster::RemoveListener( SfxListener& rListener )
{ {
DBG_TESTSOLARMUTEX(); DBG_TESTSOLARMUTEX();
SfxListenerArr_Impl::iterator aIter = std::find( SfxListenerArr_Impl::iterator aIter = std::find(
m_Listeners.begin(), m_Listeners.end(), &rListener); mpImpl->m_Listeners.begin(), mpImpl->m_Listeners.end(), &rListener);
assert(aIter != m_Listeners.end()); // "RemoveListener: Listener unknown" assert(aIter != mpImpl->m_Listeners.end()); // "RemoveListener: Listener unknown"
// DO NOT erase the listener, set the pointer to 0 // DO NOT erase the listener, set the pointer to 0
// because the current continuation may contain this->Broadcast // because the current continuation may contain this->Broadcast
*aIter = 0; *aIter = 0;
size_t positionOfRemovedElement = std::distance(m_Listeners.begin(), aIter); size_t positionOfRemovedElement = std::distance(mpImpl->m_Listeners.begin(), aIter);
m_RemovedPositions.push_back(positionOfRemovedElement); mpImpl->m_RemovedPositions.push_back(positionOfRemovedElement);
if ( !HasListeners() ) if ( !HasListeners() )
ListenersGone(); ListenersGone();
...@@ -145,8 +155,18 @@ bool SfxBroadcaster::HasListeners() const ...@@ -145,8 +155,18 @@ bool SfxBroadcaster::HasListeners() const
size_t SfxBroadcaster::GetListenerCount() const size_t SfxBroadcaster::GetListenerCount() const
{ {
assert(m_Listeners.size() >= m_RemovedPositions.size()); assert(mpImpl->m_Listeners.size() >= mpImpl->m_RemovedPositions.size());
return m_Listeners.size() - m_RemovedPositions.size(); return mpImpl->m_Listeners.size() - mpImpl->m_RemovedPositions.size();
}
size_t SfxBroadcaster::GetSizeOfVector() const
{
return mpImpl->m_Listeners.size();
}
SfxListener* SfxBroadcaster::GetListener( size_t nNo ) const
{
return mpImpl->m_Listeners[nNo];
} }
......
...@@ -24,21 +24,29 @@ ...@@ -24,21 +24,29 @@
#include <algorithm> #include <algorithm>
#include <cassert> #include <cassert>
#include <deque>
TYPEINIT0(SfxListener); TYPEINIT0(SfxListener);
typedef std::deque<SfxBroadcaster*> SfxBroadcasterArr_Impl;
struct SfxListener::Impl
{
SfxBroadcasterArr_Impl maBCs;
};
// simple ctor of class SfxListener // simple ctor of class SfxListener
SfxListener::SfxListener() SfxListener::SfxListener() : mpImpl(new Impl)
{ {
} }
// copy ctor of class SfxListener // copy ctor of class SfxListener
SfxListener::SfxListener( const SfxListener &rListener ) SfxListener::SfxListener( const SfxListener &rListener ) : mpImpl(new Impl)
{ {
for ( sal_uInt16 n = 0; n < rListener.aBCs.size(); ++n ) for ( sal_uInt16 n = 0; n < rListener.mpImpl->maBCs.size(); ++n )
StartListening( *rListener.aBCs[n] ); StartListening( *rListener.mpImpl->maBCs[n] );
} }
// unregisters the SfxListener from its SfxBroadcasters // unregisters the SfxListener from its SfxBroadcasters
...@@ -46,11 +54,13 @@ SfxListener::SfxListener( const SfxListener &rListener ) ...@@ -46,11 +54,13 @@ SfxListener::SfxListener( const SfxListener &rListener )
SfxListener::~SfxListener() SfxListener::~SfxListener()
{ {
// unregister at all remaining broadcasters // unregister at all remaining broadcasters
for ( sal_uInt16 nPos = 0; nPos < aBCs.size(); ++nPos ) for ( sal_uInt16 nPos = 0; nPos < mpImpl->maBCs.size(); ++nPos )
{ {
SfxBroadcaster *pBC = aBCs[nPos]; SfxBroadcaster *pBC = mpImpl->maBCs[nPos];
pBC->RemoveListener(*this); pBC->RemoveListener(*this);
} }
delete mpImpl;
} }
...@@ -58,7 +68,7 @@ SfxListener::~SfxListener() ...@@ -58,7 +68,7 @@ SfxListener::~SfxListener()
void SfxListener::RemoveBroadcaster_Impl( SfxBroadcaster& rBroadcaster ) void SfxListener::RemoveBroadcaster_Impl( SfxBroadcaster& rBroadcaster )
{ {
aBCs.erase( std::find( aBCs.begin(), aBCs.end(), &rBroadcaster ) ); mpImpl->maBCs.erase( std::find( mpImpl->maBCs.begin(), mpImpl->maBCs.end(), &rBroadcaster ) );
} }
...@@ -69,7 +79,7 @@ void SfxListener::StartListening( SfxBroadcaster& rBroadcaster, bool bPreventDup ...@@ -69,7 +79,7 @@ void SfxListener::StartListening( SfxBroadcaster& rBroadcaster, bool bPreventDup
if ( !bPreventDups || !IsListening( rBroadcaster ) ) if ( !bPreventDups || !IsListening( rBroadcaster ) )
{ {
rBroadcaster.AddListener(*this); rBroadcaster.AddListener(*this);
aBCs.push_back( &rBroadcaster ); mpImpl->maBCs.push_back( &rBroadcaster );
assert(IsListening(rBroadcaster) && "StartListening failed"); assert(IsListening(rBroadcaster) && "StartListening failed");
} }
...@@ -82,13 +92,13 @@ void SfxListener::EndListening( SfxBroadcaster& rBroadcaster, bool bAllDups ) ...@@ -82,13 +92,13 @@ void SfxListener::EndListening( SfxBroadcaster& rBroadcaster, bool bAllDups )
{ {
do do
{ {
SfxBroadcasterArr_Impl::iterator it = std::find( aBCs.begin(), aBCs.end(), &rBroadcaster ); SfxBroadcasterArr_Impl::iterator it = std::find( mpImpl->maBCs.begin(), mpImpl->maBCs.end(), &rBroadcaster );
if ( it == aBCs.end() ) if ( it == mpImpl->maBCs.end() )
{ {
break; break;
} }
rBroadcaster.RemoveListener(*this); rBroadcaster.RemoveListener(*this);
aBCs.erase( it ); mpImpl->maBCs.erase( it );
} }
while ( bAllDups ); while ( bAllDups );
} }
...@@ -99,18 +109,28 @@ void SfxListener::EndListening( SfxBroadcaster& rBroadcaster, bool bAllDups ) ...@@ -99,18 +109,28 @@ void SfxListener::EndListening( SfxBroadcaster& rBroadcaster, bool bAllDups )
void SfxListener::EndListeningAll() void SfxListener::EndListeningAll()
{ {
// Attention: when optimizing this: Respect sideffects of RemoveListener! // Attention: when optimizing this: Respect sideffects of RemoveListener!
while ( !aBCs.empty() ) while ( !mpImpl->maBCs.empty() )
{ {
SfxBroadcaster *pBC = aBCs.front(); SfxBroadcaster *pBC = mpImpl->maBCs.front();
pBC->RemoveListener(*this); pBC->RemoveListener(*this);
aBCs.pop_front(); mpImpl->maBCs.pop_front();
} }
} }
bool SfxListener::IsListening( SfxBroadcaster& rBroadcaster ) const bool SfxListener::IsListening( SfxBroadcaster& rBroadcaster ) const
{ {
return aBCs.end() != std::find( aBCs.begin(), aBCs.end(), &rBroadcaster ); return mpImpl->maBCs.end() != std::find( mpImpl->maBCs.begin(), mpImpl->maBCs.end(), &rBroadcaster );
}
sal_uInt16 SfxListener::GetBroadcasterCount() const
{
return mpImpl->maBCs.size();
}
SfxBroadcaster* SfxListener::GetBroadcasterJOE( sal_uInt16 nNo ) const
{
return mpImpl->maBCs[nNo];
} }
......
...@@ -72,6 +72,8 @@ ...@@ -72,6 +72,8 @@
#include <unobaseclass.hxx> #include <unobaseclass.hxx>
#include <viewopt.hxx> #include <viewopt.hxx>
#include <deque>
#define __IFC32 Ifc1, Ifc2, Ifc3, Ifc4, Ifc5, Ifc6, Ifc7, Ifc8, Ifc9, Ifc10, Ifc11, Ifc12, Ifc13, Ifc14, Ifc15, Ifc16, \ #define __IFC32 Ifc1, Ifc2, Ifc3, Ifc4, Ifc5, Ifc6, Ifc7, Ifc8, Ifc9, Ifc10, Ifc11, Ifc12, Ifc13, Ifc14, Ifc15, Ifc16, \
Ifc17, Ifc18, Ifc19, Ifc20, Ifc21, Ifc22, Ifc23, Ifc24, Ifc25, Ifc26, Ifc27, Ifc28, Ifc29, Ifc30, Ifc31, Ifc32 Ifc17, Ifc18, Ifc19, Ifc20, Ifc21, Ifc22, Ifc23, Ifc24, Ifc25, Ifc26, Ifc27, Ifc28, Ifc29, Ifc30, Ifc31, Ifc32
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment