1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir #ifndef _CPPUHELPER_INTERFACECONTAINER_H_ 28*cdf0e10cSrcweir #define _CPPUHELPER_INTERFACECONTAINER_H_ 29*cdf0e10cSrcweir 30*cdf0e10cSrcweir #include <vector> 31*cdf0e10cSrcweir #include <osl/mutex.hxx> 32*cdf0e10cSrcweir #include <rtl/alloc.h> 33*cdf0e10cSrcweir #include <com/sun/star/uno/Sequence.hxx> 34*cdf0e10cSrcweir #include <com/sun/star/uno/XInterface.hpp> 35*cdf0e10cSrcweir #ifndef _COM_SUN_STAR_LANG_EVENTOBJECT_HXX_ 36*cdf0e10cSrcweir #include <com/sun/star/lang/EventObject.hpp> 37*cdf0e10cSrcweir #endif 38*cdf0e10cSrcweir 39*cdf0e10cSrcweir #ifndef _COM_SUN_STAR_LANG_DISPOSEDEXCEPTION_HXX_ 40*cdf0e10cSrcweir #include "com/sun/star/lang/DisposedException.hpp" 41*cdf0e10cSrcweir #endif 42*cdf0e10cSrcweir 43*cdf0e10cSrcweir /** */ //for docpp 44*cdf0e10cSrcweir namespace cppu 45*cdf0e10cSrcweir { 46*cdf0e10cSrcweir 47*cdf0e10cSrcweir namespace detail { 48*cdf0e10cSrcweir 49*cdf0e10cSrcweir union element_alias 50*cdf0e10cSrcweir { 51*cdf0e10cSrcweir ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > > *pAsSequence; 52*cdf0e10cSrcweir ::com::sun::star::uno::XInterface * pAsInterface; 53*cdf0e10cSrcweir element_alias() : pAsInterface(0) {} 54*cdf0e10cSrcweir }; 55*cdf0e10cSrcweir 56*cdf0e10cSrcweir } 57*cdf0e10cSrcweir 58*cdf0e10cSrcweir //=================================================================== 59*cdf0e10cSrcweir class OInterfaceContainerHelper; 60*cdf0e10cSrcweir /** 61*cdf0e10cSrcweir This is the iterator of a InterfaceContainerHelper. Typically 62*cdf0e10cSrcweir one constructs an instance on the stack for one firing session. 63*cdf0e10cSrcweir It is not allowed to assign or copy an instance of this class. 64*cdf0e10cSrcweir 65*cdf0e10cSrcweir @see OInterfaceContainerHelper 66*cdf0e10cSrcweir */ 67*cdf0e10cSrcweir class OInterfaceIteratorHelper 68*cdf0e10cSrcweir { 69*cdf0e10cSrcweir public: 70*cdf0e10cSrcweir /** 71*cdf0e10cSrcweir Create an iterator over the elements of the container. The iterator 72*cdf0e10cSrcweir copies the elements of the conatainer. A change to the container 73*cdf0e10cSrcweir during the lifetime of an iterator is allowed and does not 74*cdf0e10cSrcweir affect the iterator-instance. The iterator and the container take cares 75*cdf0e10cSrcweir themself for concurrent access, no additional guarding is necessary. 76*cdf0e10cSrcweir 77*cdf0e10cSrcweir Remark: The copy is on demand. The iterator copy the elements only if the container 78*cdf0e10cSrcweir change the contents. It is not allowed to destroy the container as long 79*cdf0e10cSrcweir as an iterator exist. 80*cdf0e10cSrcweir 81*cdf0e10cSrcweir @param rCont the container of the elements. 82*cdf0e10cSrcweir */ 83*cdf0e10cSrcweir OInterfaceIteratorHelper( OInterfaceContainerHelper & rCont ) SAL_THROW( () ); 84*cdf0e10cSrcweir 85*cdf0e10cSrcweir /** 86*cdf0e10cSrcweir Releases the connection to the container. 87*cdf0e10cSrcweir */ 88*cdf0e10cSrcweir ~OInterfaceIteratorHelper() SAL_THROW( () ); 89*cdf0e10cSrcweir 90*cdf0e10cSrcweir /** Return sal_True, if there are more elements in the iterator. */ 91*cdf0e10cSrcweir sal_Bool SAL_CALL hasMoreElements() const SAL_THROW( () ) 92*cdf0e10cSrcweir { return nRemain != 0; } 93*cdf0e10cSrcweir /** Return the next element of the iterator. Calling this method if 94*cdf0e10cSrcweir hasMoreElements() has returned sal_False, is an error. Cast the 95*cdf0e10cSrcweir returned pointer to the 96*cdf0e10cSrcweir */ 97*cdf0e10cSrcweir ::com::sun::star::uno::XInterface * SAL_CALL next() SAL_THROW( () ); 98*cdf0e10cSrcweir 99*cdf0e10cSrcweir /** Removes the current element (the last one returned by next()) 100*cdf0e10cSrcweir from the underlying container. Calling this method before 101*cdf0e10cSrcweir next() has been called or calling it twice with no next() 102*cdf0e10cSrcweir inbetween is an error. 103*cdf0e10cSrcweir */ 104*cdf0e10cSrcweir void SAL_CALL remove() SAL_THROW( () ); 105*cdf0e10cSrcweir 106*cdf0e10cSrcweir private: 107*cdf0e10cSrcweir OInterfaceContainerHelper & rCont; 108*cdf0e10cSrcweir sal_Bool bIsList; 109*cdf0e10cSrcweir 110*cdf0e10cSrcweir detail::element_alias aData; 111*cdf0e10cSrcweir 112*cdf0e10cSrcweir sal_Int32 nRemain; 113*cdf0e10cSrcweir 114*cdf0e10cSrcweir OInterfaceIteratorHelper( const OInterfaceIteratorHelper & ) SAL_THROW( () ); 115*cdf0e10cSrcweir OInterfaceIteratorHelper & operator = ( const OInterfaceIteratorHelper & ) SAL_THROW( () ); 116*cdf0e10cSrcweir }; 117*cdf0e10cSrcweir 118*cdf0e10cSrcweir //=================================================================== 119*cdf0e10cSrcweir /** 120*cdf0e10cSrcweir A container of interfaces. To access the elements use an iterator. 121*cdf0e10cSrcweir This implementation is thread save. 122*cdf0e10cSrcweir 123*cdf0e10cSrcweir @see OInterfaceIteratorHelper 124*cdf0e10cSrcweir */ 125*cdf0e10cSrcweir class OInterfaceContainerHelper 126*cdf0e10cSrcweir { 127*cdf0e10cSrcweir public: 128*cdf0e10cSrcweir // these are here to force memory de/allocation to sal lib. 129*cdf0e10cSrcweir inline static void * SAL_CALL operator new( size_t nSize ) SAL_THROW( () ) 130*cdf0e10cSrcweir { return ::rtl_allocateMemory( nSize ); } 131*cdf0e10cSrcweir inline static void SAL_CALL operator delete( void * pMem ) SAL_THROW( () ) 132*cdf0e10cSrcweir { ::rtl_freeMemory( pMem ); } 133*cdf0e10cSrcweir inline static void * SAL_CALL operator new( size_t, void * pMem ) SAL_THROW( () ) 134*cdf0e10cSrcweir { return pMem; } 135*cdf0e10cSrcweir inline static void SAL_CALL operator delete( void *, void * ) SAL_THROW( () ) 136*cdf0e10cSrcweir {} 137*cdf0e10cSrcweir 138*cdf0e10cSrcweir /** 139*cdf0e10cSrcweir Create an interface container. 140*cdf0e10cSrcweir 141*cdf0e10cSrcweir @param rMutex the mutex to protect multi thread access. 142*cdf0e10cSrcweir The lifetime must be longer than the lifetime 143*cdf0e10cSrcweir of this object. 144*cdf0e10cSrcweir */ 145*cdf0e10cSrcweir OInterfaceContainerHelper( ::osl::Mutex & rMutex ) SAL_THROW( () ); 146*cdf0e10cSrcweir /** 147*cdf0e10cSrcweir Release all interfaces. All iterators must be destroyed before 148*cdf0e10cSrcweir the container is destructed. 149*cdf0e10cSrcweir */ 150*cdf0e10cSrcweir ~OInterfaceContainerHelper() SAL_THROW( () ); 151*cdf0e10cSrcweir /** 152*cdf0e10cSrcweir Return the number of Elements in the container. Only useful if you have acquired 153*cdf0e10cSrcweir the mutex. 154*cdf0e10cSrcweir */ 155*cdf0e10cSrcweir sal_Int32 SAL_CALL getLength() const SAL_THROW( () ); 156*cdf0e10cSrcweir 157*cdf0e10cSrcweir /** 158*cdf0e10cSrcweir Return all interfaces added to this container. 159*cdf0e10cSrcweir **/ 160*cdf0e10cSrcweir ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > > SAL_CALL getElements() const SAL_THROW( () ); 161*cdf0e10cSrcweir 162*cdf0e10cSrcweir /** Inserts an element into the container. The position is not specified, thus it is not 163*cdf0e10cSrcweir specified in which order events are fired. 164*cdf0e10cSrcweir 165*cdf0e10cSrcweir @attention 166*cdf0e10cSrcweir If you add the same interface more than once, then it will be added to the elements list 167*cdf0e10cSrcweir more than once and thus if you want to remove that interface from the list, you have to call 168*cdf0e10cSrcweir removeInterface() the same number of times. 169*cdf0e10cSrcweir In the latter case, you will also get events fired more than once (if the interface is a 170*cdf0e10cSrcweir listener interface). 171*cdf0e10cSrcweir 172*cdf0e10cSrcweir @param rxIFace 173*cdf0e10cSrcweir interface to be added; it is allowed to insert null or 174*cdf0e10cSrcweir the same interface more than once 175*cdf0e10cSrcweir @return 176*cdf0e10cSrcweir the new count of elements in the container 177*cdf0e10cSrcweir */ 178*cdf0e10cSrcweir sal_Int32 SAL_CALL addInterface( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > & rxIFace ) SAL_THROW( () ); 179*cdf0e10cSrcweir /** Removes an element from the container. It uses interface equality to remove the interface. 180*cdf0e10cSrcweir 181*cdf0e10cSrcweir @param rxIFace 182*cdf0e10cSrcweir interface to be removed 183*cdf0e10cSrcweir @return 184*cdf0e10cSrcweir the new count of elements in the container 185*cdf0e10cSrcweir */ 186*cdf0e10cSrcweir sal_Int32 SAL_CALL removeInterface( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > & rxIFace ) SAL_THROW( () ); 187*cdf0e10cSrcweir /** 188*cdf0e10cSrcweir Call disposing on all object in the container that 189*cdf0e10cSrcweir support XEventListener. Than clear the container. 190*cdf0e10cSrcweir */ 191*cdf0e10cSrcweir void SAL_CALL disposeAndClear( const ::com::sun::star::lang::EventObject & rEvt ) SAL_THROW( () ); 192*cdf0e10cSrcweir /** 193*cdf0e10cSrcweir Clears the container without calling disposing(). 194*cdf0e10cSrcweir */ 195*cdf0e10cSrcweir void SAL_CALL clear() SAL_THROW( () ); 196*cdf0e10cSrcweir 197*cdf0e10cSrcweir /** Executes a functor for each contained listener of specified type, e.g. 198*cdf0e10cSrcweir <code>forEach<awt::XPaintListener>(...</code>. 199*cdf0e10cSrcweir 200*cdf0e10cSrcweir If a com::sun::star::lang::DisposedException occurs which relates to 201*cdf0e10cSrcweir the called listener, then that listener is removed from the container. 202*cdf0e10cSrcweir 203*cdf0e10cSrcweir @tpl ListenerT listener type 204*cdf0e10cSrcweir @tpl FuncT unary functor type, let your compiler deduce this for you 205*cdf0e10cSrcweir @param func unary functor object expecting an argument of type 206*cdf0e10cSrcweir ::com::sun::star::uno::Reference<ListenerT> 207*cdf0e10cSrcweir */ 208*cdf0e10cSrcweir template <typename ListenerT, typename FuncT> 209*cdf0e10cSrcweir inline void forEach( FuncT const& func ); 210*cdf0e10cSrcweir 211*cdf0e10cSrcweir /** Calls a UNO listener method for each contained listener. 212*cdf0e10cSrcweir 213*cdf0e10cSrcweir The listener method must take a single argument of type EventT, 214*cdf0e10cSrcweir and return <code>void</code>. 215*cdf0e10cSrcweir 216*cdf0e10cSrcweir If a com::sun::star::lang::DisposedException occurs which relates to 217*cdf0e10cSrcweir the called listener, then that listener is removed from the container. 218*cdf0e10cSrcweir 219*cdf0e10cSrcweir @tpl ListenerT UNO event listener type, let your compiler deduce this for you 220*cdf0e10cSrcweir @tpl EventT event type, let your compiler deduce this for you 221*cdf0e10cSrcweir @param NotificationMethod 222*cdf0e10cSrcweir Pointer to a method of a ListenerT interface. 223*cdf0e10cSrcweir @param Event 224*cdf0e10cSrcweir Event to notify to all contained listeners 225*cdf0e10cSrcweir 226*cdf0e10cSrcweir @example 227*cdf0e10cSrcweir <pre> 228*cdf0e10cSrcweir awt::PaintEvent aEvent( static_cast< ::cppu::OWeakObject* >( this ), ... ); 229*cdf0e10cSrcweir listeners.notifyEach( &XPaintListener::windowPaint, aEvent ); 230*cdf0e10cSrcweir </pre> 231*cdf0e10cSrcweir */ 232*cdf0e10cSrcweir template< typename ListenerT, typename EventT > 233*cdf0e10cSrcweir inline void notifyEach( void ( SAL_CALL ListenerT::*NotificationMethod )( const EventT& ), const EventT& Event ); 234*cdf0e10cSrcweir 235*cdf0e10cSrcweir private: 236*cdf0e10cSrcweir friend class OInterfaceIteratorHelper; 237*cdf0e10cSrcweir /** 238*cdf0e10cSrcweir bIsList == TRUE -> aData.pAsSequence of type Sequence< XInterfaceSequence >, 239*cdf0e10cSrcweir otherwise aData.pAsInterface == of type (XEventListener *) 240*cdf0e10cSrcweir */ 241*cdf0e10cSrcweir detail::element_alias aData; 242*cdf0e10cSrcweir ::osl::Mutex & rMutex; 243*cdf0e10cSrcweir /** TRUE -> used by an iterator. */ 244*cdf0e10cSrcweir sal_Bool bInUse; 245*cdf0e10cSrcweir /** TRUE -> aData.pAsSequence is of type Sequence< XInterfaceSequence >. */ 246*cdf0e10cSrcweir sal_Bool bIsList; 247*cdf0e10cSrcweir 248*cdf0e10cSrcweir OInterfaceContainerHelper( const OInterfaceContainerHelper & ) SAL_THROW( () ); 249*cdf0e10cSrcweir OInterfaceContainerHelper & operator = ( const OInterfaceContainerHelper & ) SAL_THROW( () ); 250*cdf0e10cSrcweir 251*cdf0e10cSrcweir /* 252*cdf0e10cSrcweir Dulicate content of the conaitner and release the old one without destroying. 253*cdf0e10cSrcweir The mutex must be locked and the memberbInUse must be true. 254*cdf0e10cSrcweir */ 255*cdf0e10cSrcweir void copyAndResetInUse() SAL_THROW( () ); 256*cdf0e10cSrcweir 257*cdf0e10cSrcweir private: 258*cdf0e10cSrcweir template< typename ListenerT, typename EventT > 259*cdf0e10cSrcweir class NotifySingleListener 260*cdf0e10cSrcweir { 261*cdf0e10cSrcweir private: 262*cdf0e10cSrcweir typedef void ( SAL_CALL ListenerT::*NotificationMethod )( const EventT& ); 263*cdf0e10cSrcweir NotificationMethod m_pMethod; 264*cdf0e10cSrcweir const EventT& m_rEvent; 265*cdf0e10cSrcweir public: 266*cdf0e10cSrcweir NotifySingleListener( NotificationMethod method, const EventT& event ) : m_pMethod( method ), m_rEvent( event ) { } 267*cdf0e10cSrcweir 268*cdf0e10cSrcweir void operator()( const ::com::sun::star::uno::Reference<ListenerT>& listener ) const 269*cdf0e10cSrcweir { 270*cdf0e10cSrcweir (listener.get()->*m_pMethod)( m_rEvent ); 271*cdf0e10cSrcweir } 272*cdf0e10cSrcweir }; 273*cdf0e10cSrcweir }; 274*cdf0e10cSrcweir 275*cdf0e10cSrcweir template <typename ListenerT, typename FuncT> 276*cdf0e10cSrcweir inline void OInterfaceContainerHelper::forEach( FuncT const& func ) 277*cdf0e10cSrcweir { 278*cdf0e10cSrcweir OInterfaceIteratorHelper iter( *this ); 279*cdf0e10cSrcweir while (iter.hasMoreElements()) { 280*cdf0e10cSrcweir ::com::sun::star::uno::Reference<ListenerT> const xListener( 281*cdf0e10cSrcweir iter.next(), ::com::sun::star::uno::UNO_QUERY ); 282*cdf0e10cSrcweir if (xListener.is()) { 283*cdf0e10cSrcweir #if defined(EXCEPTIONS_OFF) 284*cdf0e10cSrcweir func( xListener ); 285*cdf0e10cSrcweir #else 286*cdf0e10cSrcweir try { 287*cdf0e10cSrcweir func( xListener ); 288*cdf0e10cSrcweir } 289*cdf0e10cSrcweir catch (::com::sun::star::lang::DisposedException const& exc) { 290*cdf0e10cSrcweir if (exc.Context == xListener) 291*cdf0e10cSrcweir iter.remove(); 292*cdf0e10cSrcweir } 293*cdf0e10cSrcweir #endif 294*cdf0e10cSrcweir } 295*cdf0e10cSrcweir } 296*cdf0e10cSrcweir } 297*cdf0e10cSrcweir 298*cdf0e10cSrcweir template< typename ListenerT, typename EventT > 299*cdf0e10cSrcweir inline void OInterfaceContainerHelper::notifyEach( void ( SAL_CALL ListenerT::*NotificationMethod )( const EventT& ), const EventT& Event ) 300*cdf0e10cSrcweir { 301*cdf0e10cSrcweir forEach< ListenerT, NotifySingleListener< ListenerT, EventT > >( NotifySingleListener< ListenerT, EventT >( NotificationMethod, Event ) ); 302*cdf0e10cSrcweir } 303*cdf0e10cSrcweir 304*cdf0e10cSrcweir //=================================================================== 305*cdf0e10cSrcweir /** 306*cdf0e10cSrcweir A helper class to store interface references of different types. 307*cdf0e10cSrcweir 308*cdf0e10cSrcweir @see OInterfaceIteratorHelper 309*cdf0e10cSrcweir @see OInterfaceContainerHelper 310*cdf0e10cSrcweir */ 311*cdf0e10cSrcweir template< class key , class hashImpl , class equalImpl > 312*cdf0e10cSrcweir class OMultiTypeInterfaceContainerHelperVar 313*cdf0e10cSrcweir { 314*cdf0e10cSrcweir public: 315*cdf0e10cSrcweir // these are here to force memory de/allocation to sal lib. 316*cdf0e10cSrcweir inline static void * SAL_CALL operator new( size_t nSize ) SAL_THROW( () ) 317*cdf0e10cSrcweir { return ::rtl_allocateMemory( nSize ); } 318*cdf0e10cSrcweir inline static void SAL_CALL operator delete( void * pMem ) SAL_THROW( () ) 319*cdf0e10cSrcweir { ::rtl_freeMemory( pMem ); } 320*cdf0e10cSrcweir inline static void * SAL_CALL operator new( size_t, void * pMem ) SAL_THROW( () ) 321*cdf0e10cSrcweir { return pMem; } 322*cdf0e10cSrcweir inline static void SAL_CALL operator delete( void *, void * ) SAL_THROW( () ) 323*cdf0e10cSrcweir {} 324*cdf0e10cSrcweir 325*cdf0e10cSrcweir /** 326*cdf0e10cSrcweir Create a container of interface containers. 327*cdf0e10cSrcweir 328*cdf0e10cSrcweir @param rMutex the mutex to protect multi thread access. 329*cdf0e10cSrcweir The lifetime must be longer than the lifetime 330*cdf0e10cSrcweir of this object. 331*cdf0e10cSrcweir */ 332*cdf0e10cSrcweir inline OMultiTypeInterfaceContainerHelperVar( ::osl::Mutex & ) SAL_THROW( () ); 333*cdf0e10cSrcweir /** 334*cdf0e10cSrcweir Deletes all containers. 335*cdf0e10cSrcweir */ 336*cdf0e10cSrcweir inline ~OMultiTypeInterfaceContainerHelperVar() SAL_THROW( () ); 337*cdf0e10cSrcweir 338*cdf0e10cSrcweir /** 339*cdf0e10cSrcweir Return all id's under which at least one interface is added. 340*cdf0e10cSrcweir */ 341*cdf0e10cSrcweir inline ::com::sun::star::uno::Sequence< key > SAL_CALL getContainedTypes() const SAL_THROW( () ); 342*cdf0e10cSrcweir 343*cdf0e10cSrcweir /** 344*cdf0e10cSrcweir Return the container created under this key. 345*cdf0e10cSrcweir The InterfaceContainerHelper exists until the whole MultiTypeContainer is destroyed. 346*cdf0e10cSrcweir @return the container created under this key. If the container 347*cdf0e10cSrcweir was not created, null was returned. 348*cdf0e10cSrcweir */ 349*cdf0e10cSrcweir inline OInterfaceContainerHelper * SAL_CALL getContainer( const key & ) const SAL_THROW( () ); 350*cdf0e10cSrcweir 351*cdf0e10cSrcweir /** Inserts an element into the container with the specified key. 352*cdf0e10cSrcweir The position is not specified, thus it is not specified in which order events are fired. 353*cdf0e10cSrcweir 354*cdf0e10cSrcweir @attention 355*cdf0e10cSrcweir If you add the same interface more than once, then it will be added to the elements list 356*cdf0e10cSrcweir more than once and thus if you want to remove that interface from the list, you have to call 357*cdf0e10cSrcweir removeInterface() the same number of times. 358*cdf0e10cSrcweir In the latter case, you will also get events fired more than once (if the interface is a 359*cdf0e10cSrcweir listener interface). 360*cdf0e10cSrcweir 361*cdf0e10cSrcweir @param rKey 362*cdf0e10cSrcweir the id of the container 363*cdf0e10cSrcweir @param r 364*cdf0e10cSrcweir interface to be added; it is allowed, to insert null or 365*cdf0e10cSrcweir the same interface more than once 366*cdf0e10cSrcweir @return 367*cdf0e10cSrcweir the new count of elements in the container 368*cdf0e10cSrcweir */ 369*cdf0e10cSrcweir inline sal_Int32 SAL_CALL addInterface( 370*cdf0e10cSrcweir const key & rKey, 371*cdf0e10cSrcweir const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > & r ) 372*cdf0e10cSrcweir SAL_THROW( () ); 373*cdf0e10cSrcweir 374*cdf0e10cSrcweir /** Removes an element from the container with the specified key. 375*cdf0e10cSrcweir It uses interface equality to remove the interface. 376*cdf0e10cSrcweir 377*cdf0e10cSrcweir @param rKey 378*cdf0e10cSrcweir the id of the container 379*cdf0e10cSrcweir @param rxIFace 380*cdf0e10cSrcweir interface to be removed 381*cdf0e10cSrcweir @return 382*cdf0e10cSrcweir the new count of elements in the container 383*cdf0e10cSrcweir */ 384*cdf0e10cSrcweir inline sal_Int32 SAL_CALL removeInterface( 385*cdf0e10cSrcweir const key & rKey, 386*cdf0e10cSrcweir const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > & rxIFace ) 387*cdf0e10cSrcweir SAL_THROW( () ); 388*cdf0e10cSrcweir 389*cdf0e10cSrcweir /** 390*cdf0e10cSrcweir Call disposing on all references in the container, that 391*cdf0e10cSrcweir support XEventListener. Then clears the container. 392*cdf0e10cSrcweir @param rEvt the event object which is passed during disposing() call 393*cdf0e10cSrcweir */ 394*cdf0e10cSrcweir inline void SAL_CALL disposeAndClear( const ::com::sun::star::lang::EventObject & rEvt ) SAL_THROW( () ); 395*cdf0e10cSrcweir /** 396*cdf0e10cSrcweir Remove all elements of all containers. Does not delete the container. 397*cdf0e10cSrcweir */ 398*cdf0e10cSrcweir inline void SAL_CALL clear() SAL_THROW( () ); 399*cdf0e10cSrcweir 400*cdf0e10cSrcweir typedef key keyType; 401*cdf0e10cSrcweir private: 402*cdf0e10cSrcweir typedef ::std::vector< std::pair < key , void* > > InterfaceMap; 403*cdf0e10cSrcweir InterfaceMap *m_pMap; 404*cdf0e10cSrcweir ::osl::Mutex & rMutex; 405*cdf0e10cSrcweir 406*cdf0e10cSrcweir inline typename InterfaceMap::iterator find(const key &rKey) const 407*cdf0e10cSrcweir { 408*cdf0e10cSrcweir typename InterfaceMap::iterator iter = m_pMap->begin(); 409*cdf0e10cSrcweir typename InterfaceMap::iterator end = m_pMap->end(); 410*cdf0e10cSrcweir 411*cdf0e10cSrcweir while( iter != end ) 412*cdf0e10cSrcweir { 413*cdf0e10cSrcweir equalImpl equal; 414*cdf0e10cSrcweir if( equal( iter->first, rKey ) ) 415*cdf0e10cSrcweir break; 416*cdf0e10cSrcweir iter++; 417*cdf0e10cSrcweir } 418*cdf0e10cSrcweir return iter; 419*cdf0e10cSrcweir } 420*cdf0e10cSrcweir 421*cdf0e10cSrcweir inline OMultiTypeInterfaceContainerHelperVar( const OMultiTypeInterfaceContainerHelperVar & ) SAL_THROW( () ); 422*cdf0e10cSrcweir inline OMultiTypeInterfaceContainerHelperVar & operator = ( const OMultiTypeInterfaceContainerHelperVar & ) SAL_THROW( () ); 423*cdf0e10cSrcweir }; 424*cdf0e10cSrcweir 425*cdf0e10cSrcweir 426*cdf0e10cSrcweir 427*cdf0e10cSrcweir 428*cdf0e10cSrcweir /** 429*cdf0e10cSrcweir This struct contains the standard variables of a broadcaster. Helper 430*cdf0e10cSrcweir classes only know a reference to this struct instead of references 431*cdf0e10cSrcweir to the four members. The access to the members must be guarded with 432*cdf0e10cSrcweir rMutex. 433*cdf0e10cSrcweir 434*cdf0e10cSrcweir The additional template parameter keyType has been added, because gcc 435*cdf0e10cSrcweir can't compile addListener( const container::keyType &key ). 436*cdf0e10cSrcweir */ 437*cdf0e10cSrcweir template < class container , class keyType > 438*cdf0e10cSrcweir struct OBroadcastHelperVar 439*cdf0e10cSrcweir { 440*cdf0e10cSrcweir /** The shared mutex. */ 441*cdf0e10cSrcweir ::osl::Mutex & rMutex; 442*cdf0e10cSrcweir /** ListenerContainer class is thread save. */ 443*cdf0e10cSrcweir container aLC; 444*cdf0e10cSrcweir /** Dispose call ready. */ 445*cdf0e10cSrcweir sal_Bool bDisposed; 446*cdf0e10cSrcweir /** In dispose call. */ 447*cdf0e10cSrcweir sal_Bool bInDispose; 448*cdf0e10cSrcweir 449*cdf0e10cSrcweir /** 450*cdf0e10cSrcweir Initialize the structur. bDispose and bInDispose are set to false. 451*cdf0e10cSrcweir @param rMutex the mutex reference. 452*cdf0e10cSrcweir */ 453*cdf0e10cSrcweir OBroadcastHelperVar( ::osl::Mutex & rMutex_ ) SAL_THROW( () ) 454*cdf0e10cSrcweir : rMutex( rMutex_ ) 455*cdf0e10cSrcweir , aLC( rMutex_ ) 456*cdf0e10cSrcweir , bDisposed( sal_False ) 457*cdf0e10cSrcweir , bInDispose( sal_False ) 458*cdf0e10cSrcweir {} 459*cdf0e10cSrcweir 460*cdf0e10cSrcweir /** 461*cdf0e10cSrcweir adds a listener threadsafe. 462*cdf0e10cSrcweir **/ 463*cdf0e10cSrcweir inline void addListener( 464*cdf0e10cSrcweir const keyType &key, 465*cdf0e10cSrcweir const ::com::sun::star::uno::Reference < ::com::sun::star::uno::XInterface > &r ) 466*cdf0e10cSrcweir SAL_THROW( () ) 467*cdf0e10cSrcweir { 468*cdf0e10cSrcweir ::osl::MutexGuard guard( rMutex ); 469*cdf0e10cSrcweir OSL_ENSURE( !bInDispose, "do not add listeners in the dispose call" ); 470*cdf0e10cSrcweir OSL_ENSURE( !bDisposed, "object is disposed" ); 471*cdf0e10cSrcweir if( ! bInDispose && ! bDisposed ) 472*cdf0e10cSrcweir aLC.addInterface( key , r ); 473*cdf0e10cSrcweir } 474*cdf0e10cSrcweir 475*cdf0e10cSrcweir /** 476*cdf0e10cSrcweir removes a listener threadsafe 477*cdf0e10cSrcweir **/ 478*cdf0e10cSrcweir inline void removeListener( 479*cdf0e10cSrcweir const keyType &key, 480*cdf0e10cSrcweir const ::com::sun::star::uno::Reference < ::com::sun::star::uno::XInterface > & r ) 481*cdf0e10cSrcweir SAL_THROW( () ) 482*cdf0e10cSrcweir { 483*cdf0e10cSrcweir ::osl::MutexGuard guard( rMutex ); 484*cdf0e10cSrcweir OSL_ENSURE( !bDisposed, "object is disposed" ); 485*cdf0e10cSrcweir if( ! bInDispose && ! bDisposed ) 486*cdf0e10cSrcweir aLC.removeInterface( key , r ); 487*cdf0e10cSrcweir } 488*cdf0e10cSrcweir 489*cdf0e10cSrcweir /** 490*cdf0e10cSrcweir Return the container created under this key. 491*cdf0e10cSrcweir @return the container created under this key. If the container 492*cdf0e10cSrcweir was not created, null was returned. This can be used to optimize 493*cdf0e10cSrcweir performance ( construction of an event object can be avoided ). 494*cdf0e10cSrcweir ***/ 495*cdf0e10cSrcweir inline OInterfaceContainerHelper * SAL_CALL getContainer( const keyType &key ) const SAL_THROW( () ) 496*cdf0e10cSrcweir { return aLC.getContainer( key ); } 497*cdf0e10cSrcweir }; 498*cdf0e10cSrcweir 499*cdf0e10cSrcweir /*------------------------------------------ 500*cdf0e10cSrcweir * 501*cdf0e10cSrcweir * In general, the above templates are used with a Type as key. 502*cdf0e10cSrcweir * Therefore a default declaration is given ( OMultiTypeInterfaceContainerHelper and OBroadcastHelper ) 503*cdf0e10cSrcweir * 504*cdf0e10cSrcweir *------------------------------------------*/ 505*cdf0e10cSrcweir 506*cdf0e10cSrcweir // helper function call class 507*cdf0e10cSrcweir struct hashType_Impl 508*cdf0e10cSrcweir { 509*cdf0e10cSrcweir size_t operator()(const ::com::sun::star::uno::Type & s) const SAL_THROW( () ) 510*cdf0e10cSrcweir { return s.getTypeName().hashCode(); } 511*cdf0e10cSrcweir }; 512*cdf0e10cSrcweir 513*cdf0e10cSrcweir 514*cdf0e10cSrcweir /** Specialized class for key type com::sun::star::uno::Type, 515*cdf0e10cSrcweir without explicit usage of STL symbols. 516*cdf0e10cSrcweir */ 517*cdf0e10cSrcweir class OMultiTypeInterfaceContainerHelper 518*cdf0e10cSrcweir { 519*cdf0e10cSrcweir public: 520*cdf0e10cSrcweir // these are here to force memory de/allocation to sal lib. 521*cdf0e10cSrcweir inline static void * SAL_CALL operator new( size_t nSize ) SAL_THROW( () ) 522*cdf0e10cSrcweir { return ::rtl_allocateMemory( nSize ); } 523*cdf0e10cSrcweir inline static void SAL_CALL operator delete( void * pMem ) SAL_THROW( () ) 524*cdf0e10cSrcweir { ::rtl_freeMemory( pMem ); } 525*cdf0e10cSrcweir inline static void * SAL_CALL operator new( size_t, void * pMem ) SAL_THROW( () ) 526*cdf0e10cSrcweir { return pMem; } 527*cdf0e10cSrcweir inline static void SAL_CALL operator delete( void *, void * ) SAL_THROW( () ) 528*cdf0e10cSrcweir {} 529*cdf0e10cSrcweir 530*cdf0e10cSrcweir /** 531*cdf0e10cSrcweir Create a container of interface containers. 532*cdf0e10cSrcweir 533*cdf0e10cSrcweir @param rMutex the mutex to protect multi thread access. 534*cdf0e10cSrcweir The lifetime must be longer than the lifetime 535*cdf0e10cSrcweir of this object. 536*cdf0e10cSrcweir */ 537*cdf0e10cSrcweir OMultiTypeInterfaceContainerHelper( ::osl::Mutex & ) SAL_THROW( () ); 538*cdf0e10cSrcweir /** 539*cdf0e10cSrcweir Delete all containers. 540*cdf0e10cSrcweir */ 541*cdf0e10cSrcweir ~OMultiTypeInterfaceContainerHelper() SAL_THROW( () ); 542*cdf0e10cSrcweir 543*cdf0e10cSrcweir /** 544*cdf0e10cSrcweir Return all id's under which at least one interface is added. 545*cdf0e10cSrcweir */ 546*cdf0e10cSrcweir ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getContainedTypes() const SAL_THROW( () ); 547*cdf0e10cSrcweir 548*cdf0e10cSrcweir /** 549*cdf0e10cSrcweir Return the container created under this key. 550*cdf0e10cSrcweir @return the container created under this key. If the container 551*cdf0e10cSrcweir was not created, null was returned. 552*cdf0e10cSrcweir */ 553*cdf0e10cSrcweir OInterfaceContainerHelper * SAL_CALL getContainer( const ::com::sun::star::uno::Type & rKey ) const SAL_THROW( () ); 554*cdf0e10cSrcweir 555*cdf0e10cSrcweir /** Inserts an element into the container with the specified key. 556*cdf0e10cSrcweir The position is not specified, thus it is not specified in which order events are fired. 557*cdf0e10cSrcweir 558*cdf0e10cSrcweir @attention 559*cdf0e10cSrcweir If you add the same interface more than once, then it will be added to the elements list 560*cdf0e10cSrcweir more than once and thus if you want to remove that interface from the list, you have to call 561*cdf0e10cSrcweir removeInterface() the same number of times. 562*cdf0e10cSrcweir In the latter case, you will also get events fired more than once (if the interface is a 563*cdf0e10cSrcweir listener interface). 564*cdf0e10cSrcweir 565*cdf0e10cSrcweir @param rKey 566*cdf0e10cSrcweir the id of the container 567*cdf0e10cSrcweir @param r 568*cdf0e10cSrcweir interface to be added; it is allowed, to insert null or 569*cdf0e10cSrcweir the same interface more than once 570*cdf0e10cSrcweir @return 571*cdf0e10cSrcweir the new count of elements in the container 572*cdf0e10cSrcweir */ 573*cdf0e10cSrcweir sal_Int32 SAL_CALL addInterface( 574*cdf0e10cSrcweir const ::com::sun::star::uno::Type & rKey, 575*cdf0e10cSrcweir const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > & r ) 576*cdf0e10cSrcweir SAL_THROW( () ); 577*cdf0e10cSrcweir 578*cdf0e10cSrcweir /** Removes an element from the container with the specified key. 579*cdf0e10cSrcweir It uses interface equality to remove the interface. 580*cdf0e10cSrcweir 581*cdf0e10cSrcweir @param rKey 582*cdf0e10cSrcweir the id of the container 583*cdf0e10cSrcweir @param rxIFace 584*cdf0e10cSrcweir interface to be removed 585*cdf0e10cSrcweir @return 586*cdf0e10cSrcweir the new count of elements in the container 587*cdf0e10cSrcweir */ 588*cdf0e10cSrcweir sal_Int32 SAL_CALL removeInterface( 589*cdf0e10cSrcweir const ::com::sun::star::uno::Type & rKey, 590*cdf0e10cSrcweir const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > & rxIFace ) 591*cdf0e10cSrcweir SAL_THROW( () ); 592*cdf0e10cSrcweir 593*cdf0e10cSrcweir /** 594*cdf0e10cSrcweir Call disposing on all object in the container that 595*cdf0e10cSrcweir support XEventListener. Than clear the container. 596*cdf0e10cSrcweir */ 597*cdf0e10cSrcweir void SAL_CALL disposeAndClear( const ::com::sun::star::lang::EventObject & rEvt ) SAL_THROW( () ); 598*cdf0e10cSrcweir /** 599*cdf0e10cSrcweir Remove all elements of all containers. Does not delete the container. 600*cdf0e10cSrcweir */ 601*cdf0e10cSrcweir void SAL_CALL clear() SAL_THROW( () ); 602*cdf0e10cSrcweir 603*cdf0e10cSrcweir typedef ::com::sun::star::uno::Type keyType; 604*cdf0e10cSrcweir private: 605*cdf0e10cSrcweir void *m_pMap; 606*cdf0e10cSrcweir ::osl::Mutex & rMutex; 607*cdf0e10cSrcweir 608*cdf0e10cSrcweir inline OMultiTypeInterfaceContainerHelper( const OMultiTypeInterfaceContainerHelper & ) SAL_THROW( () ); 609*cdf0e10cSrcweir inline OMultiTypeInterfaceContainerHelper & operator = ( const OMultiTypeInterfaceContainerHelper & ) SAL_THROW( () ); 610*cdf0e10cSrcweir }; 611*cdf0e10cSrcweir 612*cdf0e10cSrcweir typedef OBroadcastHelperVar< OMultiTypeInterfaceContainerHelper , OMultiTypeInterfaceContainerHelper::keyType > OBroadcastHelper; 613*cdf0e10cSrcweir 614*cdf0e10cSrcweir } 615*cdf0e10cSrcweir 616*cdf0e10cSrcweir #endif 617*cdf0e10cSrcweir 618