1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
19 #ifndef INCLUDED_COMPHELPER_INTERFACECONTAINER2_H
20 #define INCLUDED_COMPHELPER_INTERFACECONTAINER2_H
22 #include <sal/config.h>
29 #include <osl/diagnose.h>
30 #include <osl/mutex.hxx>
31 #include <rtl/alloc.h>
32 #include <com/sun/star/uno/Sequence.hxx>
33 #include <com/sun/star/uno/XInterface.hpp>
34 #include <com/sun/star/lang/EventObject.hpp>
36 #include <com/sun/star/lang/DisposedException.hpp>
37 #include <comphelper/comphelperdllapi.h>
46 This is here to optimise space in the common case that there are zero or one
51 std::vector
< css::uno::Reference
< css::uno::XInterface
> > *pAsVector
;
52 css::uno::XInterface
* pAsInterface
;
53 element_alias2() : pAsInterface(nullptr) {}
59 class OInterfaceContainerHelper2
;
61 This is the iterator of a InterfaceContainerHelper. Typically
62 one constructs an instance on the stack for one firing session.
63 It is not allowed to assign or copy an instance of this class.
65 @see OInterfaceContainerHelper
67 class COMPHELPER_DLLPUBLIC OInterfaceIteratorHelper2
71 Create an iterator over the elements of the container. The iterator
72 copies the elements of the container. A change to the container
73 during the lifetime of an iterator is allowed and does not
74 affect the iterator-instance. The iterator and the container take cares
75 themself for concurrent access, no additional guarding is necessary.
77 Remark: The copy is on demand. The iterator copy the elements only if the container
78 change the contents. It is not allowed to destroy the container as long
81 @param rCont the container of the elements.
83 OInterfaceIteratorHelper2( OInterfaceContainerHelper2
& rCont
);
86 Releases the connection to the container.
88 ~OInterfaceIteratorHelper2();
90 /** Return true, if there are more elements in the iterator. */
91 bool SAL_CALL
hasMoreElements() const
92 { return nRemain
!= 0; }
93 /** Return the next element of the iterator. Calling this method if
94 hasMoreElements() has returned false, is an error. Cast the
95 returned pointer to the
97 css::uno::XInterface
* SAL_CALL
next();
99 /** Removes the current element (the last one returned by next())
100 from the underlying container. Calling this method before
101 next() has been called or calling it twice with no next()
102 inbetween is an error.
104 void SAL_CALL
remove();
107 OInterfaceContainerHelper2
& rCont
;
109 detail::element_alias2 aData
;
112 OInterfaceIteratorHelper2( const OInterfaceIteratorHelper2
& )
113 SAL_DELETED_FUNCTION
;
114 OInterfaceIteratorHelper2
& operator = ( const OInterfaceIteratorHelper2
& )
115 SAL_DELETED_FUNCTION
;
120 A container of interfaces. To access the elements use an iterator.
121 This implementation is thread save.
123 @see OInterfaceIteratorHelper
125 class COMPHELPER_DLLPUBLIC OInterfaceContainerHelper2
128 // these are here to force memory de/allocation to sal lib.
129 static void * SAL_CALL
operator new( size_t nSize
)
130 { return ::rtl_allocateMemory( nSize
); }
131 static void SAL_CALL
operator delete( void * pMem
)
132 { ::rtl_freeMemory( pMem
); }
133 static void * SAL_CALL
operator new( size_t, void * pMem
)
135 static void SAL_CALL
operator delete( void *, void * )
139 Create an interface container.
141 @param rMutex the mutex to protect multi thread access.
142 The lifetime must be longer than the lifetime
145 OInterfaceContainerHelper2( ::osl::Mutex
& rMutex
);
147 Release all interfaces. All iterators must be destroyed before
148 the container is destructed.
150 ~OInterfaceContainerHelper2();
152 Return the number of Elements in the container. Only useful if you have acquired
155 sal_Int32 SAL_CALL
getLength() const;
158 Return all interfaces added to this container.
160 std::vector
< css::uno::Reference
< css::uno::XInterface
> > SAL_CALL
getElements() const;
162 /** Inserts an element into the container. The position is not specified, thus it is not
163 specified in which order events are fired.
166 If you add the same interface more than once, then it will be added to the elements list
167 more than once and thus if you want to remove that interface from the list, you have to call
168 removeInterface() the same number of times.
169 In the latter case, you will also get events fired more than once (if the interface is a
173 interface to be added; it is allowed to insert null or
174 the same interface more than once
176 the new count of elements in the container
178 sal_Int32 SAL_CALL
addInterface( const css::uno::Reference
< css::uno::XInterface
> & rxIFace
);
179 /** Removes an element from the container. It uses interface equality to remove the interface.
182 interface to be removed
184 the new count of elements in the container
186 sal_Int32 SAL_CALL
removeInterface( const css::uno::Reference
< css::uno::XInterface
> & rxIFace
);
188 Call disposing on all object in the container that
189 support XEventListener. Than clear the container.
191 void SAL_CALL
disposeAndClear( const css::lang::EventObject
& rEvt
);
193 Clears the container without calling disposing().
195 void SAL_CALL
clear();
197 /** Executes a functor for each contained listener of specified type, e.g.
198 <code>forEach<awt::XPaintListener>(...</code>.
200 If a css::lang::DisposedException occurs which relates to
201 the called listener, then that listener is removed from the container.
203 @tparam ListenerT listener type
204 @tparam FuncT unary functor type, let your compiler deduce this for you
205 @param func unary functor object expecting an argument of type
206 css::uno::Reference<ListenerT>
208 template <typename ListenerT
, typename FuncT
>
209 inline void forEach( FuncT
const& func
);
211 /** Calls a UNO listener method for each contained listener.
213 The listener method must take a single argument of type EventT,
214 and return <code>void</code>.
216 If a css::lang::DisposedException occurs which relates to
217 the called listener, then that listener is removed from the container.
219 @tparam ListenerT UNO event listener type, let your compiler deduce this for you
220 @tparam EventT event type, let your compiler deduce this for you
221 @param NotificationMethod
222 Pointer to a method of a ListenerT interface.
224 Event to notify to all contained listeners
228 awt::PaintEvent aEvent( static_cast< cppu::OWeakObject* >( this ), ... );
229 listeners.notifyEach( &XPaintListener::windowPaint, aEvent );
232 template< typename ListenerT
, typename EventT
>
233 inline void notifyEach( void ( SAL_CALL
ListenerT::*NotificationMethod
)( const EventT
& ), const EventT
& Event
);
236 friend class OInterfaceIteratorHelper2
;
238 bIsList == TRUE -> aData.pAsVector of type vector< XInterfaceSequence >,
239 otherwise aData.pAsInterface == of type (XEventListener *)
241 detail::element_alias2 aData
;
242 ::osl::Mutex
& rMutex
;
243 /** TRUE -> used by an iterator. */
245 /** TRUE -> aData.pAsVector is of type Sequence< XInterfaceSequence >. */
248 OInterfaceContainerHelper2( const OInterfaceContainerHelper2
& )
249 SAL_DELETED_FUNCTION
;
250 OInterfaceContainerHelper2
& operator = ( const OInterfaceContainerHelper2
& )
251 SAL_DELETED_FUNCTION
;
254 Duplicate content of the container and release the old one without destroying.
255 The mutex must be locked and the memberbInUse must be true.
257 void copyAndResetInUse();
260 template< typename ListenerT
, typename EventT
>
261 class NotifySingleListener
264 typedef void ( SAL_CALL
ListenerT::*NotificationMethod
)( const EventT
& );
265 NotificationMethod m_pMethod
;
266 const EventT
& m_rEvent
;
268 NotifySingleListener( NotificationMethod method
, const EventT
& event
) : m_pMethod( method
), m_rEvent( event
) { }
270 void operator()( const css::uno::Reference
<ListenerT
>& listener
) const
272 (listener
.get()->*m_pMethod
)( m_rEvent
);
277 template <typename ListenerT
, typename FuncT
>
278 inline void OInterfaceContainerHelper2::forEach( FuncT
const& func
)
280 OInterfaceIteratorHelper2
iter( *this );
281 while (iter
.hasMoreElements()) {
282 css::uno::Reference
<ListenerT
> const xListener( iter
.next(), css::uno::UNO_QUERY
);
283 if (xListener
.is()) {
287 catch (css::lang::DisposedException
const& exc
) {
288 if (exc
.Context
== xListener
)
295 template< typename ListenerT
, typename EventT
>
296 inline void OInterfaceContainerHelper2::notifyEach( void ( SAL_CALL
ListenerT::*NotificationMethod
)( const EventT
& ), const EventT
& Event
)
298 forEach
< ListenerT
, NotifySingleListener
< ListenerT
, EventT
> >( NotifySingleListener
< ListenerT
, EventT
>( NotificationMethod
, Event
) );
304 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */