LibreOffice Module comphelper (master)  1
multiinterfacecontainer2.hxx
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 #pragma once
20 
21 #include <sal/config.h>
22 
23 #include <com/sun/star/lang/EventObject.hpp>
24 #include <com/sun/star/lang/DisposedException.hpp>
27 #include <memory>
28 #include <vector>
29 
30 namespace com::sun::star::uno
31 {
32 class XInterface;
33 }
34 namespace osl
35 {
36 class Mutex;
37 }
38  //for docpp
40 namespace comphelper
41 {
50 template <class key, class hashImpl = void, class equalImpl = std::equal_to<key>>
52 {
53 public:
61  inline OMultiTypeInterfaceContainerHelperVar2(::osl::Mutex& rMutex_)
62  : rMutex(rMutex_)
63  {
64  }
65 
69  inline std::vector<key> getContainedTypes() const
70  {
71  ::osl::MutexGuard aGuard(rMutex);
72  std::vector<key> aInterfaceTypes;
73  aInterfaceTypes.reserve(m_aMap.size());
74  for (const auto& rPair : m_aMap)
75  // are interfaces added to this container?
76  if (rPair.second->getLength())
77  // yes, put the type in the array
78  aInterfaceTypes.push_back(rPair.first);
79  return aInterfaceTypes;
80  }
81 
82  inline bool hasContainedTypes() const
83  {
84  ::osl::MutexGuard aGuard(rMutex);
85  for (const auto& rPair : m_aMap)
86  // are interfaces added to this container?
87  if (rPair.second->getLength())
88  return true;
89  return false;
90  }
91 
98  inline OInterfaceContainerHelper2* getContainer(const key& rKey) const
99  {
100  ::osl::MutexGuard aGuard(rMutex);
101 
102  auto iter = find(rKey);
103  if (iter != m_aMap.end())
104  return (*iter).second.get();
105  return nullptr;
106  }
107 
126  inline sal_Int32 addInterface(const key& rKey,
127  const css::uno::Reference<css::uno::XInterface>& rListener)
128  {
129  ::osl::MutexGuard aGuard(rMutex);
130  auto iter = find(rKey);
131  if (iter == m_aMap.end())
132  {
134  m_aMap.emplace_back(rKey, pLC);
135  return pLC->addInterface(rListener);
136  }
137  else
138  return (*iter).second->addInterface(rListener);
139  }
140 
151  inline sal_Int32 removeInterface(const key& rKey,
152  const css::uno::Reference<css::uno::XInterface>& rListener)
153  {
154  ::osl::MutexGuard aGuard(rMutex);
155 
156  // search container with id nUik
157  auto iter = find(rKey);
158  // container found?
159  if (iter != m_aMap.end())
160  return (*iter).second->removeInterface(rListener);
161 
162  // no container with this id. Always return 0
163  return 0;
164  }
165 
171  inline void disposeAndClear(const css::lang::EventObject& rEvt)
172  {
173  typename InterfaceMap::size_type nSize = 0;
174  OInterfaceContainerHelper2** ppListenerContainers = nullptr;
175  {
176  ::osl::MutexGuard aGuard(rMutex);
177  nSize = m_aMap.size();
178  if (nSize)
179  {
180  typedef OInterfaceContainerHelper2* ppp;
181  ppListenerContainers = new ppp[nSize];
182 
183  typename InterfaceMap::iterator iter = m_aMap.begin();
184  typename InterfaceMap::iterator end = m_aMap.end();
185 
186  typename InterfaceMap::size_type i = 0;
187  while (iter != end)
188  {
189  ppListenerContainers[i++] = (*iter).second.get();
190  ++iter;
191  }
192  }
193  }
194 
195  // create a copy, because do not fire event in a guarded section
196  for (typename InterfaceMap::size_type i = 0; i < nSize; i++)
197  {
198  if (ppListenerContainers[i])
199  ppListenerContainers[i]->disposeAndClear(rEvt);
200  }
201 
202  delete[] ppListenerContainers;
203  }
204 
208  inline void clear()
209  {
210  ::osl::MutexGuard aGuard(rMutex);
211 
212  for (const auto& rPair : m_aMap)
213  rPair.second->clear();
214  }
215 
216  typedef key keyType;
217 
218 private:
219  typedef ::std::vector<std::pair<key, std::unique_ptr<OInterfaceContainerHelper2>>> InterfaceMap;
220  InterfaceMap m_aMap;
221  ::osl::Mutex& rMutex;
222 
223  typename InterfaceMap::const_iterator find(const key& rKey) const
224  {
225  auto iter = m_aMap.begin();
226  auto end = m_aMap.end();
227 
228  while (iter != end)
229  {
230  equalImpl equal;
231  if (equal(iter->first, rKey))
232  break;
233  ++iter;
234  }
235  return iter;
236  }
237 
240  = delete;
241 };
242 
243 } // namespace comphelper
244 
245 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
OMultiTypeInterfaceContainerHelperVar2 & operator=(const OMultiTypeInterfaceContainerHelperVar2 &)=delete
OMultiTypeInterfaceContainerHelperVar2(::osl::Mutex &rMutex_)
Create a container of interface containers.
::std::vector< std::pair< key, std::unique_ptr< OInterfaceContainerHelper2 > > > InterfaceMap
sal_Int32 addInterface(const css::uno::Reference< css::uno::XInterface > &rxIFace)
Inserts an element into the container.
void disposeAndClear(const css::lang::EventObject &rEvt)
Call disposing on all object in the container that support XEventListener.
sal_Int32 addInterface(const key &rKey, const css::uno::Reference< css::uno::XInterface > &rListener)
Inserts an element into the container with the specified key.
void disposeAndClear(const css::lang::EventObject &rEvt)
Call disposing on all references in the container, that support XEventListener.
int i
bool equal(T const &rfValA, T const &rfValB)
std::vector< key > getContainedTypes() const
Return all id's under which at least one interface is added.
enumrange< T >::Iterator end(enumrange< T >)
OInterfaceContainerHelper2 * getContainer(const key &rKey) const
Return the container created under this key.
InterfaceMap::const_iterator find(const key &rKey) const
sal_Int32 removeInterface(const key &rKey, const css::uno::Reference< css::uno::XInterface > &rListener)
Removes an element from the container with the specified key.
A helper class to store interface references of different types.
void clear()
Remove all elements of all containers.