nss: upgrade to release 3.73
[LibreOffice.git] / svl / source / notify / SfxBroadcaster.cxx
blobdbd1ab3a71912594e7faad02253c7ea8fa5ed7c9
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <svl/SfxBroadcaster.hxx>
22 #include <svl/hint.hxx>
23 #include <svl/lstner.hxx>
24 #include <tools/debug.hxx>
26 #include <algorithm>
27 #include <cassert>
28 #include <vector>
30 // broadcast immediately
32 void SfxBroadcaster::Broadcast(const SfxHint& rHint)
34 // notify all registered listeners exactly once
35 for (size_t i = 0; i < m_Listeners.size(); ++i)
37 SfxListener* const pListener = m_Listeners[i];
38 if (pListener)
39 pListener->Notify(*this, rHint);
43 // unregister all listeners
45 SfxBroadcaster::~SfxBroadcaster() COVERITY_NOEXCEPT_FALSE
47 Broadcast(SfxHint(SfxHintId::Dying));
49 // remove all still registered listeners
50 for (size_t i = 0; i < m_Listeners.size(); ++i)
52 SfxListener* const pListener = m_Listeners[i];
53 if (pListener)
54 pListener->RemoveBroadcaster_Impl(*this);
58 // copy ctor of class SfxBroadcaster
60 SfxBroadcaster::SfxBroadcaster(const SfxBroadcaster& rOther)
62 for (size_t i = 0; i < rOther.m_Listeners.size(); ++i)
64 SfxListener* const pListener = rOther.m_Listeners[i];
65 if (pListener)
66 pListener->StartListening(*this);
70 // add a new SfxListener to the list
72 void SfxBroadcaster::AddListener(SfxListener& rListener)
74 DBG_TESTSOLARMUTEX();
75 if (m_RemovedPositions.empty())
77 m_Listeners.push_back(&rListener);
79 else
81 size_t targetPosition = m_RemovedPositions.back();
82 m_RemovedPositions.pop_back();
83 assert(m_Listeners[targetPosition] == nullptr);
84 m_Listeners[targetPosition] = &rListener;
88 // forward a notification to all registered listeners
90 void SfxBroadcaster::Forward(SfxBroadcaster& rBC, const SfxHint& rHint)
92 for (size_t i = 0; i < m_Listeners.size(); ++i)
94 SfxListener* const pListener = m_Listeners[i];
95 if (pListener)
96 pListener->Notify(rBC, rHint);
100 // remove one SfxListener from the list
102 void SfxBroadcaster::RemoveListener(SfxListener& rListener)
104 DBG_TESTSOLARMUTEX();
106 // First, check the slots either side of the last removed slot, makes a significant
107 // difference when the list is large.
108 int positionOfRemovedElement = -1;
109 if (!m_RemovedPositions.empty())
111 auto i = m_RemovedPositions.back();
112 if (i < m_Listeners.size() - 2 && m_Listeners[i + 1] == &rListener)
114 positionOfRemovedElement = i + 1;
116 else if (i > 0 && m_Listeners[i - 1] == &rListener)
118 positionOfRemovedElement = i - 1;
121 // then scan the whole list if we didn't find it
122 if (positionOfRemovedElement == -1)
124 auto aIter = std::find(m_Listeners.begin(), m_Listeners.end(), &rListener);
125 positionOfRemovedElement = std::distance(m_Listeners.begin(), aIter);
127 // DO NOT erase the listener, set the pointer to 0
128 // because the current continuation may contain this->Broadcast
129 m_Listeners[positionOfRemovedElement] = nullptr;
130 m_RemovedPositions.push_back(positionOfRemovedElement);
133 bool SfxBroadcaster::HasListeners() const { return (GetListenerCount() != 0); }
135 size_t SfxBroadcaster::GetListenerCount() const
137 assert(m_Listeners.size() >= m_RemovedPositions.size());
138 return m_Listeners.size() - m_RemovedPositions.size();
141 size_t SfxBroadcaster::GetSizeOfVector() const { return m_Listeners.size(); }
143 SfxListener* SfxBroadcaster::GetListener(size_t nNo) const { return m_Listeners[nNo]; }
145 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */