LibreOffice
LibreOffice 24.2 SDK C/C++ API Reference
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"
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 
44 namespace cppu
45 {
46 
47 namespace detail {
48 
54  {
55  std::vector< css::uno::Reference< css::uno::XInterface > > *pAsVector;
56  css::uno::XInterface * pAsInterface;
58  };
59 
60 }
61 
62 
63 class OInterfaceContainerHelper;
72 {
73 public:
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 
110 private:
112  sal_Bool bIsList;
113 
114  detail::element_alias aData;
115 
116  sal_Int32 nRemain;
117 
120  OInterfaceIteratorHelper & operator = ( const OInterfaceIteratorHelper & )
122 };
123 
124 
132 {
133 public:
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 
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 
241 private:
247  detail::element_alias aData;
248  ::osl::Mutex & rMutex;
250  sal_Bool bInUse;
252  sal_Bool bIsList;
253 
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 
265 private:
266  template< typename ListenerT, typename EventT >
267  class NotifySingleListener
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 
283 template <typename ListenerT, typename FuncT>
284 inline 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 
301 template< typename ListenerT, typename EventT >
302 inline 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 
314 template< class key, class hashImpl = void, class equalImpl = std::equal_to<key> >
316 {
317 public:
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 
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;
402 private:
403  typedef ::std::vector< std::pair < key , void* > > InterfaceMap;
404  InterfaceMap *m_pMap;
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 
438 template < class container , class keyType >
440 {
444  container aLC;
449 
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 {
517 public:
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 
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;
600 private:
601  void * m_pMap;
602  ::osl::Mutex & rMutex;
603 
606 };
607 
609 
610 }
611 
612 #endif
613 
614 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
sal_Bool bInDispose
In dispose call.
Definition: interfacecontainer.h:448
std::vector< css::uno::Reference< css::uno::XInterface > > * pAsVector
Definition: interfacecontainer.h:55
OBroadcastHelperVar(::osl::Mutex &rMutex_)
Initialize the structure.
Definition: interfacecontainer.h:454
css::uno::Type keyType
Definition: interfacecontainer.h:599
size_t operator()(const css::uno::Type &s) const
Definition: interfacecontainer.h:507
OBroadcastHelperVar< OMultiTypeInterfaceContainerHelper, OMultiTypeInterfaceContainerHelper::keyType > OBroadcastHelper
Definition: interfacecontainer.h:608
This enum value can be used for implicit interface query.
Definition: Reference.h:157
OMultiTypeInterfaceContainerHelperVar(::osl::Mutex &rMutex)
Create a container of interface containers.
Definition: interfacecontainer.hxx:37
#define SAL_DELETED_FUNCTION
short-circuit extra-verbose API namespaces
Definition: types.h:378
void removeListener(const keyType &key, const css::uno::Reference< css::uno::XInterface > &r)
removes a listener threadsafe
Definition: interfacecontainer.h:478
container aLC
ListenerContainer class is thread safe.
Definition: interfacecontainer.h:444
::osl::Mutex & rMutex
The shared mutex.
Definition: interfacecontainer.h:442
Object lifetime scoped mutex object or interface lock.
Definition: mutex.hxx:123
#define SAL_WARN_UNUSED
Annotate classes where a compiler should warn if an instance is unused.
Definition: types.h:587
Provides simple diagnostic support.
A container of interfaces.
Definition: interfacecontainer.h:131
SAL_DLLPUBLIC void * rtl_allocateMemory(sal_Size Bytes) SAL_THROW_EXTERN_C()
Allocate memory.
element_alias()
Definition: interfacecontainer.h:57
Definition: types.h:359
Specialized class for key type css::uno::Type, without explicit usage of STL symbols.
Definition: interfacecontainer.h:515
A mutual exclusion synchronization object.
Definition: mutex.hxx:35
A helper class to store interface references of different types.
Definition: interfacecontainer.h:315
void forEach(FuncT const &func)
Executes a functor for each contained listener of specified type, e.g.
Definition: interfacecontainer.h:284
unsigned char sal_Bool
Definition: types.h:38
OInterfaceContainerHelper * getContainer(const keyType &key) const
Return the container created under this key.
Definition: interfacecontainer.h:493
void disposeAndClear(const css::lang::EventObject &rEvt)
Call disposing on all references in the container, that support XEventListener.
Definition: interfacecontainer.hxx:142
Definition: Enterable.hxx:30
This is the iterator of an InterfaceContainerHelper.
Definition: interfacecontainer.h:71
~OMultiTypeInterfaceContainerHelperVar()
Deletes all containers.
Definition: interfacecontainer.hxx:45
#define CPPUHELPER_DLLPUBLIC
Definition: cppuhelperdllapi.h:32
void remove()
Removes the current element (the last one returned by next()) from the underlying container...
key keyType
Definition: interfacecontainer.h:401
Definition: interfacecontainer.h:505
css::uno::XInterface * pAsInterface
Definition: interfacecontainer.h:56
This is here to optimise space in the common case that there are zero or one listeners.
Definition: interfacecontainer.h:53
void notifyEach(void(ListenerT::*NotificationMethod)(const EventT &), const EventT &Event)
Calls a UNO listener method for each contained listener.
Definition: interfacecontainer.h:302
css::uno::XInterface * next()
Return the next element of the iterator.
SAL_DLLPUBLIC void rtl_freeMemory(void *Ptr) SAL_THROW_EXTERN_C()
Free memory.
void clear()
Remove all elements of all containers.
Definition: interfacecontainer.hxx:179
void addListener(const keyType &key, const css::uno::Reference< css::uno::XInterface > &r)
adds a listener threadsafe.
Definition: interfacecontainer.h:464
sal_Int32 removeInterface(const key &rKey, const css::uno::Reference< css::uno::XInterface > &rxIFace)
Removes an element from the container with the specified key.
Definition: interfacecontainer.hxx:124
This struct contains the standard variables of a broadcaster.
Definition: interfacecontainer.h:439
sal_Bool bDisposed
Dispose call ready.
Definition: interfacecontainer.h:446
OInterfaceContainerHelper * getContainer(const key &) const
Return the container created under this key.
Definition: interfacecontainer.hxx:93
bool hasMoreElements() const
Return true, if there are more elements in the iterator.
Definition: interfacecontainer.h:95
#define OSL_ENSURE(c, m)
If cond is false, reports an error with message msg.
Definition: diagnose.h:87
css::uno::Sequence< key > getContainedTypes() const
Return all id&#39;s under which at least one interface is added.
Definition: interfacecontainer.hxx:61
sal_Int32 addInterface(const key &rKey, const css::uno::Reference< css::uno::XInterface > &r)
Inserts an element into the container with the specified key.
Definition: interfacecontainer.hxx:106