OpenShot Audio Library | OpenShotAudio 0.4.0

Loading...
Searching...
No Matches
juce_ListenerList.h
1/*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - Raw Material Software Limited
6
7 JUCE is an open source library subject to commercial or open-source
8 licensing.
9
10 The code included in this file is provided under the terms of the ISC license
11 http://www.isc.org/downloads/software-support-policy/isc-license. Permission
12 To use, copy, modify, and/or distribute this software for any purpose with or
13 without fee is hereby granted provided that the above copyright notice and
14 this permission notice appear in all copies.
15
16 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
17 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
18 DISCLAIMED.
19
20 ==============================================================================
21*/
22
23 namespace juce
24{
25
26//==============================================================================
78 template <class ListenerClass,
79 class ArrayType = Array<ListenerClass*>>
80 class ListenerList
81{
82 public:
83 //==============================================================================
85 ListenerList() = default;
86
88 ~ListenerList() { clear(); }
89
90 //==============================================================================
100 void add (ListenerClass* listenerToAdd)
101 {
102 if (listenerToAdd != nullptr)
103 listeners->addIfNotAlreadyThere (listenerToAdd);
104 else
105 jassertfalse; // Listeners can't be null pointers!
106 }
107
114 void remove (ListenerClass* listenerToRemove)
115 {
116 jassert (listenerToRemove != nullptr); // Listeners can't be null pointers!
117
118 const ScopedLockType lock (listeners->getLock());
119
120 if (const auto index = listeners->removeFirstMatchingValue (listenerToRemove); index >= 0)
121 {
122 for (auto* it : *iterators)
123 {
124 --it->end;
125
126 if (index <= it->index)
127 --it->index;
128 }
129 }
130 }
131
138 ErasedScopeGuard addScoped (ListenerClass& listenerToAdd)
139 {
140 add (&listenerToAdd);
141 return ErasedScopeGuard { [this, &listenerToAdd] { remove (&listenerToAdd); } };
142 }
143
145 int size() const noexcept { return listeners->size(); }
146
148 bool isEmpty() const noexcept { return listeners->isEmpty(); }
149
155 void clear()
156 {
157 const ScopedLockType lock (listeners->getLock());
158
159 listeners->clear();
160
161 for (auto* it : *iterators)
162 it->end = 0;
163 }
164
166 bool contains (ListenerClass* listener) const noexcept { return listeners->contains (listener); }
167
177 const ArrayType& getListeners() const noexcept { return *listeners; }
178
179 //==============================================================================
181 template <typename Callback>
182 void call (Callback&& callback)
183 {
184 callCheckedExcluding (nullptr,
185 DummyBailOutChecker{},
186 std::forward<Callback> (callback));
187 }
188
192 template <typename Callback>
193 void callExcluding (ListenerClass* listenerToExclude, Callback&& callback)
194 {
195 callCheckedExcluding (listenerToExclude,
196 DummyBailOutChecker{},
197 std::forward<Callback> (callback));
198
199 }
200
206 template <typename Callback, typename BailOutCheckerType>
207 void callChecked (const BailOutCheckerType& bailOutChecker, Callback&& callback)
208 {
209 callCheckedExcluding (nullptr,
210 bailOutChecker,
211 std::forward<Callback> (callback));
212 }
213
220 template <typename Callback, typename BailOutCheckerType>
221 void callCheckedExcluding (ListenerClass* listenerToExclude,
222 const BailOutCheckerType& bailOutChecker,
223 Callback&& callback)
224 {
225 const auto localListeners = listeners;
226 const ScopedLockType lock { localListeners->getLock() };
227
228 Iterator it{};
229 it.end = localListeners->size();
230
231 iterators->push_back (&it);
232
233 const ScopeGuard scope { [i = iterators, &it]
234 {
235 i->erase (std::remove (i->begin(), i->end(), &it), i->end());
236 } };
237
238 for (; it.index < it.end; ++it.index)
239 {
240 if (bailOutChecker.shouldBailOut())
241 return;
242
243 auto* listener = localListeners->getUnchecked (it.index);
244
245 if (listener == listenerToExclude)
246 continue;
247
248 callback (*listener);
249 }
250 }
251
252 //==============================================================================
254 template <typename... MethodArgs, typename... Args>
255 void call (void (ListenerClass::*callbackFunction) (MethodArgs...), Args&&... args)
256 {
257 callCheckedExcluding (nullptr,
258 DummyBailOutChecker{},
259 callbackFunction,
260 std::forward<Args> (args)...);
261 }
262
266 template <typename... MethodArgs, typename... Args>
267 void callExcluding (ListenerClass* listenerToExclude,
268 void (ListenerClass::*callbackFunction) (MethodArgs...),
269 Args&&... args)
270 {
271 callCheckedExcluding (listenerToExclude,
272 DummyBailOutChecker{},
273 callbackFunction,
274 std::forward<Args> (args)...);
275 }
276
282 template <typename BailOutCheckerType, typename... MethodArgs, typename... Args>
283 void callChecked (const BailOutCheckerType& bailOutChecker,
284 void (ListenerClass::*callbackFunction) (MethodArgs...),
285 Args&&... args)
286 {
287 callCheckedExcluding (nullptr,
288 bailOutChecker,
289 callbackFunction,
290 std::forward<Args> (args)...);
291 }
292
299 template <typename BailOutCheckerType, typename... MethodArgs, typename... Args>
300 void callCheckedExcluding (ListenerClass* listenerToExclude,
301 const BailOutCheckerType& bailOutChecker,
302 void (ListenerClass::*callbackFunction) (MethodArgs...),
303 Args&&... args)
304 {
305 callCheckedExcluding (listenerToExclude, bailOutChecker, [&] (ListenerClass& l)
306 {
307 (l.*callbackFunction) (args...);
308 });
309 }
310
311 //==============================================================================
315 struct DummyBailOutChecker
316 {
317 constexpr bool shouldBailOut() const noexcept { return false; }
318 };
319
320 //==============================================================================
321 using ThisType = ListenerList<ListenerClass, ArrayType>;
322 using ListenerType = ListenerClass;
323
324 private:
325 //==============================================================================
326 using ScopedLockType = typename ArrayType::ScopedLockType;
327
328 //==============================================================================
329 using SharedListeners = std::shared_ptr<ArrayType>;
330 const SharedListeners listeners = std::make_shared<ArrayType>();
331
332 struct Iterator
333 {
334 int index{};
335 int end{};
336 };
337
338 using SafeIterators = std::vector<Iterator*>;
339 using SharedIterators = std::shared_ptr<SafeIterators>;
340 const SharedIterators iterators = std::make_shared<SafeIterators>();
341
342 //==============================================================================
343 JUCE_DECLARE_NON_COPYABLE (ListenerList)
344};
345
346} // namespace juce
juce::ErasedScopeGuard
Definition juce_ScopeGuard.h:77
juce::ListenerList
Definition juce_ListenerList.h:81
juce::ListenerList::callChecked
void callChecked(const BailOutCheckerType &bailOutChecker, Callback &&callback)
Definition juce_ListenerList.h:207
juce::ListenerList::isEmpty
bool isEmpty() const noexcept
Definition juce_ListenerList.h:148
juce::ListenerList::callCheckedExcluding
void callCheckedExcluding(ListenerClass *listenerToExclude, const BailOutCheckerType &bailOutChecker, Callback &&callback)
Definition juce_ListenerList.h:221
juce::ListenerList::callChecked
void callChecked(const BailOutCheckerType &bailOutChecker, void(ListenerClass::*callbackFunction)(MethodArgs...), Args &&... args)
Definition juce_ListenerList.h:283
juce::ListenerList::call
void call(Callback &&callback)
Definition juce_ListenerList.h:182
juce::ListenerList::callExcluding
void callExcluding(ListenerClass *listenerToExclude, Callback &&callback)
Definition juce_ListenerList.h:193
juce::ListenerList::callCheckedExcluding
void callCheckedExcluding(ListenerClass *listenerToExclude, const BailOutCheckerType &bailOutChecker, void(ListenerClass::*callbackFunction)(MethodArgs...), Args &&... args)
Definition juce_ListenerList.h:300
juce::ListenerList::call
void call(void(ListenerClass::*callbackFunction)(MethodArgs...), Args &&... args)
Definition juce_ListenerList.h:255
juce::ListenerList::add
void add(ListenerClass *listenerToAdd)
Definition juce_ListenerList.h:100
juce::ListenerList::addScoped
ErasedScopeGuard addScoped(ListenerClass &listenerToAdd)
Definition juce_ListenerList.h:138
juce::ListenerList::remove
void remove(ListenerClass *listenerToRemove)
Definition juce_ListenerList.h:114
juce::ListenerList::contains
bool contains(ListenerClass *listener) const noexcept
Definition juce_ListenerList.h:166
juce::ListenerList::size
int size() const noexcept
Definition juce_ListenerList.h:145
juce::ListenerList::ListenerList
ListenerList()=default
juce::ListenerList::callExcluding
void callExcluding(ListenerClass *listenerToExclude, void(ListenerClass::*callbackFunction)(MethodArgs...), Args &&... args)
Definition juce_ListenerList.h:267
juce::ListenerList::getListeners
const ArrayType & getListeners() const noexcept
Definition juce_ListenerList.h:177
juce::ListenerList::clear
void clear()
Definition juce_ListenerList.h:155
juce::ListenerList::~ListenerList
~ListenerList()
Definition juce_ListenerList.h:88
juce::ListenerList::DummyBailOutChecker
Definition juce_ListenerList.h:316
juce::ScopeGuard
Definition juce_ScopeGuard.h:52