LibreOffice Module cppuhelper (master) 1
interfacecontainer.h
Go to the documentation of this file.
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
20/*
21 * This file is part of LibreOffice published API.
22 */
23#ifndef INCLUDED_CPPUHELPER_INTERFACECONTAINER_H
24#define INCLUDED_CPPUHELPER_INTERFACECONTAINER_H
25
26#include "sal/config.h"
27
28#include <cstddef>
29#include <functional>
30#include <vector>
31#include <utility>
32
33#include "osl/diagnose.h"
34#include "osl/mutex.hxx"
35#include "rtl/alloc.h"
36#include "com/sun/star/uno/Sequence.hxx"
37#include "com/sun/star/lang/EventObject.hpp"
38
39#include "com/sun/star/lang/DisposedException.hpp"
41
42namespace com { namespace sun { namespace star { namespace uno { class XInterface; } } } }
43
44namespace cppu
45{
46
47namespace detail {
48
54 {
55 std::vector< css::uno::Reference< css::uno::XInterface > > *pAsVector;
56 css::uno::XInterface * pAsInterface;
58 };
59
60}
61
62
63class OInterfaceContainerHelper;
72{
73public:
88
93
95 bool SAL_CALL hasMoreElements() const
96 { return nRemain != 0; }
101 css::uno::XInterface * SAL_CALL next();
102
108 void SAL_CALL remove();
109
110private:
113
115
116 sal_Int32 nRemain;
117
119 SAL_DELETED_FUNCTION;
121 SAL_DELETED_FUNCTION;
122};
123
124
132{
133public:
134 // these are here to force memory de/allocation to sal lib.
135 static void * SAL_CALL operator new( size_t nSize )
136 { return ::rtl_allocateMemory( nSize ); }
137 static void SAL_CALL operator delete( void * pMem )
138 { ::rtl_freeMemory( pMem ); }
139 static void * SAL_CALL operator new( size_t, void * pMem )
140 { return pMem; }
141 static void SAL_CALL operator delete( void *, void * )
142 {}
143
151 OInterfaceContainerHelper( ::osl::Mutex & rMutex );
161 sal_Int32 SAL_CALL getLength() const;
162
166 css::uno::Sequence< css::uno::Reference< css::uno::XInterface > > SAL_CALL getElements() const;
167
184 sal_Int32 SAL_CALL addInterface( const css::uno::Reference< css::uno::XInterface > & rxIFace );
192 sal_Int32 SAL_CALL removeInterface( const css::uno::Reference< css::uno::XInterface > & rxIFace );
197 void SAL_CALL disposeAndClear( const css::lang::EventObject & rEvt );
201 void SAL_CALL clear();
202
214 template <typename ListenerT, typename FuncT>
215 inline void forEach( FuncT const& func );
216
238 template< typename ListenerT, typename EventT >
239 inline void notifyEach( void ( SAL_CALL ListenerT::*NotificationMethod )( const EventT& ), const EventT& Event );
240
241private:
248 ::osl::Mutex & rMutex;
253
255 SAL_DELETED_FUNCTION;
257 SAL_DELETED_FUNCTION;
258
259 /*
260 Duplicate content of the container and release the old one without destroying.
261 The mutex must be locked and the memberbInUse must be true.
262 */
263 void copyAndResetInUse();
264
265private:
266 template< typename ListenerT, typename EventT >
268 {
269 private:
270 typedef void ( SAL_CALL ListenerT::*NotificationMethod )( const EventT& );
271 NotificationMethod m_pMethod;
272 const EventT& m_rEvent;
273 public:
274 NotifySingleListener( NotificationMethod method, const EventT& event ) : m_pMethod( method ), m_rEvent( event ) { }
275
276 void operator()( const css::uno::Reference<ListenerT>& listener ) const
277 {
278 (listener.get()->*m_pMethod)( m_rEvent );
279 }
280 };
281};
282
283template <typename ListenerT, typename FuncT>
284inline void OInterfaceContainerHelper::forEach( FuncT const& func )
285{
286 OInterfaceIteratorHelper iter( *this );
287 while (iter.hasMoreElements()) {
288 css::uno::Reference<ListenerT> const xListener( iter.next(), css::uno::UNO_QUERY );
289 if (xListener.is()) {
290 try {
291 func( xListener );
292 }
293 catch (css::lang::DisposedException const& exc) {
294 if (exc.Context == xListener)
295 iter.remove();
296 }
297 }
298 }
299}
300
301template< typename ListenerT, typename EventT >
302inline void OInterfaceContainerHelper::notifyEach( void ( SAL_CALL ListenerT::*NotificationMethod )( const EventT& ), const EventT& Event )
303{
304 forEach< ListenerT, NotifySingleListener< ListenerT, EventT > >( NotifySingleListener< ListenerT, EventT >( NotificationMethod, Event ) );
305}
306
307
314template< class key, class hashImpl = void, class equalImpl = std::equal_to<key> >
316{
317public:
318 // these are here to force memory de/allocation to sal lib.
319 static void * SAL_CALL operator new( size_t nSize )
320 { return ::rtl_allocateMemory( nSize ); }
321 static void SAL_CALL operator delete( void * pMem )
322 { ::rtl_freeMemory( pMem ); }
323 static void * SAL_CALL operator new( size_t, void * pMem )
324 { return pMem; }
325 static void SAL_CALL operator delete( void *, void * )
326 {}
327
335 inline OMultiTypeInterfaceContainerHelperVar( ::osl::Mutex & rMutex );
340
344 inline css::uno::Sequence< key > SAL_CALL getContainedTypes() const;
345
352 inline OInterfaceContainerHelper * SAL_CALL getContainer( const key & ) const;
353
372 inline sal_Int32 SAL_CALL addInterface(
373 const key & rKey,
374 const css::uno::Reference< css::uno::XInterface > & r );
375
386 inline sal_Int32 SAL_CALL removeInterface(
387 const key & rKey,
388 const css::uno::Reference< css::uno::XInterface > & rxIFace );
389
395 inline void SAL_CALL disposeAndClear( const css::lang::EventObject & rEvt );
399 inline void SAL_CALL clear();
400
401 typedef key keyType;
402private:
403 typedef ::std::vector< std::pair < key , void* > > InterfaceMap;
405 ::osl::Mutex & rMutex;
406
407 typename InterfaceMap::iterator find(const key &rKey) const
408 {
409 typename InterfaceMap::iterator iter = m_pMap->begin();
410 typename InterfaceMap::iterator end = m_pMap->end();
411
412 while( iter != end )
413 {
414 equalImpl equal;
415 if( equal( iter->first, rKey ) )
416 break;
417 ++iter;
418 }
419 return iter;
420 }
421
424};
425
426
427
428
438template < class container , class keyType >
440{
442 ::osl::Mutex & rMutex;
444 container aLC;
449
454 OBroadcastHelperVar( ::osl::Mutex & rMutex_ )
455 : rMutex( rMutex_ )
456 , aLC( rMutex_ )
457 , bDisposed( false )
458 , bInDispose( false )
459 {}
460
465 const keyType &key,
466 const css::uno::Reference < css::uno::XInterface > &r )
467 {
468 ::osl::MutexGuard guard( rMutex );
469 OSL_ENSURE( !bInDispose, "do not add listeners in the dispose call" );
470 OSL_ENSURE( !bDisposed, "object is disposed" );
471 if( ! bInDispose && ! bDisposed )
472 aLC.addInterface( key , r );
473 }
474
479 const keyType &key,
480 const css::uno::Reference < css::uno::XInterface > & r )
481 {
482 ::osl::MutexGuard guard( rMutex );
483 if( ! bInDispose && ! bDisposed )
484 aLC.removeInterface( key , r );
485 }
486
493 OInterfaceContainerHelper * SAL_CALL getContainer( const keyType &key ) const
494 { return aLC.getContainer( key ); }
495};
496
497/*------------------------------------------
498*
499* In general, the above templates are used with a Type as key.
500* Therefore a default declaration is given ( OMultiTypeInterfaceContainerHelper and OBroadcastHelper )
501*
502*------------------------------------------*/
503
504// helper function call class
506{
507 size_t operator()(const css::uno::Type & s) const
508 { return static_cast<size_t>(s.getTypeName().hashCode()); }
509};
510
511
516{
517public:
518 // these are here to force memory de/allocation to sal lib.
519 static void * SAL_CALL operator new( size_t nSize )
520 { return ::rtl_allocateMemory( nSize ); }
521 static void SAL_CALL operator delete( void * pMem )
522 { ::rtl_freeMemory( pMem ); }
523 static void * SAL_CALL operator new( size_t, void * pMem )
524 { return pMem; }
525 static void SAL_CALL operator delete( void *, void * )
526 {}
527
535 OMultiTypeInterfaceContainerHelper( ::osl::Mutex & rMutex );
540
544 css::uno::Sequence< css::uno::Type > SAL_CALL getContainedTypes() const;
545
551 OInterfaceContainerHelper * SAL_CALL getContainer( const css::uno::Type & rKey ) const;
552
571 sal_Int32 SAL_CALL addInterface(
572 const css::uno::Type & rKey,
573 const css::uno::Reference< css::uno::XInterface > & r );
574
585 sal_Int32 SAL_CALL removeInterface(
586 const css::uno::Type & rKey,
587 const css::uno::Reference< css::uno::XInterface > & rxIFace );
588
593 void SAL_CALL disposeAndClear( const css::lang::EventObject & rEvt );
597 void SAL_CALL clear();
598
599 typedef css::uno::Type keyType;
600private:
601 void * m_pMap;
602 ::osl::Mutex & rMutex;
603
605 OMultiTypeInterfaceContainerHelper & operator = ( const OMultiTypeInterfaceContainerHelper & ) SAL_DELETED_FUNCTION;
606};
607
609
610}
611
612#endif
613
614/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
typedef void(SAL_CALL ListenerT::*NotificationMethod)(const EventT &)
NotifySingleListener(NotificationMethod method, const EventT &event)
void operator()(const css::uno::Reference< ListenerT > &listener) const
A container of interfaces.
sal_Bool bInUse
TRUE -> used by an iterator.
OInterfaceContainerHelper(const OInterfaceContainerHelper &) SAL_DELETED_FUNCTION
sal_Bool bIsList
TRUE -> aData.pAsSequence is of type Sequence< XInterfaceSequence >.
void forEach(FuncT const &func)
Executes a functor for each contained listener of specified type, e.g.
detail::element_alias aData
bIsList == TRUE -> aData.pAsSequence of type Sequence< XInterfaceSequence >, otherwise aData....
void notifyEach(void(SAL_CALL ListenerT::*NotificationMethod)(const EventT &), const EventT &Event)
Calls a UNO listener method for each contained listener.
OInterfaceContainerHelper(::osl::Mutex &rMutex)
Create an interface container.
This is the iterator of an InterfaceContainerHelper.
OInterfaceContainerHelper & rCont
css::uno::XInterface *SAL_CALL next()
Return the next element of the iterator.
bool SAL_CALL hasMoreElements() const
Return true, if there are more elements in the iterator.
void SAL_CALL remove()
Removes the current element (the last one returned by next()) from the underlying container.
OInterfaceIteratorHelper(const OInterfaceIteratorHelper &) SAL_DELETED_FUNCTION
A helper class to store interface references of different types.
~OMultiTypeInterfaceContainerHelperVar()
Deletes all containers.
sal_Int32 SAL_CALL addInterface(const key &rKey, const css::uno::Reference< css::uno::XInterface > &r)
Inserts an element into the container with the specified key.
OInterfaceContainerHelper *SAL_CALL getContainer(const key &) const
Return the container created under this key.
OMultiTypeInterfaceContainerHelperVar & operator=(const OMultiTypeInterfaceContainerHelperVar &) SAL_DELETED_FUNCTION
void SAL_CALL clear()
Remove all elements of all containers.
InterfaceMap::iterator find(const key &rKey) const
void SAL_CALL disposeAndClear(const css::lang::EventObject &rEvt)
Call disposing on all references in the container, that support XEventListener.
::std::vector< std::pair< key, void * > > InterfaceMap
OMultiTypeInterfaceContainerHelperVar(::osl::Mutex &rMutex)
Create a container of interface containers.
OMultiTypeInterfaceContainerHelperVar(const OMultiTypeInterfaceContainerHelperVar &) SAL_DELETED_FUNCTION
css::uno::Sequence< key > SAL_CALL getContainedTypes() const
Return all id's under which at least one interface is added.
sal_Int32 SAL_CALL removeInterface(const key &rKey, const css::uno::Reference< css::uno::XInterface > &rxIFace)
Removes an element from the container with the specified key.
Specialized class for key type css::uno::Type, without explicit usage of STL symbols.
OMultiTypeInterfaceContainerHelper(::osl::Mutex &rMutex)
Create a container of interface containers.
OMultiTypeInterfaceContainerHelper(const OMultiTypeInterfaceContainerHelper &) SAL_DELETED_FUNCTION
#define CPPUHELPER_DLLPUBLIC
const ContainerEvent & m_rEvent
ContainerApprovalMethod m_pMethod
return NULL
bool equal(T const &rfValA, T const &rfValB)
double getLength(const B2DPolygon &rCandidate)
OUStringBuffer & remove(OUStringBuffer &rIn, sal_Unicode c)
OBroadcastHelperVar< OMultiTypeInterfaceContainerHelper, OMultiTypeInterfaceContainerHelper::keyType > OBroadcastHelper
end
This struct contains the standard variables of a broadcaster.
void addListener(const keyType &key, const css::uno::Reference< css::uno::XInterface > &r)
adds a listener threadsafe.
container aLC
ListenerContainer class is thread safe.
::osl::Mutex & rMutex
The shared mutex.
sal_Bool bInDispose
In dispose call.
void removeListener(const keyType &key, const css::uno::Reference< css::uno::XInterface > &r)
removes a listener threadsafe
sal_Bool bDisposed
Dispose call ready.
OBroadcastHelperVar(::osl::Mutex &rMutex_)
Initialize the structure.
OInterfaceContainerHelper *SAL_CALL getContainer(const keyType &key) const
Return the container created under this key.
size_t operator()(const css::uno::Type &s) const
unsigned char sal_Bool
#define SAL_WARN_UNUSED
This is here to optimise space in the common case that there are zero or one listeners.
std::vector< css::uno::Reference< css::uno::XInterface > > * pAsVector
css::uno::XInterface * pAsInterface