bump product version to 7.6.3.2-android
[LibreOffice.git] / include / comphelper / interfacecontainer2.hxx
blob3df7c71d49d803af51f83afaf7dd9e28d4f5aac8
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
24 #include <vector>
26 #include <com/sun/star/lang/EventObject.hpp>
28 #include <com/sun/star/lang/DisposedException.hpp>
29 #include <comphelper/comphelperdllapi.h>
31 namespace com::sun::star::uno { class XInterface; }
32 namespace osl { class Mutex; }
34 namespace comphelper
37 namespace detail {
39 /**
40 This is here to optimise space in the common case that there are zero or one
41 listeners.
43 union element_alias2
45 std::vector< css::uno::Reference< css::uno::XInterface > > *pAsVector;
46 css::uno::XInterface * pAsInterface;
47 element_alias2() : pAsInterface(nullptr) {}
53 class OInterfaceContainerHelper2;
54 /**
55 This is the iterator of an OInterfaceContainerHelper2. Typically
56 one constructs an instance on the stack for one firing session.
57 It is not allowed to assign or copy an instance of this class.
59 @see OInterfaceContainerHelper2
61 class COMPHELPER_DLLPUBLIC OInterfaceIteratorHelper2
63 public:
64 /**
65 Create an iterator over the elements of the container. The iterator
66 copies the elements of the container. A change to the container
67 during the lifetime of an iterator is allowed and does not
68 affect the iterator-instance. The iterator and the container take cares
69 themself for concurrent access, no additional guarding is necessary.
71 Remark: The copy is on demand. The iterator copy the elements only if the container
72 change the contents. It is not allowed to destroy the container as long
73 as an iterator exist.
75 @param rCont the container of the elements.
77 OInterfaceIteratorHelper2( OInterfaceContainerHelper2 & rCont );
79 /**
80 Releases the connection to the container.
82 ~OInterfaceIteratorHelper2();
84 /** Return true, if there are more elements in the iterator. */
85 bool hasMoreElements() const
86 { return nRemain != 0; }
87 /** Return the next element of the iterator. Calling this method if
88 hasMoreElements() has returned false, is an error. Cast the
89 returned pointer to the
91 css::uno::XInterface * next();
93 /** Removes the current element (the last one returned by next())
94 from the underlying container. Calling this method before
95 next() has been called or calling it twice with no next()
96 inbetween is an error.
98 void remove();
100 private:
101 OInterfaceContainerHelper2 & rCont;
102 detail::element_alias2 aData;
103 sal_Int32 nRemain;
104 bool bIsList;
106 OInterfaceIteratorHelper2( const OInterfaceIteratorHelper2 & ) = delete;
107 OInterfaceIteratorHelper2 & operator = ( const OInterfaceIteratorHelper2 & ) = delete;
112 A container of interfaces. To access the elements use an iterator.
113 This implementation is thread-safe.
115 This is a copy of the code at include/cppuhelper/interfacecontainer.h,
116 Except that it uses a std::vector instead of a Sequence for the mutable listener
117 list, which provides far better performance.
119 @see OInterfaceIteratorHelper2
121 class COMPHELPER_DLLPUBLIC OInterfaceContainerHelper2
123 public:
125 Create an interface container.
127 @param rMutex the mutex to protect multi thread access.
128 The lifetime must be longer than the lifetime
129 of this object.
131 OInterfaceContainerHelper2( ::osl::Mutex & rMutex );
133 Release all interfaces. All iterators must be destroyed before
134 the container is destructed.
136 ~OInterfaceContainerHelper2();
138 Return the number of Elements in the container. Only useful if you have acquired
139 the mutex.
141 sal_Int32 getLength() const;
144 Return all interfaces added to this container.
146 std::vector< css::uno::Reference< css::uno::XInterface > > getElements() const;
148 /** Inserts an element into the container. The position is not specified, thus it is not
149 specified in which order events are fired.
151 @attention
152 If you add the same interface more than once, then it will be added to the elements list
153 more than once and thus if you want to remove that interface from the list, you have to call
154 removeInterface() the same number of times.
155 In the latter case, you will also get events fired more than once (if the interface is a
156 listener interface).
158 @param rxIFace
159 interface to be added; it is allowed to insert null or
160 the same interface more than once
161 @return
162 the new count of elements in the container
164 sal_Int32 addInterface( const css::uno::Reference< css::uno::XInterface > & rxIFace );
165 /** Removes an element from the container. It uses interface equality to remove the interface.
167 @param rxIFace
168 interface to be removed
169 @return
170 the new count of elements in the container
172 sal_Int32 removeInterface( const css::uno::Reference< css::uno::XInterface > & rxIFace );
173 /** Return an interface by index */
174 css::uno::Reference< css::uno::XInterface > getInterface(sal_Int32 nIndex) const;
176 Call disposing on all object in the container that
177 support XEventListener. Then clear the container.
179 void disposeAndClear( const css::lang::EventObject & rEvt );
181 Clears the container without calling disposing().
183 void clear();
185 /** Executes a functor for each contained listener of specified type, e.g.
186 <code>forEach<awt::XPaintListener>(...</code>.
188 If a css::lang::DisposedException occurs which relates to
189 the called listener, then that listener is removed from the container.
191 @tparam ListenerT listener type
192 @tparam FuncT unary functor type, let your compiler deduce this for you
193 @param func unary functor object expecting an argument of type
194 css::uno::Reference<ListenerT>
196 template <typename ListenerT, typename FuncT>
197 inline void forEach( FuncT const& func );
199 /** Calls a UNO listener method for each contained listener.
201 The listener method must take a single argument of type EventT,
202 and return <code>void</code>.
204 If a css::lang::DisposedException occurs which relates to
205 the called listener, then that listener is removed from the container.
207 @tparam ListenerT UNO event listener type, let your compiler deduce this for you
208 @tparam EventT event type, let your compiler deduce this for you
209 @param NotificationMethod
210 Pointer to a method of a ListenerT interface.
211 @param Event
212 Event to notify to all contained listeners
214 Example:
215 @code
216 awt::PaintEvent aEvent( static_cast< cppu::OWeakObject* >( this ), ... );
217 listeners.notifyEach( &XPaintListener::windowPaint, aEvent );
218 @endcode
220 template< typename ListenerT, typename EventT >
221 inline void notifyEach( void ( SAL_CALL ListenerT::*NotificationMethod )( const EventT& ), const EventT& Event );
223 private:
224 friend class OInterfaceIteratorHelper2;
226 bIsList == TRUE -> aData.pAsVector of type vector< XInterfaceSequence >,
227 otherwise aData.pAsInterface == of type (XEventListener *)
229 detail::element_alias2 aData;
230 ::osl::Mutex & rMutex;
231 /** TRUE -> used by an iterator. */
232 bool bInUse;
233 /** TRUE -> aData.pAsVector is of type Sequence< XInterfaceSequence >. */
234 bool bIsList;
236 OInterfaceContainerHelper2( const OInterfaceContainerHelper2 & ) = delete;
237 OInterfaceContainerHelper2 & operator = ( const OInterfaceContainerHelper2 & ) = delete;
240 Duplicate content of the container and release the old one without destroying.
241 The mutex must be locked and the memberbInUse must be true.
243 void copyAndResetInUse();
245 private:
246 template< typename ListenerT, typename EventT >
247 class NotifySingleListener
249 private:
250 typedef void ( SAL_CALL ListenerT::*NotificationMethod )( const EventT& );
251 NotificationMethod const m_pMethod;
252 const EventT& m_rEvent;
253 public:
254 NotifySingleListener( NotificationMethod method, const EventT& event ) : m_pMethod( method ), m_rEvent( event ) { }
256 void operator()( const css::uno::Reference<ListenerT>& listener ) const
258 (listener.get()->*m_pMethod)( m_rEvent );
263 template <typename ListenerT, typename FuncT>
264 inline void OInterfaceContainerHelper2::forEach( FuncT const& func )
266 OInterfaceIteratorHelper2 iter( *this );
267 while (iter.hasMoreElements()) {
268 css::uno::Reference<ListenerT> const xListener( iter.next(), css::uno::UNO_QUERY );
269 if (xListener.is()) {
270 try {
271 func( xListener );
273 catch (css::lang::DisposedException const& exc) {
274 if (exc.Context == xListener)
275 iter.remove();
281 template< typename ListenerT, typename EventT >
282 inline void OInterfaceContainerHelper2::notifyEach( void ( SAL_CALL ListenerT::*NotificationMethod )( const EventT& ), const EventT& Event )
284 forEach< ListenerT, NotifySingleListener< ListenerT, EventT > >( NotifySingleListener< ListenerT, EventT >( NotificationMethod, Event ) );
288 #endif
290 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */