/src/libreoffice/include/comphelper/interfacecontainer2.hxx
Line | Count | Source |
1 | | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | | /* |
3 | | * This file is part of the LibreOffice project. |
4 | | * |
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/. |
8 | | * |
9 | | * This file incorporates work covered by the following license notice: |
10 | | * |
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 . |
18 | | */ |
19 | | #ifndef INCLUDED_COMPHELPER_INTERFACECONTAINER2_H |
20 | | #define INCLUDED_COMPHELPER_INTERFACECONTAINER2_H |
21 | | |
22 | | #include <sal/config.h> |
23 | | |
24 | | #include <vector> |
25 | | |
26 | | #include <com/sun/star/lang/DisposedException.hpp> |
27 | | #include <comphelper/comphelperdllapi.h> |
28 | | |
29 | | namespace com::sun::star::lang { struct EventObject; } |
30 | | namespace com::sun::star::uno { class XInterface; } |
31 | | namespace osl { class Mutex; } |
32 | | |
33 | | namespace comphelper |
34 | | { |
35 | | |
36 | | namespace detail { |
37 | | |
38 | | /** |
39 | | This is here to optimise space in the common case that there are zero or one |
40 | | listeners. |
41 | | */ |
42 | | union element_alias2 |
43 | | { |
44 | | std::vector< css::uno::Reference< css::uno::XInterface > > *pAsVector; |
45 | | css::uno::XInterface * pAsInterface; |
46 | 288k | element_alias2() : pAsInterface(nullptr) {} |
47 | | }; |
48 | | |
49 | | } |
50 | | |
51 | | |
52 | | class OInterfaceContainerHelper2; |
53 | | /** |
54 | | This is the iterator of an OInterfaceContainerHelper2. Typically |
55 | | one constructs an instance on the stack for one firing session. |
56 | | It is not allowed to assign or copy an instance of this class. |
57 | | |
58 | | @see OInterfaceContainerHelper2 |
59 | | */ |
60 | | class COMPHELPER_DLLPUBLIC OInterfaceIteratorHelper2 |
61 | | { |
62 | | public: |
63 | | /** |
64 | | Create an iterator over the elements of the container. The iterator |
65 | | copies the elements of the container. A change to the container |
66 | | during the lifetime of an iterator is allowed and does not |
67 | | affect the iterator-instance. The iterator and the container take cares |
68 | | themself for concurrent access, no additional guarding is necessary. |
69 | | |
70 | | Remark: The copy is on demand. The iterator copy the elements only if the container |
71 | | change the contents. It is not allowed to destroy the container as long |
72 | | as an iterator exist. |
73 | | |
74 | | @param rCont the container of the elements. |
75 | | */ |
76 | | OInterfaceIteratorHelper2( OInterfaceContainerHelper2 & rCont ); |
77 | | |
78 | | /** |
79 | | Releases the connection to the container. |
80 | | */ |
81 | | ~OInterfaceIteratorHelper2(); |
82 | | |
83 | | /** Return true, if there are more elements in the iterator. */ |
84 | | bool hasMoreElements() const |
85 | 361k | { return nRemain != 0; } |
86 | | /** Return the next element of the iterator. Calling this method if |
87 | | hasMoreElements() has returned false, is an error. Cast the |
88 | | returned pointer to the |
89 | | */ |
90 | | css::uno::XInterface * next(); |
91 | | |
92 | | /** Removes the current element (the last one returned by next()) |
93 | | from the underlying container. Calling this method before |
94 | | next() has been called or calling it twice with no next() |
95 | | inbetween is an error. |
96 | | */ |
97 | | void remove(); |
98 | | |
99 | | private: |
100 | | OInterfaceContainerHelper2 & rCont; |
101 | | detail::element_alias2 aData; |
102 | | sal_Int32 nRemain; |
103 | | bool bIsList; |
104 | | |
105 | | OInterfaceIteratorHelper2( const OInterfaceIteratorHelper2 & ) = delete; |
106 | | OInterfaceIteratorHelper2 & operator = ( const OInterfaceIteratorHelper2 & ) = delete; |
107 | | }; |
108 | | |
109 | | |
110 | | /** |
111 | | A container of interfaces. To access the elements use an iterator. |
112 | | This implementation is thread-safe. |
113 | | |
114 | | This is a copy of the code at include/cppuhelper/interfacecontainer.h, |
115 | | Except that it uses a std::vector instead of a Sequence for the mutable listener |
116 | | list, which provides far better performance. |
117 | | |
118 | | @see OInterfaceIteratorHelper2 |
119 | | */ |
120 | | class COMPHELPER_DLLPUBLIC OInterfaceContainerHelper2 |
121 | | { |
122 | | public: |
123 | | /** |
124 | | Create an interface container. |
125 | | |
126 | | @param rMutex the mutex to protect multi thread access. |
127 | | The lifetime must be longer than the lifetime |
128 | | of this object. |
129 | | */ |
130 | | OInterfaceContainerHelper2( ::osl::Mutex & rMutex ); |
131 | | /** |
132 | | Release all interfaces. All iterators must be destroyed before |
133 | | the container is destructed. |
134 | | */ |
135 | | ~OInterfaceContainerHelper2(); |
136 | | /** |
137 | | Return the number of Elements in the container. Only useful if you have acquired |
138 | | the mutex. |
139 | | */ |
140 | | sal_Int32 getLength() const; |
141 | | |
142 | | /** |
143 | | Return all interfaces added to this container. |
144 | | **/ |
145 | | std::vector< css::uno::Reference< css::uno::XInterface > > getElements() const; |
146 | | |
147 | | /** Inserts an element into the container. The position is not specified, thus it is not |
148 | | specified in which order events are fired. |
149 | | |
150 | | @attention |
151 | | If you add the same interface more than once, then it will be added to the elements list |
152 | | more than once and thus if you want to remove that interface from the list, you have to call |
153 | | removeInterface() the same number of times. |
154 | | In the latter case, you will also get events fired more than once (if the interface is a |
155 | | listener interface). |
156 | | |
157 | | @param rxIFace |
158 | | interface to be added; it is allowed to insert null or |
159 | | the same interface more than once |
160 | | @return |
161 | | the new count of elements in the container |
162 | | */ |
163 | | sal_Int32 addInterface( const css::uno::Reference< css::uno::XInterface > & rxIFace ); |
164 | | /** Removes an element from the container. It uses interface equality to remove the interface. |
165 | | |
166 | | @param rxIFace |
167 | | interface to be removed |
168 | | @return |
169 | | the new count of elements in the container |
170 | | */ |
171 | | sal_Int32 removeInterface( const css::uno::Reference< css::uno::XInterface > & rxIFace ); |
172 | | /** Return an interface by index */ |
173 | | css::uno::Reference< css::uno::XInterface > getInterface(sal_Int32 nIndex) const; |
174 | | /** |
175 | | Call disposing on all object in the container that |
176 | | support XEventListener. Then clear the container. |
177 | | */ |
178 | | void disposeAndClear( const css::lang::EventObject & rEvt ); |
179 | | /** |
180 | | Clears the container without calling disposing(). |
181 | | */ |
182 | | void clear(); |
183 | | |
184 | | /** Executes a functor for each contained listener of specified type, e.g. |
185 | | <code>forEach<awt::XPaintListener>(...</code>. |
186 | | |
187 | | If a css::lang::DisposedException occurs which relates to |
188 | | the called listener, then that listener is removed from the container. |
189 | | |
190 | | @tparam ListenerT listener type |
191 | | @tparam FuncT unary functor type, let your compiler deduce this for you |
192 | | @param func unary functor object expecting an argument of type |
193 | | css::uno::Reference<ListenerT> |
194 | | */ |
195 | | template <typename ListenerT, typename FuncT> |
196 | | inline void forEach( FuncT const& func ); |
197 | | |
198 | | /** Calls a UNO listener method for each contained listener. |
199 | | |
200 | | The listener method must take a single argument of type EventT, |
201 | | and return <code>void</code>. |
202 | | |
203 | | If a css::lang::DisposedException occurs which relates to |
204 | | the called listener, then that listener is removed from the container. |
205 | | |
206 | | @tparam ListenerT UNO event listener type, let your compiler deduce this for you |
207 | | @tparam EventT event type, let your compiler deduce this for you |
208 | | @param NotificationMethod |
209 | | Pointer to a method of a ListenerT interface. |
210 | | @param Event |
211 | | Event to notify to all contained listeners |
212 | | |
213 | | Example: |
214 | | @code |
215 | | awt::PaintEvent aEvent( static_cast< cppu::OWeakObject* >( this ), ... ); |
216 | | listeners.notifyEach( &XPaintListener::windowPaint, aEvent ); |
217 | | @endcode |
218 | | */ |
219 | | template< typename ListenerT, typename EventT > |
220 | | inline void notifyEach( void ( SAL_CALL ListenerT::*NotificationMethod )( const EventT& ), const EventT& Event ); |
221 | | |
222 | | private: |
223 | | friend class OInterfaceIteratorHelper2; |
224 | | /** |
225 | | bIsList == TRUE -> aData.pAsVector of type vector< XInterfaceSequence >, |
226 | | otherwise aData.pAsInterface == of type (XEventListener *) |
227 | | */ |
228 | | detail::element_alias2 aData; |
229 | | ::osl::Mutex & rMutex; |
230 | | /** TRUE -> used by an iterator. */ |
231 | | bool bInUse; |
232 | | /** TRUE -> aData.pAsVector is of type Sequence< XInterfaceSequence >. */ |
233 | | bool bIsList; |
234 | | |
235 | | OInterfaceContainerHelper2( const OInterfaceContainerHelper2 & ) = delete; |
236 | | OInterfaceContainerHelper2 & operator = ( const OInterfaceContainerHelper2 & ) = delete; |
237 | | |
238 | | /* |
239 | | Duplicate content of the container and release the old one without destroying. |
240 | | The mutex must be locked and the memberbInUse must be true. |
241 | | */ |
242 | | void copyAndResetInUse(); |
243 | | |
244 | | private: |
245 | | template< typename ListenerT, typename EventT > |
246 | | class NotifySingleListener |
247 | | { |
248 | | private: |
249 | | typedef void ( SAL_CALL ListenerT::*NotificationMethod )( const EventT& ); |
250 | | NotificationMethod const m_pMethod; |
251 | | const EventT& m_rEvent; |
252 | | public: |
253 | 0 | NotifySingleListener( NotificationMethod method, const EventT& event ) : m_pMethod( method ), m_rEvent( event ) { }Unexecuted instantiation: comphelper::OInterfaceContainerHelper2::NotifySingleListener<com::sun::star::container::XContainerListener, com::sun::star::container::ContainerEvent>::NotifySingleListener(void (com::sun::star::container::XContainerListener::*)(com::sun::star::container::ContainerEvent const&), com::sun::star::container::ContainerEvent const&) Unexecuted instantiation: comphelper::OInterfaceContainerHelper2::NotifySingleListener<com::sun::star::linguistic2::XLinguServiceEventListener, com::sun::star::linguistic2::LinguServiceEvent>::NotifySingleListener(void (com::sun::star::linguistic2::XLinguServiceEventListener::*)(com::sun::star::linguistic2::LinguServiceEvent const&), com::sun::star::linguistic2::LinguServiceEvent const&) Unexecuted instantiation: comphelper::OInterfaceContainerHelper2::NotifySingleListener<com::sun::star::linguistic2::XDictionaryListEventListener, com::sun::star::linguistic2::DictionaryListEvent>::NotifySingleListener(void (com::sun::star::linguistic2::XDictionaryListEventListener::*)(com::sun::star::linguistic2::DictionaryListEvent const&), com::sun::star::linguistic2::DictionaryListEvent const&) |
254 | | |
255 | | void operator()( const css::uno::Reference<ListenerT>& listener ) const |
256 | 0 | { |
257 | 0 | (listener.get()->*m_pMethod)( m_rEvent ); |
258 | 0 | } Unexecuted instantiation: comphelper::OInterfaceContainerHelper2::NotifySingleListener<com::sun::star::container::XContainerListener, com::sun::star::container::ContainerEvent>::operator()(com::sun::star::uno::Reference<com::sun::star::container::XContainerListener> const&) const Unexecuted instantiation: comphelper::OInterfaceContainerHelper2::NotifySingleListener<com::sun::star::linguistic2::XLinguServiceEventListener, com::sun::star::linguistic2::LinguServiceEvent>::operator()(com::sun::star::uno::Reference<com::sun::star::linguistic2::XLinguServiceEventListener> const&) const Unexecuted instantiation: comphelper::OInterfaceContainerHelper2::NotifySingleListener<com::sun::star::linguistic2::XDictionaryListEventListener, com::sun::star::linguistic2::DictionaryListEvent>::operator()(com::sun::star::uno::Reference<com::sun::star::linguistic2::XDictionaryListEventListener> const&) const |
259 | | }; |
260 | | }; |
261 | | |
262 | | template <typename ListenerT, typename FuncT> |
263 | | inline void OInterfaceContainerHelper2::forEach( FuncT const& func ) |
264 | 0 | { |
265 | 0 | OInterfaceIteratorHelper2 iter( *this ); |
266 | 0 | while (iter.hasMoreElements()) { |
267 | 0 | css::uno::Reference<ListenerT> const xListener( iter.next(), css::uno::UNO_QUERY ); |
268 | 0 | if (xListener.is()) { |
269 | 0 | try { |
270 | 0 | func( xListener ); |
271 | 0 | } |
272 | 0 | catch (css::lang::DisposedException const& exc) { |
273 | 0 | if (exc.Context == xListener) |
274 | 0 | iter.remove(); |
275 | 0 | } |
276 | 0 | } |
277 | 0 | } |
278 | 0 | } Unexecuted instantiation: definitioncontainer.cxx:void comphelper::OInterfaceContainerHelper2::forEach<com::sun::star::container::XContainerApproveListener, dbaccess::(anonymous namespace)::RaiseExceptionFromVeto>(dbaccess::(anonymous namespace)::RaiseExceptionFromVeto const&) Unexecuted instantiation: void comphelper::OInterfaceContainerHelper2::forEach<com::sun::star::container::XContainerListener, comphelper::OInterfaceContainerHelper2::NotifySingleListener<com::sun::star::container::XContainerListener, com::sun::star::container::ContainerEvent> >(comphelper::OInterfaceContainerHelper2::NotifySingleListener<com::sun::star::container::XContainerListener, com::sun::star::container::ContainerEvent> const&) Unexecuted instantiation: void comphelper::OInterfaceContainerHelper2::forEach<com::sun::star::linguistic2::XLinguServiceEventListener, comphelper::OInterfaceContainerHelper2::NotifySingleListener<com::sun::star::linguistic2::XLinguServiceEventListener, com::sun::star::linguistic2::LinguServiceEvent> >(comphelper::OInterfaceContainerHelper2::NotifySingleListener<com::sun::star::linguistic2::XLinguServiceEventListener, com::sun::star::linguistic2::LinguServiceEvent> const&) Unexecuted instantiation: void comphelper::OInterfaceContainerHelper2::forEach<com::sun::star::linguistic2::XDictionaryListEventListener, comphelper::OInterfaceContainerHelper2::NotifySingleListener<com::sun::star::linguistic2::XDictionaryListEventListener, com::sun::star::linguistic2::DictionaryListEvent> >(comphelper::OInterfaceContainerHelper2::NotifySingleListener<com::sun::star::linguistic2::XDictionaryListEventListener, com::sun::star::linguistic2::DictionaryListEvent> const&) Unexecuted instantiation: olemisc.cxx:void comphelper::OInterfaceContainerHelper2::forEach<com::sun::star::document::XEventListener, OleEmbeddedObject::MakeEventListenerNotification_Impl(rtl::OUString const&, osl::ResettableGuard<osl::Mutex>&)::$_0>(OleEmbeddedObject::MakeEventListenerNotification_Impl(rtl::OUString const&, osl::ResettableGuard<osl::Mutex>&)::$_0 const&) |
279 | | |
280 | | template< typename ListenerT, typename EventT > |
281 | | inline void OInterfaceContainerHelper2::notifyEach( void ( SAL_CALL ListenerT::*NotificationMethod )( const EventT& ), const EventT& Event ) |
282 | 0 | { |
283 | 0 | forEach< ListenerT, NotifySingleListener< ListenerT, EventT > >( NotifySingleListener< ListenerT, EventT >( NotificationMethod, Event ) ); |
284 | 0 | } Unexecuted instantiation: void comphelper::OInterfaceContainerHelper2::notifyEach<com::sun::star::container::XContainerListener, com::sun::star::container::ContainerEvent>(void (com::sun::star::container::XContainerListener::*)(com::sun::star::container::ContainerEvent const&), com::sun::star::container::ContainerEvent const&) Unexecuted instantiation: void comphelper::OInterfaceContainerHelper2::notifyEach<com::sun::star::linguistic2::XLinguServiceEventListener, com::sun::star::linguistic2::LinguServiceEvent>(void (com::sun::star::linguistic2::XLinguServiceEventListener::*)(com::sun::star::linguistic2::LinguServiceEvent const&), com::sun::star::linguistic2::LinguServiceEvent const&) Unexecuted instantiation: void comphelper::OInterfaceContainerHelper2::notifyEach<com::sun::star::linguistic2::XDictionaryListEventListener, com::sun::star::linguistic2::DictionaryListEvent>(void (com::sun::star::linguistic2::XDictionaryListEventListener::*)(com::sun::star::linguistic2::DictionaryListEvent const&), com::sun::star::linguistic2::DictionaryListEvent const&) |
285 | | |
286 | | } |
287 | | #endif |
288 | | |
289 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |