LibreOffice Module comphelper (master) 1
multiinterfacecontainer4.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#include <sal/config.h>
21#include <com/sun/star/lang/EventObject.hpp>
23#include <memory>
24#include <mutex>
25#include <vector> //for docpp
27namespace comphelper
28{
38template <class key, class listener, class equalImpl = std::equal_to<key>>
40{
41public:
46 inline std::vector<key> getContainedTypes(std::unique_lock<std::mutex>& rGuard) const
47 {
48 assert(rGuard.owns_lock());
49 std::vector<key> aInterfaceTypes;
50 aInterfaceTypes.reserve(m_aMap.size());
51 for (const auto& rPair : m_aMap)
52 // are interfaces added to this container?
53 if (rPair.second->getLength(rGuard))
54 // yes, put the type in the array
55 aInterfaceTypes.push_back(rPair.first);
56 return aInterfaceTypes;
57 }
58 inline bool hasContainedTypes(std::unique_lock<std::mutex>& rGuard) const
59 {
60 assert(rGuard.owns_lock());
61 for (const auto& rPair : m_aMap)
62 // are interfaces added to this container?
63 if (rPair.second->getLength(rGuard))
64 return true;
65 return false;
66 }
73 inline OInterfaceContainerHelper4<listener>* getContainer(std::unique_lock<std::mutex>& rGuard,
74 const key& rKey) const
75 {
76 auto iter = find(rGuard, rKey);
77 if (iter != m_aMap.end())
78 return (*iter).second.get();
79 return nullptr;
80 }
97 inline sal_Int32 addInterface(::std::unique_lock<::std::mutex>& rGuard, const key& rKey,
98 const css::uno::Reference<listener>& rListener)
99 {
100 auto iter = find(rGuard, rKey);
101 if (iter == m_aMap.end())
102 {
104 m_aMap.emplace_back(rKey, pLC);
105 return pLC->addInterface(rGuard, rListener);
106 }
107 else
108 return (*iter).second->addInterface(rGuard, rListener);
109 }
119 inline sal_Int32 removeInterface(::std::unique_lock<::std::mutex>& rGuard, const key& rKey,
120 const css::uno::Reference<listener>& rListener)
121 {
122 // search container with id nUik
123 auto iter = find(rGuard, rKey);
124 // container found?
125 if (iter != m_aMap.end())
126 return (*iter).second->removeInterface(rGuard, rListener);
127 // no container with this id. Always return 0
128 return 0;
129 }
135 inline void disposeAndClear(std::unique_lock<std::mutex>& rGuard,
136 const css::lang::EventObject& rEvt)
137 {
138 assert(rGuard.owns_lock());
139 // create a copy, because do not fire event in a guarded section
140 InterfaceMap tempMap;
141 {
142 tempMap = std::move(m_aMap);
143 }
144 rGuard.unlock();
145 // So... we don't want to hold the normal mutex while we fire
146 // the events, but the calling convention here wants a mutex, so
147 // just create a temporary/fake one. Since the listeners we
148 // are working with are now function-local, we don't really need
149 // a mutex at all, but it's easier to create a fake one than
150 // create a bunch of special-case code for this situation.
151 std::mutex tempMutex;
152 std::unique_lock tempGuard(tempMutex);
153 for (auto& rPair : tempMap)
154 {
155 OInterfaceIteratorHelper4<listener> aIt(tempGuard, *rPair.second);
156 while (aIt.hasMoreElements())
157 {
158 try
159 {
160 aIt.next()->disposing(rEvt);
161 }
162 catch (css::uno::RuntimeException&)
163 {
164 // be robust, if e.g. a remote bridge has disposed already.
165 // there is no way to delegate the error to the caller :o(.
166 }
167 }
168 }
169 rGuard.lock(); // return with lock in same state as entry
170 }
174 inline void clear(std::unique_lock<std::mutex>& rGuard)
175 {
176 assert(rGuard.owns_lock());
177 (void)rGuard;
178 for (const auto& rPair : m_aMap)
179 rPair.second->clear();
180 }
181 typedef key keyType;
182
183private:
184 typedef ::std::vector<std::pair<key, std::unique_ptr<OInterfaceContainerHelper4<listener>>>>
187 typename InterfaceMap::const_iterator find(std::unique_lock<std::mutex>& rGuard,
188 const key& rKey) const
189 {
190 assert(rGuard.owns_lock());
191 (void)rGuard;
192 auto iter = m_aMap.begin();
193 auto end = m_aMap.end();
194 while (iter != end)
195 {
196 equalImpl equal;
197 if (equal(iter->first, rKey))
198 break;
199 ++iter;
200 }
201 return iter;
202 }
205 = delete;
206};
207} // namespace comphelper
208/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
This is the iterator of an OInterfaceContainerHelper4.
bool hasMoreElements() const
Return true, if there are more elements in the iterator.
css::uno::Reference< ListenerT > const & next()
Return the next element of the iterator.
A helper class to store interface references of different types.
::std::vector< std::pair< key, std::unique_ptr< OInterfaceContainerHelper4< listener > > > > InterfaceMap
OMultiTypeInterfaceContainerHelperVar4 & operator=(const OMultiTypeInterfaceContainerHelperVar4 &)=delete
void clear(std::unique_lock< std::mutex > &rGuard)
Remove all elements of all containers.
sal_Int32 removeInterface(::std::unique_lock<::std::mutex > &rGuard, const key &rKey, const css::uno::Reference< listener > &rListener)
Removes an element from the container with the specified key.
OMultiTypeInterfaceContainerHelperVar4(const OMultiTypeInterfaceContainerHelperVar4 &)=delete
std::vector< key > getContainedTypes(std::unique_lock< std::mutex > &rGuard) const
Return all id's under which at least one interface is added.
bool hasContainedTypes(std::unique_lock< std::mutex > &rGuard) const
sal_Int32 addInterface(::std::unique_lock<::std::mutex > &rGuard, const key &rKey, const css::uno::Reference< listener > &rListener)
Inserts an element into the container with the specified key.
void disposeAndClear(std::unique_lock< std::mutex > &rGuard, const css::lang::EventObject &rEvt)
Call disposing on all references in the container, that support XEventListener.
InterfaceMap::const_iterator find(std::unique_lock< std::mutex > &rGuard, const key &rKey) const
OInterfaceContainerHelper4< listener > * getContainer(std::unique_lock< std::mutex > &rGuard, const key &rKey) const
Return the container created under this key.
bool equal(T const &rfValA, T const &rfValB)
end
std::mutex mutex
Definition: random.cxx:41