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