diff options
author | Kohei Yoshida <kohei.yoshida@collabora.com> | 2013-11-13 20:33:50 -0500 |
---|---|---|
committer | Kohei Yoshida <kohei.yoshida@collabora.com> | 2013-11-14 23:53:50 -0500 |
commit | 18d07b2affbbbfb2ff9152d3ad8d1744fe75ab47 (patch) | |
tree | 49e285fe010f073c89f92f321397a495902f78a5 /svl | |
parent | d7867b28623e4220f62b8ed9259bed5d8878a3b3 (diff) |
Rework SvtListener and SvtBroadcaster internals.
The old code was simply awkward.
Change-Id: I1a58a9af86c100be238d306570b40f70c5100314
Diffstat (limited to 'svl')
-rw-r--r-- | svl/Library_svl.mk | 2 | ||||
-rw-r--r-- | svl/source/notify/broadcast.cxx | 109 | ||||
-rw-r--r-- | svl/source/notify/listener.cxx | 115 | ||||
-rw-r--r-- | svl/source/notify/listenerbase.cxx | 66 | ||||
-rw-r--r-- | svl/source/notify/listenerbase.hxx | 50 | ||||
-rw-r--r-- | svl/source/notify/listeneriter.cxx | 105 |
6 files changed, 92 insertions, 355 deletions
diff --git a/svl/Library_svl.mk b/svl/Library_svl.mk index 283e06b3b25a..d6d83b5e0ceb 100644 --- a/svl/Library_svl.mk +++ b/svl/Library_svl.mk @@ -119,8 +119,6 @@ $(eval $(call gb_Library_add_exception_objects,svl,\ svl/source/notify/hint \ svl/source/notify/isethint \ svl/source/notify/listener \ - svl/source/notify/listenerbase \ - svl/source/notify/listeneriter \ svl/source/notify/lstner \ svl/source/notify/smplhint \ svl/source/numbers/numfmuno \ diff --git a/svl/source/notify/broadcast.cxx b/svl/source/notify/broadcast.cxx index 4cdaa1425a60..79c17578e25d 100644 --- a/svl/source/notify/broadcast.cxx +++ b/svl/source/notify/broadcast.cxx @@ -17,85 +17,94 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ - -#include <svl/listener.hxx> -#include <svl/listeneriter.hxx> #include <svl/broadcast.hxx> +#include <svl/listener.hxx> #include <svl/smplhint.hxx> +namespace { -TYPEINIT0(SvtBroadcaster); +class StartListeningHandler : std::unary_function<SvtListener*, void> +{ + SvtBroadcaster& mrBC; +public: + StartListeningHandler( SvtBroadcaster& rBC ) : mrBC(rBC) {} + void operator() ( SvtListener* p ) + { + p->StartListening(mrBC); + } +}; -// simple ctor of class SvtBroadcaster +class EndListeningHandler : std::unary_function<SvtListener*, void> +{ + SvtBroadcaster& mrBC; +public: + EndListeningHandler( SvtBroadcaster& rBC ) : mrBC(rBC) {} -SvtBroadcaster::SvtBroadcaster() - : pRoot( 0 ) + void operator() ( SvtListener* p ) + { + p->EndListening(mrBC); + } +}; + +class NotifyHandler : std::unary_function<SvtListener*, void> { -} + SvtBroadcaster& mrBC; + const SfxHint& mrHint; +public: + NotifyHandler( SvtBroadcaster& rBC, const SfxHint& rHint ) : mrBC(rBC), mrHint(rHint) {} + + void operator() ( SvtListener* p ) + { + p->Notify(mrBC, mrHint); + } +}; +} -// copy ctor of class SvtBroadcaster +void SvtBroadcaster::Add( SvtListener* p ) +{ + maListeners.insert(p); +} -SvtBroadcaster::SvtBroadcaster( const SvtBroadcaster &rBC ) - : pRoot( 0 ) +void SvtBroadcaster::Remove( SvtListener* p ) { - SvtListenerIter aIter( (SvtBroadcaster&)rBC ); - SvtListener* pLast = aIter.GoStart(); - if( pLast ) - do { - pLast->StartListening( *this ); - } while( 0 != ( pLast = aIter.GoNext() )); + maListeners.erase(p); + if (maListeners.empty()) + ListenersGone(); } +SvtBroadcaster::SvtBroadcaster() {} -// unregister all listeners +SvtBroadcaster::SvtBroadcaster( const SvtBroadcaster &rBC ) : + maListeners(rBC.maListeners) +{ + std::for_each(maListeners.begin(), maListeners.end(), StartListeningHandler(*this)); +} SvtBroadcaster::~SvtBroadcaster() { Broadcast( SfxSimpleHint(SFX_HINT_DYING) ); - SvtListenerIter aIter( *this ); - SvtListener* pLast = aIter.GoStart(); - if( pLast ) - do { - pLast->EndListening( *this ); - if( !HasListeners() ) // all gone ?? - break; - } while( 0 != ( pLast = aIter.GoNext() )); + // unregister all listeners. + std::for_each(maListeners.begin(), maListeners.end(), EndListeningHandler(*this)); } - -// broadcast immedeately - void SvtBroadcaster::Broadcast( const SfxHint &rHint ) { - // is anybody to notify? - if( HasListeners() /* && !IsModifyLocked()*/ ) - { -// LockModify(); -// bInModify = sal_True; - - SvtListenerIter aIter( *this ); - SvtListener* pLast = aIter.GoStart(); - if( pLast ) - do { - pLast->Notify( *this, rHint ); - if( !HasListeners() ) // all gone ?? - break; - } while( 0 != ( pLast = aIter.GoNext() )); - -// bInModify = sal_False; -// UnlockModify(); - } + std::for_each(maListeners.begin(), maListeners.end(), NotifyHandler(*this, rHint)); } +void SvtBroadcaster::ListenersGone() {} +SvtBroadcaster::ListenersType& SvtBroadcaster::GetAllListeners() +{ + return maListeners; +} -// called, if no more listeners exists - -void SvtBroadcaster::ListenersGone() +bool SvtBroadcaster::HasListeners() const { + return !maListeners.empty(); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svl/source/notify/listener.cxx b/svl/source/notify/listener.cxx index fd8616df4f51..59d3ef9f3352 100644 --- a/svl/source/notify/listener.cxx +++ b/svl/source/notify/listener.cxx @@ -17,117 +17,68 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ - -#include <tools/debug.hxx> -#include <svl/broadcast.hxx> #include <svl/listener.hxx> -#include "listenerbase.hxx" -#include <svl/listeneriter.hxx> - - -TYPEINIT0(SvtListener); - -// simple ctor of class SvtListener - -SvtListener::SvtListener() - : pBrdCastLst( 0 ) -{ -} - -// copy ctor of class SvtListener +#include <svl/broadcast.hxx> +#include <tools/debug.hxx> -SvtListener::SvtListener( const SvtListener &rListener ) - : pBrdCastLst( 0 ) -{ - SvtListenerBase* pLst = rListener.pBrdCastLst; - while( pLst ) - { - new SvtListenerBase( *this, *pLst->GetBroadcaster() ); - pLst = pLst->GetNext(); - } -} +SvtListener::SvtListener() {} -// unregisteres the SvtListener from its SvtBroadcasters +SvtListener::SvtListener( const SvtListener &r ) : + maBroadcasters(r.maBroadcasters) {} SvtListener::~SvtListener() { + // Unregister itself from all broadcasters it's listening to. EndListeningAll(); } - // registeres at a specific SvtBroadcaster -sal_Bool SvtListener::StartListening( SvtBroadcaster& rBroadcaster ) +bool SvtListener::StartListening( SvtBroadcaster& rBroadcaster ) { - const SvtListenerBase* pLst = pBrdCastLst; - while( pLst ) + std::pair<BroadcastersType::iterator, bool> r = + maBroadcasters.insert(&rBroadcaster); + if (r.second) { - if( &rBroadcaster == pLst->GetBroadcaster() ) - { - // double, than return - return sal_False; - } - pLst = pLst->GetNext(); + // This is a new broadcaster. + rBroadcaster.Add(this); } - new SvtListenerBase( *this, rBroadcaster ); - return sal_True; + return r.second; } - -// unregisteres at a specific SvtBroadcaster - -sal_Bool SvtListener::EndListening( SvtBroadcaster& rBroadcaster ) +bool SvtListener::EndListening( SvtBroadcaster& rBroadcaster ) { - SvtListenerBase *pLst = pBrdCastLst, *pPrev = pLst; - while( pLst ) - { - if( &rBroadcaster == pLst->GetBroadcaster() ) - { - if( pBrdCastLst == pLst ) - pBrdCastLst = pLst->GetNext(); - else - pPrev->SetNext( pLst->GetNext() ); - - delete pLst; - return sal_True; - } - pPrev = pLst; - pLst = pLst->GetNext(); - } - return sal_False; + BroadcastersType::iterator it = maBroadcasters.find(&rBroadcaster); + if (it == maBroadcasters.end()) + // Not listening to this broadcaster. + return false; + + rBroadcaster.Remove(this); + maBroadcasters.erase(it); + return true; } - -// unregisteres all Broadcasters - void SvtListener::EndListeningAll() { - SvtListenerBase *pLst = pBrdCastLst; - while( pLst ) + BroadcastersType::iterator it = maBroadcasters.begin(), itEnd = maBroadcasters.end(); + for (; it != itEnd; ++it) { - SvtListenerBase *pDel = pLst; - pLst = pLst->GetNext(); - - delete pDel; + SvtBroadcaster& rBC = **it; + rBC.Remove(this); } - pBrdCastLst = 0; + maBroadcasters.clear(); } -sal_Bool SvtListener::IsListening( SvtBroadcaster& rBroadcaster ) const +bool SvtListener::IsListening( SvtBroadcaster& rBroadcaster ) const { - const SvtListenerBase *pLst = pBrdCastLst; - while( pLst ) - { - if( &rBroadcaster == pLst->GetBroadcaster() ) - break; - pLst = pLst->GetNext(); - } - return 0 != pLst; + return maBroadcasters.count(&rBroadcaster) > 0; } - -// base implementation of notification handler +bool SvtListener::HasBroadcaster() const +{ + return !maBroadcasters.empty(); +} void SvtListener::Notify( SvtBroadcaster& #ifdef DBG_UTIL diff --git a/svl/source/notify/listenerbase.cxx b/svl/source/notify/listenerbase.cxx deleted file mode 100644 index 73b5f34ce03f..000000000000 --- a/svl/source/notify/listenerbase.cxx +++ /dev/null @@ -1,66 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - - -#include "listenerbase.hxx" -#include <svl/listeneriter.hxx> -#include <svl/listener.hxx> -#include <svl/broadcast.hxx> - - -SvtListenerBase::SvtListenerBase( SvtListener& rLst, - SvtBroadcaster& rBroadcaster ) - : pLeft( 0 ), pRight( 0 ), - pBroadcaster( &rBroadcaster ), pListener( &rLst ) -{ - pNext = rLst.pBrdCastLst; - rLst.pBrdCastLst = this; - - if( pBroadcaster->pRoot ) - { - // set ever behind the root - pRight = pBroadcaster->pRoot->pRight; - pBroadcaster->pRoot->pRight = this; - this->pLeft = pBroadcaster->pRoot; - if( pRight ) - pRight->pLeft = this; - } - else - pBroadcaster->pRoot = this; -} - -SvtListenerBase::~SvtListenerBase() -{ - SvtListenerBase *pR = pRight, *pL = pLeft; - if( pBroadcaster->pRoot ) - pBroadcaster->pRoot = pL ? pL : pR; - - if( pL ) - pL->pRight = pR; - if( pR ) - pR->pLeft = pL; - - SvtListenerIter::RemoveListener( *this, pR ); - - if( !pBroadcaster->pRoot ) - pBroadcaster->ListenersGone(); -} - - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svl/source/notify/listenerbase.hxx b/svl/source/notify/listenerbase.hxx deleted file mode 100644 index 9473953fad90..000000000000 --- a/svl/source/notify/listenerbase.hxx +++ /dev/null @@ -1,50 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ -#ifndef INCLUDED_SVL_SOURCE_NOTIFY_LISTENERBASE_HXX -#define INCLUDED_SVL_SOURCE_NOTIFY_LISTENERBASE_HXX - -class SvtBroadcaster; -class SvtListener; - -class SvtListenerBase -{ - SvtListenerBase *pNext; - SvtListenerBase *pLeft, *pRight; - SvtBroadcaster *pBroadcaster; - SvtListener *pListener; - -public: - - SvtListenerBase( SvtListener& rLst, SvtBroadcaster& rBroadcaster ); - ~SvtListenerBase(); - - SvtListenerBase* GetNext() const { return pNext; } - void SetNext( SvtListenerBase* p ) { pNext = p; } - - SvtBroadcaster* GetBroadcaster() const { return pBroadcaster; } - SvtListener* GetListener() const { return pListener; } - - SvtListenerBase* GetLeft() const { return pLeft; } - SvtListenerBase* GetRight() const { return pRight; } -}; - - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svl/source/notify/listeneriter.cxx b/svl/source/notify/listeneriter.cxx deleted file mode 100644 index 79058da90766..000000000000 --- a/svl/source/notify/listeneriter.cxx +++ /dev/null @@ -1,105 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include "listenerbase.hxx" -#include <svl/listeneriter.hxx> -#include <svl/broadcast.hxx> -#include <svl/listener.hxx> - -SvtListenerIter* SvtListenerIter::pListenerIters = 0; - -SvtListenerIter::SvtListenerIter( SvtBroadcaster& rBrdcst ) - : rRoot( rBrdcst ) -{ - // hinten einketten! - pNxtIter = 0; - if( pListenerIters ) - { - SvtListenerIter* pTmp = pListenerIters; - while( pTmp->pNxtIter ) - pTmp = pTmp->pNxtIter; - pTmp->pNxtIter = this; - } - else - pListenerIters = this; - - pAkt = rRoot.pRoot; - pDelNext = pAkt; -} - - - -SvtListenerIter::~SvtListenerIter() -{ - if( pListenerIters ) - { - if( pListenerIters == this ) - pListenerIters = pNxtIter; - else - { - SvtListenerIter* pTmp = pListenerIters; - while( pTmp->pNxtIter != this ) - if( 0 == ( pTmp = pTmp->pNxtIter ) ) - return ; - pTmp->pNxtIter = pNxtIter; - } - } -} - -void SvtListenerIter::RemoveListener( SvtListenerBase& rDel, - SvtListenerBase* pNext ) -{ - // Update the ListenerIter - SvtListenerIter* pTmp = pListenerIters; - while( pTmp ) - { - if( pTmp->pAkt == &rDel || pTmp->pDelNext == &rDel ) - pTmp->pDelNext = pNext; - pTmp = pTmp->pNxtIter; - } -} - -SvtListener* SvtListenerIter::GoNext() -{ - if( pDelNext == pAkt ) - { - pAkt = pAkt->GetRight(); - pDelNext = pAkt; - } - else - pAkt = pDelNext; - return pAkt ? pAkt->GetListener() : 0; -} - -SvtListener* SvtListenerIter::GoStart() // zum Anfang des Baums -{ - pAkt = rRoot.pRoot; - if( pAkt ) - while( pAkt->GetLeft() ) - pAkt = pAkt->GetLeft(); - pDelNext = pAkt; - return pAkt ? pAkt->GetListener() : 0; -} - -SvtListener* SvtListenerIter::GetCurr() const // returns the current -{ - return pDelNext ? pDelNext->GetListener() : 0; -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |