LMMS
Loading...
Searching...
No Matches
juce_ListenerList.h
Go to the documentation of this file.
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
23namespace juce
24{
25
26//==============================================================================
67template <class ListenerClass,
68 class ArrayType = Array<ListenerClass*>>
70{
71public:
72 //==============================================================================
74 ListenerList() = default;
75
78 {
80 {
81 iter.invalidate();
82 });
83 }
84
85 //==============================================================================
91 void add (ListenerClass* listenerToAdd)
92 {
93 if (listenerToAdd != nullptr)
94 listeners.addIfNotAlreadyThere (listenerToAdd);
95 else
96 jassertfalse; // Listeners can't be null pointers!
97 }
98
102 void remove (ListenerClass* listenerToRemove)
103 {
104 jassert (listenerToRemove != nullptr); // Listeners can't be null pointers!
105
106 typename ArrayType::ScopedLockType lock (listeners.getLock());
107
108 const auto index = listeners.removeFirstMatchingValue (listenerToRemove);
109
111 {
112 if (0 <= index && index < iter.get().index)
113 --iter.get().index;
114 });
115 }
116
118 int size() const noexcept { return listeners.size(); }
119
121 bool isEmpty() const noexcept { return listeners.isEmpty(); }
122
124 void clear() { listeners.clear(); }
125
127 bool contains (ListenerClass* listener) const noexcept { return listeners.contains (listener); }
128
130 const ArrayType& getListeners() const noexcept { return listeners; }
131
132 //==============================================================================
134 template <typename Callback>
135 void call (Callback&& callback)
136 {
137 typename ArrayType::ScopedLockType lock (listeners.getLock());
138
139 for (WrappedIterator iter (*this, activeIterators); iter.get().next();)
140 callback (*iter.get().getListener());
141 }
142
146 template <typename Callback>
147 void callExcluding (ListenerClass* listenerToExclude, Callback&& callback)
148 {
149 typename ArrayType::ScopedLockType lock (listeners.getLock());
150
151 for (WrappedIterator iter (*this, activeIterators); iter.get().next();)
152 {
153 auto* l = iter.get().getListener();
154
155 if (l != listenerToExclude)
156 callback (*l);
157 }
158 }
159
163 template <typename Callback, typename BailOutCheckerType>
164 void callChecked (const BailOutCheckerType& bailOutChecker, Callback&& callback)
165 {
166 typename ArrayType::ScopedLockType lock (listeners.getLock());
167
168 for (WrappedIterator iter (*this, activeIterators); iter.get().next (bailOutChecker);)
169 {
170 callback (*iter.get().getListener());
171 }
172 }
173
178 template <typename Callback, typename BailOutCheckerType>
179 void callCheckedExcluding (ListenerClass* listenerToExclude,
180 const BailOutCheckerType& bailOutChecker,
181 Callback&& callback)
182 {
183 typename ArrayType::ScopedLockType lock (listeners.getLock());
184
185 for (WrappedIterator iter (*this, activeIterators); iter.get().next (bailOutChecker);)
186 {
187 auto* l = iter.get().getListener();
188
189 if (l != listenerToExclude)
190 callback (*l);
191 }
192 }
193
194 //==============================================================================
199 {
200 bool shouldBailOut() const noexcept { return false; }
201 };
202
204 using ListenerType = ListenerClass;
205
206 //==============================================================================
208 struct Iterator
209 {
210 explicit Iterator (const ListenerList& listToIterate) noexcept
211 : list (listToIterate), index (listToIterate.size())
212 {}
213
214 //==============================================================================
216 {
217 if (index <= 0)
218 return false;
219
220 auto listSize = list.size();
221
222 if (--index < listSize)
223 return true;
224
225 index = listSize - 1;
226 return index >= 0;
227 }
228
229 template <class BailOutCheckerType>
230 bool next (const BailOutCheckerType& bailOutChecker) noexcept
231 {
232 return (! bailOutChecker.shouldBailOut()) && next();
233 }
234
235 ListenerClass* getListener() const noexcept
236 {
237 return list.getListeners().getUnchecked (index);
238 }
239
240 private:
242 int index;
243
245
247 };
248
249 //==============================================================================
250 #ifndef DOXYGEN
251 void call (void (ListenerClass::*callbackFunction) ())
252 {
253 call ([=] (ListenerClass& l) { (l.*callbackFunction)(); });
254 }
255
256 void callExcluding (ListenerClass* listenerToExclude, void (ListenerClass::*callbackFunction) ())
257 {
258 callExcluding (listenerToExclude, [=] (ListenerClass& l) { (l.*callbackFunction)(); });
259 }
260
261 template <class BailOutCheckerType>
262 void callChecked (const BailOutCheckerType& bailOutChecker, void (ListenerClass::*callbackFunction) ())
263 {
264 callChecked (bailOutChecker, [=] (ListenerClass& l) { (l.*callbackFunction)(); });
265 }
266
267 template <class BailOutCheckerType>
268 void callCheckedExcluding (ListenerClass* listenerToExclude,
269 const BailOutCheckerType& bailOutChecker,
270 void (ListenerClass::*callbackFunction) ())
271 {
272 callCheckedExcluding (listenerToExclude, bailOutChecker, [=] (ListenerClass& l) { (l.*callbackFunction)(); });
273 }
274
275 template <typename... MethodArgs, typename... Args>
276 void call (void (ListenerClass::*callbackFunction) (MethodArgs...), Args&&... args)
277 {
278 typename ArrayType::ScopedLockType lock (listeners.getLock());
279
280 for (Iterator iter (*this); iter.next();)
281 (iter.getListener()->*callbackFunction) (static_cast<typename TypeHelpers::ParameterType<Args>::type> (args)...);
282 }
283
284 template <typename... MethodArgs, typename... Args>
285 void callExcluding (ListenerClass* listenerToExclude,
286 void (ListenerClass::*callbackFunction) (MethodArgs...),
287 Args&&... args)
288 {
289 typename ArrayType::ScopedLockType lock (listeners.getLock());
290
291 for (Iterator iter (*this); iter.next();)
292 if (iter.getListener() != listenerToExclude)
293 (iter.getListener()->*callbackFunction) (static_cast<typename TypeHelpers::ParameterType<Args>::type> (args)...);
294 }
295
296 template <typename BailOutCheckerType, typename... MethodArgs, typename... Args>
297 void callChecked (const BailOutCheckerType& bailOutChecker,
298 void (ListenerClass::*callbackFunction) (MethodArgs...),
299 Args&&... args)
300 {
301 typename ArrayType::ScopedLockType lock (listeners.getLock());
302
303 for (Iterator iter (*this); iter.next (bailOutChecker);)
304 (iter.getListener()->*callbackFunction) (static_cast<typename TypeHelpers::ParameterType<Args>::type> (args)...);
305 }
306
307 template <typename BailOutCheckerType, typename... MethodArgs, typename... Args>
308 void callCheckedExcluding (ListenerClass* listenerToExclude,
309 const BailOutCheckerType& bailOutChecker,
310 void (ListenerClass::*callbackFunction) (MethodArgs...),
311 Args&&... args)
312 {
313 typename ArrayType::ScopedLockType lock (listeners.getLock());
314
315 for (Iterator iter (*this); iter.next (bailOutChecker);)
316 if (iter.getListener() != listenerToExclude)
317 (iter.getListener()->*callbackFunction) (static_cast<typename TypeHelpers::ParameterType<Args>::type> (args)...);
318 }
319 #endif
320
321private:
323 {
324 public:
325 WrappedIterator (const ListenerList& listToIterate, WrappedIterator*& listHeadIn)
326 : it (listToIterate), listHead (listHeadIn), next (listHead)
327 {
328 listHead = this;
329 }
330
332 {
333 if (valid)
334 listHead = next;
335 }
336
337 auto& get() noexcept { return it; }
338
339 template <typename Callback>
340 static void forEach (WrappedIterator* wrapped, Callback&& cb)
341 {
342 for (auto* p = wrapped; p != nullptr; p = p->next)
343 cb (*p);
344 }
345
346 void invalidate() noexcept { valid = false; }
347
348 private:
352 bool valid = true;
353 };
354
355 //==============================================================================
356 ArrayType listeners;
357 WrappedIterator* activeIterators = nullptr;
358
360};
361
362} // namespace juce
#define noexcept
Definition DistrhoDefines.h:72
WrappedIterator(const ListenerList &listToIterate, WrappedIterator *&listHeadIn)
Definition juce_ListenerList.h:325
~WrappedIterator()
Definition juce_ListenerList.h:331
void invalidate() noexcept
Definition juce_ListenerList.h:346
WrappedIterator *& listHead
Definition juce_ListenerList.h:350
WrappedIterator * next
Definition juce_ListenerList.h:351
Iterator it
Definition juce_ListenerList.h:349
bool valid
Definition juce_ListenerList.h:352
auto & get() noexcept
Definition juce_ListenerList.h:337
static void forEach(WrappedIterator *wrapped, Callback &&cb)
Definition juce_ListenerList.h:340
void callChecked(const BailOutCheckerType &bailOutChecker, Callback &&callback)
Definition juce_ListenerList.h:164
void callCheckedExcluding(ListenerClass *listenerToExclude, const BailOutCheckerType &bailOutChecker, void(ListenerClass::*callbackFunction)())
Definition juce_ListenerList.h:268
ArrayType listeners
Definition juce_ListenerList.h:356
void callChecked(const BailOutCheckerType &bailOutChecker, void(ListenerClass::*callbackFunction)())
Definition juce_ListenerList.h:262
bool isEmpty() const noexcept
Definition juce_ListenerList.h:121
void callCheckedExcluding(ListenerClass *listenerToExclude, const BailOutCheckerType &bailOutChecker, Callback &&callback)
Definition juce_ListenerList.h:179
void callChecked(const BailOutCheckerType &bailOutChecker, void(ListenerClass::*callbackFunction)(MethodArgs...), Args &&... args)
Definition juce_ListenerList.h:297
void call(Callback &&callback)
Definition juce_ListenerList.h:135
void callExcluding(ListenerClass *listenerToExclude, Callback &&callback)
Definition juce_ListenerList.h:147
void callCheckedExcluding(ListenerClass *listenerToExclude, const BailOutCheckerType &bailOutChecker, void(ListenerClass::*callbackFunction)(MethodArgs...), Args &&... args)
Definition juce_ListenerList.h:308
void call(void(ListenerClass::*callbackFunction)(MethodArgs...), Args &&... args)
Definition juce_ListenerList.h:276
void call(void(ListenerClass::*callbackFunction)())
Definition juce_ListenerList.h:251
void add(ListenerClass *listenerToAdd)
Definition juce_ListenerList.h:91
void remove(ListenerClass *listenerToRemove)
Definition juce_ListenerList.h:102
void callExcluding(ListenerClass *listenerToExclude, void(ListenerClass::*callbackFunction)())
Definition juce_ListenerList.h:256
bool contains(ListenerClass *listener) const noexcept
Definition juce_ListenerList.h:127
int size() const noexcept
Definition juce_ListenerList.h:118
ListenerList()=default
void callExcluding(ListenerClass *listenerToExclude, void(ListenerClass::*callbackFunction)(MethodArgs...), Args &&... args)
Definition juce_ListenerList.h:285
WrappedIterator * activeIterators
Definition juce_ListenerList.h:357
ListenerClass ListenerType
Definition juce_ListenerList.h:204
const ArrayType & getListeners() const noexcept
Definition juce_ListenerList.h:130
void clear()
Definition juce_ListenerList.h:124
~ListenerList()
Definition juce_ListenerList.h:77
ListenerList< ListenerClass, ArrayType > ThisType
Definition juce_ListenerList.h:203
int * l
Definition inflate.c:1579
#define jassert(expression)
#define JUCE_DECLARE_NON_COPYABLE(className)
#define jassertfalse
Definition carla_juce.cpp:31
Definition juce_ListenerList.h:199
bool shouldBailOut() const noexcept
Definition juce_ListenerList.h:200
Definition juce_ListenerList.h:209
bool next() noexcept
Definition juce_ListenerList.h:215
int index
Definition juce_ListenerList.h:242
Iterator(const ListenerList &listToIterate) noexcept
Definition juce_ListenerList.h:210
ListenerClass * getListener() const noexcept
Definition juce_ListenerList.h:235
const ListenerList & list
Definition juce_ListenerList.h:241
friend ListenerList
Definition juce_ListenerList.h:244
bool next(const BailOutCheckerType &bailOutChecker) noexcept
Definition juce_ListenerList.h:230
const Type & type
Definition juce_MathsFunctions.h:632
RECT const char void(* callback)(const char *droppath))) SWELL_API_DEFINE(BOOL
Definition swell-functions.h:1004
uch * p
Definition crypt.c:594
#define const
Definition zconf.h:137