78template <
class ListenerClass,
79 class ArrayType = Array<ListenerClass*>>
100 void add (ListenerClass* listenerToAdd)
102 if (listenerToAdd !=
nullptr)
103 listeners->addIfNotAlreadyThere (listenerToAdd);
114 void remove (ListenerClass* listenerToRemove)
116 jassert (listenerToRemove !=
nullptr);
118 const ScopedLockType lock (listeners->getLock());
120 if (
const auto index = listeners->removeFirstMatchingValue (listenerToRemove); index >= 0)
122 for (
auto* it : *iterators)
126 if (index <= it->index)
140 add (&listenerToAdd);
145 int size() const noexcept {
return listeners->size(); }
148 bool isEmpty() const noexcept {
return listeners->isEmpty(); }
157 const ScopedLockType lock (listeners->getLock());
161 for (
auto* it : *iterators)
166 bool contains (ListenerClass* listener)
const noexcept {
return listeners->contains (listener); }
181 template <
typename Callback>
182 void call (Callback&& callback)
186 std::forward<Callback> (callback));
192 template <
typename Callback>
197 std::forward<Callback> (callback));
206 template <
typename Callback,
typename BailOutCheckerType>
207 void callChecked (
const BailOutCheckerType& bailOutChecker, Callback&& callback)
211 std::forward<Callback> (callback));
220 template <
typename Callback,
typename BailOutCheckerType>
222 const BailOutCheckerType& bailOutChecker,
225 const auto localListeners = listeners;
226 const ScopedLockType lock { localListeners->getLock() };
229 it.end = localListeners->size();
231 iterators->push_back (&it);
235 i->erase (std::remove (i->begin(), i->end(), &it), i->end());
238 for (; it.index < it.end; ++it.index)
240 if (bailOutChecker.shouldBailOut())
243 auto* listener = localListeners->getUnchecked (it.index);
245 if (listener == listenerToExclude)
248 callback (*listener);
254 template <
typename... MethodArgs,
typename... Args>
255 void call (
void (ListenerClass::*callbackFunction) (MethodArgs...), Args&&... args)
260 std::forward<Args> (args)...);
266 template <
typename... MethodArgs,
typename... Args>
268 void (ListenerClass::*callbackFunction) (MethodArgs...),
274 std::forward<Args> (args)...);
282 template <
typename BailOutCheckerType,
typename... MethodArgs,
typename... Args>
284 void (ListenerClass::*callbackFunction) (MethodArgs...),
290 std::forward<Args> (args)...);
299 template <
typename BailOutCheckerType,
typename... MethodArgs,
typename... Args>
301 const BailOutCheckerType& bailOutChecker,
302 void (ListenerClass::*callbackFunction) (MethodArgs...),
307 (l.*callbackFunction) (args...);
317 constexpr bool shouldBailOut()
const noexcept {
return false; }
322 using ListenerType = ListenerClass;
326 using ScopedLockType =
typename ArrayType::ScopedLockType;
329 using SharedListeners = std::shared_ptr<ArrayType>;
330 const SharedListeners listeners = std::make_shared<ArrayType>();
338 using SafeIterators = std::vector<Iterator*>;
339 using SharedIterators = std::shared_ptr<SafeIterators>;
340 const SharedIterators iterators = std::make_shared<SafeIterators>();
void callChecked(const BailOutCheckerType &bailOutChecker, Callback &&callback)
bool isEmpty() const noexcept
void callCheckedExcluding(ListenerClass *listenerToExclude, const BailOutCheckerType &bailOutChecker, Callback &&callback)
void callChecked(const BailOutCheckerType &bailOutChecker, void(ListenerClass::*callbackFunction)(MethodArgs...), Args &&... args)
void call(Callback &&callback)
void callExcluding(ListenerClass *listenerToExclude, Callback &&callback)
void callCheckedExcluding(ListenerClass *listenerToExclude, const BailOutCheckerType &bailOutChecker, void(ListenerClass::*callbackFunction)(MethodArgs...), Args &&... args)
void call(void(ListenerClass::*callbackFunction)(MethodArgs...), Args &&... args)
void add(ListenerClass *listenerToAdd)
ErasedScopeGuard addScoped(ListenerClass &listenerToAdd)
void remove(ListenerClass *listenerToRemove)
bool contains(ListenerClass *listener) const noexcept
int size() const noexcept
void callExcluding(ListenerClass *listenerToExclude, void(ListenerClass::*callbackFunction)(MethodArgs...), Args &&... args)
const ArrayType & getListeners() const noexcept