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 
42 namespace com { namespace sun { namespace star { namespace uno { class XInterface; } } } }
43  //for docpp
45 namespace cppu
46 {
47 
48 namespace detail {
49 
55  {
56  std::vector< css::uno::Reference< css::uno::XInterface > > *pAsVector;
57  css::uno::XInterface * pAsInterface;
58  element_alias() : pAsInterface(NULL) {}
59  };
60 
61 }
62 
63 
64 class OInterfaceContainerHelper;
73 {
74 public:
89 
94 
96  bool SAL_CALL hasMoreElements() const
97  { return nRemain != 0; }
102  css::uno::XInterface * SAL_CALL next();
103 
109  void SAL_CALL remove();
110 
111 private:
114 
116 
117  sal_Int32 nRemain;
118 
120  SAL_DELETED_FUNCTION;
121  OInterfaceIteratorHelper & operator = ( const OInterfaceIteratorHelper & )
122  SAL_DELETED_FUNCTION;
123 };
124 
125 
133 {
134 public:
135  // these are here to force memory de/allocation to sal lib.
136  static void * SAL_CALL operator new( size_t nSize )
137  { return ::rtl_allocateMemory( nSize ); }
138  static void SAL_CALL operator delete( void * pMem )
139  { ::rtl_freeMemory( pMem ); }
140  static void * SAL_CALL operator new( size_t, void * pMem )
141  { return pMem; }
142  static void SAL_CALL operator delete( void *, void * )
143  {}
144 
152  OInterfaceContainerHelper( ::osl::Mutex & rMutex );
157  ~OInterfaceContainerHelper();
162  sal_Int32 SAL_CALL getLength() const;
163 
167  css::uno::Sequence< css::uno::Reference< css::uno::XInterface > > SAL_CALL getElements() const;
168 
185  sal_Int32 SAL_CALL addInterface( const css::uno::Reference< css::uno::XInterface > & rxIFace );
193  sal_Int32 SAL_CALL removeInterface( const css::uno::Reference< css::uno::XInterface > & rxIFace );
198  void SAL_CALL disposeAndClear( const css::lang::EventObject & rEvt );
202  void SAL_CALL clear();
203 
215  template <typename ListenerT, typename FuncT>
216  inline void forEach( FuncT const& func );
217 
239  template< typename ListenerT, typename EventT >
240  inline void notifyEach( void ( SAL_CALL ListenerT::*NotificationMethod )( const EventT& ), const EventT& Event );
241 
242 private:
249  ::osl::Mutex & rMutex;
254 
255  OInterfaceContainerHelper( const OInterfaceContainerHelper & )
256  SAL_DELETED_FUNCTION;
257  OInterfaceContainerHelper & operator = ( const OInterfaceContainerHelper & )
258  SAL_DELETED_FUNCTION;
259 
260  /*
261  Duplicate content of the container and release the old one without destroying.
262  The mutex must be locked and the memberbInUse must be true.
263  */
264  void copyAndResetInUse();
265 
266 private:
267  template< typename ListenerT, typename EventT >
269  {
270  private:
271  typedef void ( SAL_CALL ListenerT::*NotificationMethod )( const EventT& );
272  NotificationMethod m_pMethod;
273  const EventT& m_rEvent;
274  public:
275  NotifySingleListener( NotificationMethod method, const EventT& event ) : m_pMethod( method ), m_rEvent( event ) { }
276 
277  void operator()( const css::uno::Reference<ListenerT>& listener ) const
278  {
279  (listener.get()->*m_pMethod)( m_rEvent );
280  }
281  };
282 };
283 
284 template <typename ListenerT, typename FuncT>
285 inline void OInterfaceContainerHelper::forEach( FuncT const& func )
286 {
287  OInterfaceIteratorHelper iter( *this );
288  while (iter.hasMoreElements()) {
289  css::uno::Reference<ListenerT> const xListener( iter.next(), css::uno::UNO_QUERY );
290  if (xListener.is()) {
291  try {
292  func( xListener );
293  }
294  catch (css::lang::DisposedException const& exc) {
295  if (exc.Context == xListener)
296  iter.remove();
297  }
298  }
299  }
300 }
301 
302 template< typename ListenerT, typename EventT >
303 inline void OInterfaceContainerHelper::notifyEach( void ( SAL_CALL ListenerT::*NotificationMethod )( const EventT& ), const EventT& Event )
304 {
305  forEach< ListenerT, NotifySingleListener< ListenerT, EventT > >( NotifySingleListener< ListenerT, EventT >( NotificationMethod, Event ) );
306 }
307 
308 
315 template< class key, class hashImpl = void, class equalImpl = std::equal_to<key> >
317 {
318 public:
319  // these are here to force memory de/allocation to sal lib.
320  static void * SAL_CALL operator new( size_t nSize )
321  { return ::rtl_allocateMemory( nSize ); }
322  static void SAL_CALL operator delete( void * pMem )
323  { ::rtl_freeMemory( pMem ); }
324  static void * SAL_CALL operator new( size_t, void * pMem )
325  { return pMem; }
326  static void SAL_CALL operator delete( void *, void * )
327  {}
328 
336  inline OMultiTypeInterfaceContainerHelperVar( ::osl::Mutex & rMutex );
341 
345  inline css::uno::Sequence< key > SAL_CALL getContainedTypes() const;
346 
353  inline OInterfaceContainerHelper * SAL_CALL getContainer( const key & ) const;
354 
373  inline sal_Int32 SAL_CALL addInterface(
374  const key & rKey,
375  const css::uno::Reference< css::uno::XInterface > & r );
376 
387  inline sal_Int32 SAL_CALL removeInterface(
388  const key & rKey,
389  const css::uno::Reference< css::uno::XInterface > & rxIFace );
390 
396  inline void SAL_CALL disposeAndClear( const css::lang::EventObject & rEvt );
400  inline void SAL_CALL clear();
401 
402  typedef key keyType;
403 private:
404  typedef ::std::vector< std::pair < key , void* > > InterfaceMap;
405  InterfaceMap *m_pMap;
406  ::osl::Mutex & rMutex;
407 
408  typename InterfaceMap::iterator find(const key &rKey) const
409  {
410  typename InterfaceMap::iterator iter = m_pMap->begin();
411  typename InterfaceMap::iterator end = m_pMap->end();
412 
413  while( iter != end )
414  {
415  equalImpl equal;
416  if( equal( iter->first, rKey ) )
417  break;
418  ++iter;
419  }
420  return iter;
421  }
422 
424  OMultiTypeInterfaceContainerHelperVar & operator = ( const OMultiTypeInterfaceContainerHelperVar & ) SAL_DELETED_FUNCTION;
425 };
426 
427 
428 
429 
439 template < class container , class keyType >
440 struct SAL_WARN_UNUSED OBroadcastHelperVar
441 {
443  ::osl::Mutex & rMutex;
445  container aLC;
450 
455  OBroadcastHelperVar( ::osl::Mutex & rMutex_ )
456  : rMutex( rMutex_ )
457  , aLC( rMutex_ )
458  , bDisposed( false )
459  , bInDispose( false )
460  {}
461 
466  const keyType &key,
467  const css::uno::Reference < css::uno::XInterface > &r )
468  {
469  ::osl::MutexGuard guard( rMutex );
470  OSL_ENSURE( !bInDispose, "do not add listeners in the dispose call" );
471  OSL_ENSURE( !bDisposed, "object is disposed" );
472  if( ! bInDispose && ! bDisposed )
473  aLC.addInterface( key , r );
474  }
475 
480  const keyType &key,
481  const css::uno::Reference < css::uno::XInterface > & r )
482  {
483  ::osl::MutexGuard guard( rMutex );
484  if( ! bInDispose && ! bDisposed )
485  aLC.removeInterface( key , r );
486  }
487 
494  OInterfaceContainerHelper * SAL_CALL getContainer( const keyType &key ) const
495  { return aLC.getContainer( key ); }
496 };
497 
498 /*------------------------------------------
499 *
500 * In general, the above templates are used with a Type as key.
501 * Therefore a default declaration is given ( OMultiTypeInterfaceContainerHelper and OBroadcastHelper )
502 *
503 *------------------------------------------*/
504 
505 // helper function call class
507 {
508  size_t operator()(const css::uno::Type & s) const
509  { return static_cast<size_t>(s.getTypeName().hashCode()); }
510 };
511 
512 
517 {
518 public:
519  // these are here to force memory de/allocation to sal lib.
520  static void * SAL_CALL operator new( size_t nSize )
521  { return ::rtl_allocateMemory( nSize ); }
522  static void SAL_CALL operator delete( void * pMem )
523  { ::rtl_freeMemory( pMem ); }
524  static void * SAL_CALL operator new( size_t, void * pMem )
525  { return pMem; }
526  static void SAL_CALL operator delete( void *, void * )
527  {}
528 
536  OMultiTypeInterfaceContainerHelper( ::osl::Mutex & rMutex );
541 
545  css::uno::Sequence< css::uno::Type > SAL_CALL getContainedTypes() const;
546 
552  OInterfaceContainerHelper * SAL_CALL getContainer( const css::uno::Type & rKey ) const;
553 
572  sal_Int32 SAL_CALL addInterface(
573  const css::uno::Type & rKey,
574  const css::uno::Reference< css::uno::XInterface > & r );
575 
586  sal_Int32 SAL_CALL removeInterface(
587  const css::uno::Type & rKey,
588  const css::uno::Reference< css::uno::XInterface > & rxIFace );
589 
594  void SAL_CALL disposeAndClear( const css::lang::EventObject & rEvt );
598  void SAL_CALL clear();
599 
600  typedef css::uno::Type keyType;
601 private:
602  void * m_pMap;
603  ::osl::Mutex & rMutex;
604 
606  OMultiTypeInterfaceContainerHelper & operator = ( const OMultiTypeInterfaceContainerHelper & ) SAL_DELETED_FUNCTION;
607 };
608 
609 typedef OBroadcastHelperVar< OMultiTypeInterfaceContainerHelper , OMultiTypeInterfaceContainerHelper::keyType > OBroadcastHelper;
610 
611 }
612 
613 #endif
614 
615 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
This is here to optimise space in the common case that there are zero or one listeners.
NotifySingleListener(NotificationMethod method, const EventT &event)
OInterfaceContainerHelper & rCont
sal_Bool bInUse
TRUE -> used by an iterator.
std::vector< css::uno::Reference< css::uno::XInterface > > * pAsVector
css::uno::XInterface *SAL_CALL next()
Return the next element of the iterator.
void operator()(const css::uno::Reference< ListenerT > &listener) const
::osl::Mutex & rMutex
The shared mutex.
container aLC
ListenerContainer class is thread safe.
return NULL
OInterfaceContainerHelper *SAL_CALL getContainer(const keyType &key) const
Return the container created under this key.
This is the iterator of an InterfaceContainerHelper.
css::uno::XInterface * pAsInterface
detail::element_alias aData
bIsList == TRUE -> aData.pAsSequence of type Sequence< XInterfaceSequence >, otherwise aData...
InterfaceMap::iterator find(const key &rKey) const
A helper class to store interface references of different types.
void addListener(const keyType &key, const css::uno::Reference< css::uno::XInterface > &r)
adds a listener threadsafe.
sal_Bool bDisposed
Dispose call ready.
void removeListener(const keyType &key, const css::uno::Reference< css::uno::XInterface > &r)
removes a listener threadsafe
size_t operator()(const css::uno::Type &s) const
bool equal(T const &rfValA, T const &rfValB)
unsigned char sal_Bool
This struct contains the standard variables of a broadcaster.
sal_Bool bIsList
TRUE -> aData.pAsSequence is of type Sequence< XInterfaceSequence >.
sal_Bool bInDispose
In dispose call.
enumrange< T >::Iterator end(enumrange< T >)
::std::vector< std::pair< key, void * > > InterfaceMap
A container of interfaces.
OBroadcastHelperVar(::osl::Mutex &rMutex_)
Initialize the structure.
double getLength(const B2DPolygon &rCandidate)
void forEach(FuncT const &func)
Executes a functor for each contained listener of specified type, e.g.
void notifyEach(void(SAL_CALL ListenerT::*NotificationMethod)(const EventT &), const EventT &Event)
Calls a UNO listener method for each contained listener.
#define CPPUHELPER_DLLPUBLIC
Specialized class for key type css::uno::Type, without explicit usage of STL symbols.
void SAL_CALL remove()
Removes the current element (the last one returned by next()) from the underlying container...
bool SAL_CALL hasMoreElements() const
Return true, if there are more elements in the iterator.