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>
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
; }
40 This is here to optimise space in the common case that there are zero or one
45 std::vector
< css::uno::Reference
< css::uno::XInterface
> > *pAsVector
;
46 css::uno::XInterface
* pAsInterface
;
47 element_alias2() : pAsInterface(nullptr) {}
53 class OInterfaceContainerHelper2
;
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
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
75 @param rCont the container of the elements.
77 OInterfaceIteratorHelper2( OInterfaceContainerHelper2
& rCont
);
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.
101 OInterfaceContainerHelper2
& rCont
;
102 detail::element_alias2 aData
;
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
125 Create an interface container.
127 @param rMutex the mutex to protect multi thread access.
128 The lifetime must be longer than the lifetime
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
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.
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
159 interface to be added; it is allowed to insert null or
160 the same interface more than once
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.
168 interface to be removed
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().
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.
212 Event to notify to all contained listeners
216 awt::PaintEvent aEvent( static_cast< cppu::OWeakObject* >( this ), ... );
217 listeners.notifyEach( &XPaintListener::windowPaint, aEvent );
220 template< typename ListenerT
, typename EventT
>
221 inline void notifyEach( void ( SAL_CALL
ListenerT::*NotificationMethod
)( const EventT
& ), const EventT
& Event
);
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. */
233 /** TRUE -> aData.pAsVector is of type Sequence< XInterfaceSequence >. */
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();
246 template< typename ListenerT
, typename EventT
>
247 class NotifySingleListener
250 typedef void ( SAL_CALL
ListenerT::*NotificationMethod
)( const EventT
& );
251 NotificationMethod
const m_pMethod
;
252 const EventT
& m_rEvent
;
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()) {
273 catch (css::lang::DisposedException
const& exc
) {
274 if (exc
.Context
== xListener
)
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
) );
290 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */