1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-14 00:14:18 +00:00

Added Animated App template and examples

This commit is contained in:
Felix Faire 2014-10-29 15:55:23 +00:00
parent fefcf7aca6
commit ff6520a89a
1141 changed files with 438491 additions and 94 deletions

View file

@ -0,0 +1,91 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2013 - Raw Material Software Ltd.
Permission is granted to use this software under the terms of either:
a) the GPL v2 (or any later version)
b) the Affero GPL v3
Details of these licenses can be found at: www.gnu.org/licenses
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
------------------------------------------------------------------------------
To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.juce.com for more information.
==============================================================================
*/
class ActionBroadcaster::ActionMessage : public MessageManager::MessageBase
{
public:
ActionMessage (const ActionBroadcaster* ab,
const String& messageText, ActionListener* l) noexcept
: broadcaster (const_cast<ActionBroadcaster*> (ab)),
message (messageText),
listener (l)
{}
void messageCallback() override
{
if (const ActionBroadcaster* const b = broadcaster)
if (b->actionListeners.contains (listener))
listener->actionListenerCallback (message);
}
private:
WeakReference<ActionBroadcaster> broadcaster;
const String message;
ActionListener* const listener;
JUCE_DECLARE_NON_COPYABLE (ActionMessage)
};
//==============================================================================
ActionBroadcaster::ActionBroadcaster()
{
// are you trying to create this object before or after juce has been intialised??
jassert (MessageManager::getInstanceWithoutCreating() != nullptr);
}
ActionBroadcaster::~ActionBroadcaster()
{
// all event-based objects must be deleted BEFORE juce is shut down!
jassert (MessageManager::getInstanceWithoutCreating() != nullptr);
masterReference.clear();
}
void ActionBroadcaster::addActionListener (ActionListener* const listener)
{
const ScopedLock sl (actionListenerLock);
if (listener != nullptr)
actionListeners.add (listener);
}
void ActionBroadcaster::removeActionListener (ActionListener* const listener)
{
const ScopedLock sl (actionListenerLock);
actionListeners.removeValue (listener);
}
void ActionBroadcaster::removeAllActionListeners()
{
const ScopedLock sl (actionListenerLock);
actionListeners.clear();
}
void ActionBroadcaster::sendActionMessage (const String& message) const
{
const ScopedLock sl (actionListenerLock);
for (int i = actionListeners.size(); --i >= 0;)
(new ActionMessage (this, message, actionListeners.getUnchecked(i)))->post();
}

View file

@ -0,0 +1,83 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2013 - Raw Material Software Ltd.
Permission is granted to use this software under the terms of either:
a) the GPL v2 (or any later version)
b) the Affero GPL v3
Details of these licenses can be found at: www.gnu.org/licenses
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
------------------------------------------------------------------------------
To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.juce.com for more information.
==============================================================================
*/
#ifndef JUCE_ACTIONBROADCASTER_H_INCLUDED
#define JUCE_ACTIONBROADCASTER_H_INCLUDED
//==============================================================================
/** Manages a list of ActionListeners, and can send them messages.
To quickly add methods to your class that can add/remove action
listeners and broadcast to them, you can derive from this.
@see ActionListener, ChangeListener
*/
class JUCE_API ActionBroadcaster
{
public:
//==============================================================================
/** Creates an ActionBroadcaster. */
ActionBroadcaster();
/** Destructor. */
virtual ~ActionBroadcaster();
//==============================================================================
/** Adds a listener to the list.
Trying to add a listener that's already on the list will have no effect.
*/
void addActionListener (ActionListener* listener);
/** Removes a listener from the list.
If the listener isn't on the list, this won't have any effect.
*/
void removeActionListener (ActionListener* listener);
/** Removes all listeners from the list. */
void removeAllActionListeners();
//==============================================================================
/** Broadcasts a message to all the registered listeners.
@see ActionListener::actionListenerCallback
*/
void sendActionMessage (const String& message) const;
private:
//==============================================================================
friend class WeakReference<ActionBroadcaster>;
WeakReference<ActionBroadcaster>::Master masterReference;
class ActionMessage;
friend class ActionMessage;
SortedSet<ActionListener*> actionListeners;
CriticalSection actionListenerLock;
JUCE_DECLARE_NON_COPYABLE (ActionBroadcaster)
};
#endif // JUCE_ACTIONBROADCASTER_H_INCLUDED

View file

@ -0,0 +1,50 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2013 - Raw Material Software Ltd.
Permission is granted to use this software under the terms of either:
a) the GPL v2 (or any later version)
b) the Affero GPL v3
Details of these licenses can be found at: www.gnu.org/licenses
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
------------------------------------------------------------------------------
To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.juce.com for more information.
==============================================================================
*/
#ifndef JUCE_ACTIONLISTENER_H_INCLUDED
#define JUCE_ACTIONLISTENER_H_INCLUDED
//==============================================================================
/**
Interface class for delivery of events that are sent by an ActionBroadcaster.
@see ActionBroadcaster, ChangeListener
*/
class JUCE_API ActionListener
{
public:
/** Destructor. */
virtual ~ActionListener() {}
/** Overridden by your subclass to receive the callback.
@param message the string that was specified when the event was triggered
by a call to ActionBroadcaster::sendActionMessage()
*/
virtual void actionListenerCallback (const String& message) = 0;
};
#endif // JUCE_ACTIONLISTENER_H_INCLUDED

View file

@ -0,0 +1,86 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2013 - Raw Material Software Ltd.
Permission is granted to use this software under the terms of either:
a) the GPL v2 (or any later version)
b) the Affero GPL v3
Details of these licenses can be found at: www.gnu.org/licenses
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
------------------------------------------------------------------------------
To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.juce.com for more information.
==============================================================================
*/
class AsyncUpdater::AsyncUpdaterMessage : public CallbackMessage
{
public:
AsyncUpdaterMessage (AsyncUpdater& au) : owner (au) {}
void messageCallback() override
{
if (shouldDeliver.compareAndSetBool (0, 1))
owner.handleAsyncUpdate();
}
Atomic<int> shouldDeliver;
private:
AsyncUpdater& owner;
JUCE_DECLARE_NON_COPYABLE (AsyncUpdaterMessage)
};
//==============================================================================
AsyncUpdater::AsyncUpdater()
{
activeMessage = new AsyncUpdaterMessage (*this);
}
AsyncUpdater::~AsyncUpdater()
{
// You're deleting this object with a background thread while there's an update
// pending on the main event thread - that's pretty dodgy threading, as the callback could
// happen after this destructor has finished. You should either use a MessageManagerLock while
// deleting this object, or find some other way to avoid such a race condition.
jassert ((! isUpdatePending()) || MessageManager::getInstance()->currentThreadHasLockedMessageManager());
activeMessage->shouldDeliver.set (0);
}
void AsyncUpdater::triggerAsyncUpdate()
{
if (activeMessage->shouldDeliver.compareAndSetBool (1, 0))
if (! activeMessage->post())
cancelPendingUpdate(); // if the message queue fails, this avoids getting
// trapped waiting for the message to arrive
}
void AsyncUpdater::cancelPendingUpdate() noexcept
{
activeMessage->shouldDeliver.set (0);
}
void AsyncUpdater::handleUpdateNowIfNeeded()
{
// This can only be called by the event thread.
jassert (MessageManager::getInstance()->currentThreadHasLockedMessageManager());
if (activeMessage->shouldDeliver.exchange (0) != 0)
handleAsyncUpdate();
}
bool AsyncUpdater::isUpdatePending() const noexcept
{
return activeMessage->shouldDeliver.value != 0;
}

View file

@ -0,0 +1,109 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2013 - Raw Material Software Ltd.
Permission is granted to use this software under the terms of either:
a) the GPL v2 (or any later version)
b) the Affero GPL v3
Details of these licenses can be found at: www.gnu.org/licenses
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
------------------------------------------------------------------------------
To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.juce.com for more information.
==============================================================================
*/
#ifndef JUCE_ASYNCUPDATER_H_INCLUDED
#define JUCE_ASYNCUPDATER_H_INCLUDED
//==============================================================================
/**
Has a callback method that is triggered asynchronously.
This object allows an asynchronous callback function to be triggered, for
tasks such as coalescing multiple updates into a single callback later on.
Basically, one or more calls to the triggerAsyncUpdate() will result in the
message thread calling handleAsyncUpdate() as soon as it can.
*/
class JUCE_API AsyncUpdater
{
public:
//==============================================================================
/** Creates an AsyncUpdater object. */
AsyncUpdater();
/** Destructor.
If there are any pending callbacks when the object is deleted, these are lost.
*/
virtual ~AsyncUpdater();
//==============================================================================
/** Causes the callback to be triggered at a later time.
This method returns immediately, having made sure that a callback
to the handleAsyncUpdate() method will occur as soon as possible.
If an update callback is already pending but hasn't happened yet, calls
to this method will be ignored.
It's thread-safe to call this method from any number of threads without
needing to worry about locking.
*/
void triggerAsyncUpdate();
/** This will stop any pending updates from happening.
If called after triggerAsyncUpdate() and before the handleAsyncUpdate()
callback happens, this will cancel the handleAsyncUpdate() callback.
Note that this method simply cancels the next callback - if a callback is already
in progress on a different thread, this won't block until the callback finishes, so
there's no guarantee that the callback isn't still running when the method returns.
*/
void cancelPendingUpdate() noexcept;
/** If an update has been triggered and is pending, this will invoke it
synchronously.
Use this as a kind of "flush" operation - if an update is pending, the
handleAsyncUpdate() method will be called immediately; if no update is
pending, then nothing will be done.
Because this may invoke the callback, this method must only be called on
the main event thread.
*/
void handleUpdateNowIfNeeded();
/** Returns true if there's an update callback in the pipeline. */
bool isUpdatePending() const noexcept;
//==============================================================================
/** Called back to do whatever your class needs to do.
This method is called by the message thread at the next convenient time
after the triggerAsyncUpdate() method has been called.
*/
virtual void handleAsyncUpdate() = 0;
private:
//==============================================================================
class AsyncUpdaterMessage;
friend class ReferenceCountedObjectPtr<AsyncUpdaterMessage>;
ReferenceCountedObjectPtr<AsyncUpdaterMessage> activeMessage;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AsyncUpdater)
};
#endif // JUCE_ASYNCUPDATER_H_INCLUDED

View file

@ -0,0 +1,96 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2013 - Raw Material Software Ltd.
Permission is granted to use this software under the terms of either:
a) the GPL v2 (or any later version)
b) the Affero GPL v3
Details of these licenses can be found at: www.gnu.org/licenses
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
------------------------------------------------------------------------------
To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.juce.com for more information.
==============================================================================
*/
ChangeBroadcaster::ChangeBroadcaster() noexcept
{
callback.owner = this;
}
ChangeBroadcaster::~ChangeBroadcaster()
{
}
void ChangeBroadcaster::addChangeListener (ChangeListener* const listener)
{
// Listeners can only be safely added when the event thread is locked
// You can use a MessageManagerLock if you need to call this from another thread.
jassert (MessageManager::getInstance()->currentThreadHasLockedMessageManager());
changeListeners.add (listener);
}
void ChangeBroadcaster::removeChangeListener (ChangeListener* const listener)
{
// Listeners can only be safely added when the event thread is locked
// You can use a MessageManagerLock if you need to call this from another thread.
jassert (MessageManager::getInstance()->currentThreadHasLockedMessageManager());
changeListeners.remove (listener);
}
void ChangeBroadcaster::removeAllChangeListeners()
{
// Listeners can only be safely added when the event thread is locked
// You can use a MessageManagerLock if you need to call this from another thread.
jassert (MessageManager::getInstance()->currentThreadHasLockedMessageManager());
changeListeners.clear();
}
void ChangeBroadcaster::sendChangeMessage()
{
if (changeListeners.size() > 0)
callback.triggerAsyncUpdate();
}
void ChangeBroadcaster::sendSynchronousChangeMessage()
{
// This can only be called by the event thread.
jassert (MessageManager::getInstance()->isThisTheMessageThread());
callback.cancelPendingUpdate();
callListeners();
}
void ChangeBroadcaster::dispatchPendingMessages()
{
callback.handleUpdateNowIfNeeded();
}
void ChangeBroadcaster::callListeners()
{
changeListeners.call (&ChangeListener::changeListenerCallback, this);
}
//==============================================================================
ChangeBroadcaster::ChangeBroadcasterCallback::ChangeBroadcasterCallback()
: owner (nullptr)
{
}
void ChangeBroadcaster::ChangeBroadcasterCallback::handleAsyncUpdate()
{
jassert (owner != nullptr);
owner->callListeners();
}

View file

@ -0,0 +1,105 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2013 - Raw Material Software Ltd.
Permission is granted to use this software under the terms of either:
a) the GPL v2 (or any later version)
b) the Affero GPL v3
Details of these licenses can be found at: www.gnu.org/licenses
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
------------------------------------------------------------------------------
To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.juce.com for more information.
==============================================================================
*/
#ifndef JUCE_CHANGEBROADCASTER_H_INCLUDED
#define JUCE_CHANGEBROADCASTER_H_INCLUDED
//==============================================================================
/**
Holds a list of ChangeListeners, and sends messages to them when instructed.
@see ChangeListener
*/
class JUCE_API ChangeBroadcaster
{
public:
//==============================================================================
/** Creates an ChangeBroadcaster. */
ChangeBroadcaster() noexcept;
/** Destructor. */
virtual ~ChangeBroadcaster();
//==============================================================================
/** Registers a listener to receive change callbacks from this broadcaster.
Trying to add a listener that's already on the list will have no effect.
*/
void addChangeListener (ChangeListener* listener);
/** Unregisters a listener from the list.
If the listener isn't on the list, this won't have any effect.
*/
void removeChangeListener (ChangeListener* listener);
/** Removes all listeners from the list. */
void removeAllChangeListeners();
//==============================================================================
/** Causes an asynchronous change message to be sent to all the registered listeners.
The message will be delivered asynchronously by the main message thread, so this
method will return immediately. To call the listeners synchronously use
sendSynchronousChangeMessage().
*/
void sendChangeMessage();
/** Sends a synchronous change message to all the registered listeners.
This will immediately call all the listeners that are registered. For thread-safety
reasons, you must only call this method on the main message thread.
@see dispatchPendingMessages
*/
void sendSynchronousChangeMessage();
/** If a change message has been sent but not yet dispatched, this will call
sendSynchronousChangeMessage() to make the callback immediately.
For thread-safety reasons, you must only call this method on the main message thread.
*/
void dispatchPendingMessages();
private:
//==============================================================================
class ChangeBroadcasterCallback : public AsyncUpdater
{
public:
ChangeBroadcasterCallback();
void handleAsyncUpdate() override;
ChangeBroadcaster* owner;
};
friend class ChangeBroadcasterCallback;
ChangeBroadcasterCallback callback;
ListenerList <ChangeListener> changeListeners;
void callListeners();
JUCE_DECLARE_NON_COPYABLE (ChangeBroadcaster)
};
#endif // JUCE_CHANGEBROADCASTER_H_INCLUDED

View file

@ -0,0 +1,64 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2013 - Raw Material Software Ltd.
Permission is granted to use this software under the terms of either:
a) the GPL v2 (or any later version)
b) the Affero GPL v3
Details of these licenses can be found at: www.gnu.org/licenses
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
------------------------------------------------------------------------------
To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.juce.com for more information.
==============================================================================
*/
#ifndef JUCE_CHANGELISTENER_H_INCLUDED
#define JUCE_CHANGELISTENER_H_INCLUDED
class ChangeBroadcaster;
//==============================================================================
/**
Receives change event callbacks that are sent out by a ChangeBroadcaster.
A ChangeBroadcaster keeps a set of listeners to which it broadcasts a message when
the ChangeBroadcaster::sendChangeMessage() method is called. A subclass of
ChangeListener is used to receive these callbacks.
Note that the major difference between an ActionListener and a ChangeListener
is that for a ChangeListener, multiple changes will be coalesced into fewer
callbacks, but ActionListeners perform one callback for every event posted.
@see ChangeBroadcaster, ActionListener
*/
class JUCE_API ChangeListener
{
public:
/** Destructor. */
virtual ~ChangeListener() {}
/** Your subclass should implement this method to receive the callback.
@param source the ChangeBroadcaster that triggered the callback.
*/
virtual void changeListenerCallback (ChangeBroadcaster* source) = 0;
//==============================================================================
#if JUCE_CATCH_DEPRECATED_CODE_MISUSE
// This method's signature has changed to take a ChangeBroadcaster parameter - please update your code!
private: virtual int changeListenerCallback (void*) { return 0; }
#endif
};
#endif // JUCE_CHANGELISTENER_H_INCLUDED

View file

@ -0,0 +1,359 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2013 - Raw Material Software Ltd.
Permission is granted to use this software under the terms of either:
a) the GPL v2 (or any later version)
b) the Affero GPL v3
Details of these licenses can be found at: www.gnu.org/licenses
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
------------------------------------------------------------------------------
To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.juce.com for more information.
==============================================================================
*/
#ifndef JUCE_LISTENERLIST_H_INCLUDED
#define JUCE_LISTENERLIST_H_INCLUDED
//==============================================================================
/**
Holds a set of objects and can invoke a member function callback on each object
in the set with a single call.
Use a ListenerList to manage a set of objects which need a callback, and you
can invoke a member function by simply calling call() or callChecked().
E.g.
@code
class MyListenerType
{
public:
void myCallbackMethod (int foo, bool bar);
};
ListenerList <MyListenerType> listeners;
listeners.add (someCallbackObjects...);
// This will invoke myCallbackMethod (1234, true) on each of the objects
// in the list...
listeners.call (&MyListenerType::myCallbackMethod, 1234, true);
@endcode
If you add or remove listeners from the list during one of the callbacks - i.e. while
it's in the middle of iterating the listeners, then it's guaranteed that no listeners
will be mistakenly called after they've been removed, but it may mean that some of the
listeners could be called more than once, or not at all, depending on the list's order.
Sometimes, there's a chance that invoking one of the callbacks might result in the
list itself being deleted while it's still iterating - to survive this situation, you can
use callChecked() instead of call(), passing it a local object to act as a "BailOutChecker".
The BailOutChecker must implement a method of the form "bool shouldBailOut()", and
the list will check this after each callback to determine whether it should abort the
operation. For an example of a bail-out checker, see the Component::BailOutChecker class,
which can be used to check when a Component has been deleted. See also
ListenerList::DummyBailOutChecker, which is a dummy checker that always returns false.
*/
template <class ListenerClass,
class ArrayType = Array<ListenerClass*> >
class ListenerList
{
// Horrible macros required to support VC7..
#ifndef DOXYGEN
#if JUCE_VC8_OR_EARLIER
#define LL_TEMPLATE(a) typename P##a, typename Q##a
#define LL_PARAM(a) Q##a& param##a
#else
#define LL_TEMPLATE(a) typename P##a
#define LL_PARAM(a) PARAMETER_TYPE(P##a) param##a
#endif
#endif
public:
//==============================================================================
/** Creates an empty list. */
ListenerList()
{
}
/** Destructor. */
~ListenerList()
{
}
//==============================================================================
/** Adds a listener to the list.
A listener can only be added once, so if the listener is already in the list,
this method has no effect.
@see remove
*/
void add (ListenerClass* const listenerToAdd)
{
// Listeners can't be null pointers!
jassert (listenerToAdd != nullptr);
if (listenerToAdd != nullptr)
listeners.addIfNotAlreadyThere (listenerToAdd);
}
/** Removes a listener from the list.
If the listener wasn't in the list, this has no effect.
*/
void remove (ListenerClass* const listenerToRemove)
{
// Listeners can't be null pointers!
jassert (listenerToRemove != nullptr);
listeners.removeFirstMatchingValue (listenerToRemove);
}
/** Returns the number of registered listeners. */
int size() const noexcept
{
return listeners.size();
}
/** Returns true if any listeners are registered. */
bool isEmpty() const noexcept
{
return listeners.size() == 0;
}
/** Clears the list. */
void clear()
{
listeners.clear();
}
/** Returns true if the specified listener has been added to the list. */
bool contains (ListenerClass* const listener) const noexcept
{
return listeners.contains (listener);
}
//==============================================================================
/** Calls a member function on each listener in the list, with no parameters. */
void call (void (ListenerClass::*callbackFunction) ())
{
callChecked (static_cast <const DummyBailOutChecker&> (DummyBailOutChecker()), callbackFunction);
}
/** Calls a member function on each listener in the list, with no parameters and a bail-out-checker.
See the class description for info about writing a bail-out checker. */
template <class BailOutCheckerType>
void callChecked (const BailOutCheckerType& bailOutChecker,
void (ListenerClass::*callbackFunction) ())
{
for (Iterator<BailOutCheckerType, ThisType> iter (*this); iter.next (bailOutChecker);)
(iter.getListener()->*callbackFunction) ();
}
//==============================================================================
/** Calls a member function on each listener in the list, with 1 parameter. */
template <LL_TEMPLATE(1)>
void call (void (ListenerClass::*callbackFunction) (P1), LL_PARAM(1))
{
for (Iterator<DummyBailOutChecker, ThisType> iter (*this); iter.next();)
(iter.getListener()->*callbackFunction) (param1);
}
/** Calls a member function on each listener in the list, with one parameter and a bail-out-checker.
See the class description for info about writing a bail-out checker. */
template <class BailOutCheckerType, LL_TEMPLATE(1)>
void callChecked (const BailOutCheckerType& bailOutChecker,
void (ListenerClass::*callbackFunction) (P1),
LL_PARAM(1))
{
for (Iterator<BailOutCheckerType, ThisType> iter (*this); iter.next (bailOutChecker);)
(iter.getListener()->*callbackFunction) (param1);
}
//==============================================================================
/** Calls a member function on each listener in the list, with 2 parameters. */
template <LL_TEMPLATE(1), LL_TEMPLATE(2)>
void call (void (ListenerClass::*callbackFunction) (P1, P2),
LL_PARAM(1), LL_PARAM(2))
{
for (Iterator<DummyBailOutChecker, ThisType> iter (*this); iter.next();)
(iter.getListener()->*callbackFunction) (param1, param2);
}
/** Calls a member function on each listener in the list, with 2 parameters and a bail-out-checker.
See the class description for info about writing a bail-out checker. */
template <class BailOutCheckerType, LL_TEMPLATE(1), LL_TEMPLATE(2)>
void callChecked (const BailOutCheckerType& bailOutChecker,
void (ListenerClass::*callbackFunction) (P1, P2),
LL_PARAM(1), LL_PARAM(2))
{
for (Iterator<BailOutCheckerType, ThisType> iter (*this); iter.next (bailOutChecker);)
(iter.getListener()->*callbackFunction) (param1, param2);
}
//==============================================================================
/** Calls a member function on each listener in the list, with 3 parameters. */
template <LL_TEMPLATE(1), LL_TEMPLATE(2), LL_TEMPLATE(3)>
void call (void (ListenerClass::*callbackFunction) (P1, P2, P3),
LL_PARAM(1), LL_PARAM(2), LL_PARAM(3))
{
for (Iterator<DummyBailOutChecker, ThisType> iter (*this); iter.next();)
(iter.getListener()->*callbackFunction) (param1, param2, param3);
}
/** Calls a member function on each listener in the list, with 3 parameters and a bail-out-checker.
See the class description for info about writing a bail-out checker. */
template <class BailOutCheckerType, LL_TEMPLATE(1), LL_TEMPLATE(2), LL_TEMPLATE(3)>
void callChecked (const BailOutCheckerType& bailOutChecker,
void (ListenerClass::*callbackFunction) (P1, P2, P3),
LL_PARAM(1), LL_PARAM(2), LL_PARAM(3))
{
for (Iterator<BailOutCheckerType, ThisType> iter (*this); iter.next (bailOutChecker);)
(iter.getListener()->*callbackFunction) (param1, param2, param3);
}
//==============================================================================
/** Calls a member function on each listener in the list, with 4 parameters. */
template <LL_TEMPLATE(1), LL_TEMPLATE(2), LL_TEMPLATE(3), LL_TEMPLATE(4)>
void call (void (ListenerClass::*callbackFunction) (P1, P2, P3, P4),
LL_PARAM(1), LL_PARAM(2), LL_PARAM(3), LL_PARAM(4))
{
for (Iterator<DummyBailOutChecker, ThisType> iter (*this); iter.next();)
(iter.getListener()->*callbackFunction) (param1, param2, param3, param4);
}
/** Calls a member function on each listener in the list, with 4 parameters and a bail-out-checker.
See the class description for info about writing a bail-out checker. */
template <class BailOutCheckerType, LL_TEMPLATE(1), LL_TEMPLATE(2), LL_TEMPLATE(3), LL_TEMPLATE(4)>
void callChecked (const BailOutCheckerType& bailOutChecker,
void (ListenerClass::*callbackFunction) (P1, P2, P3, P4),
LL_PARAM(1), LL_PARAM(2), LL_PARAM(3), LL_PARAM(4))
{
for (Iterator<BailOutCheckerType, ThisType> iter (*this); iter.next (bailOutChecker);)
(iter.getListener()->*callbackFunction) (param1, param2, param3, param4);
}
//==============================================================================
/** Calls a member function on each listener in the list, with 5 parameters. */
template <LL_TEMPLATE(1), LL_TEMPLATE(2), LL_TEMPLATE(3), LL_TEMPLATE(4), LL_TEMPLATE(5)>
void call (void (ListenerClass::*callbackFunction) (P1, P2, P3, P4, P5),
LL_PARAM(1), LL_PARAM(2), LL_PARAM(3), LL_PARAM(4), LL_PARAM(5))
{
for (Iterator<DummyBailOutChecker, ThisType> iter (*this); iter.next();)
(iter.getListener()->*callbackFunction) (param1, param2, param3, param4, param5);
}
/** Calls a member function on each listener in the list, with 5 parameters and a bail-out-checker.
See the class description for info about writing a bail-out checker. */
template <class BailOutCheckerType, LL_TEMPLATE(1), LL_TEMPLATE(2), LL_TEMPLATE(3), LL_TEMPLATE(4), LL_TEMPLATE(5)>
void callChecked (const BailOutCheckerType& bailOutChecker,
void (ListenerClass::*callbackFunction) (P1, P2, P3, P4, P5),
LL_PARAM(1), LL_PARAM(2), LL_PARAM(3), LL_PARAM(4), LL_PARAM(5))
{
for (Iterator<BailOutCheckerType, ThisType> iter (*this); iter.next (bailOutChecker);)
(iter.getListener()->*callbackFunction) (param1, param2, param3, param4, param5);
}
//==============================================================================
/** Calls a member function on each listener in the list, with 5 parameters. */
template <LL_TEMPLATE(1), LL_TEMPLATE(2), LL_TEMPLATE(3), LL_TEMPLATE(4), LL_TEMPLATE(5), LL_TEMPLATE(6)>
void call (void (ListenerClass::*callbackFunction) (P1, P2, P3, P4, P5, P6),
LL_PARAM(1), LL_PARAM(2), LL_PARAM(3), LL_PARAM(4), LL_PARAM(5), LL_PARAM(6))
{
for (Iterator<DummyBailOutChecker, ThisType> iter (*this); iter.next();)
(iter.getListener()->*callbackFunction) (param1, param2, param3, param4, param5, param6);
}
/** Calls a member function on each listener in the list, with 5 parameters and a bail-out-checker.
See the class description for info about writing a bail-out checker. */
template <class BailOutCheckerType, LL_TEMPLATE(1), LL_TEMPLATE(2), LL_TEMPLATE(3), LL_TEMPLATE(4), LL_TEMPLATE(5), LL_TEMPLATE(6)>
void callChecked (const BailOutCheckerType& bailOutChecker,
void (ListenerClass::*callbackFunction) (P1, P2, P3, P4, P5, P6),
LL_PARAM(1), LL_PARAM(2), LL_PARAM(3), LL_PARAM(4), LL_PARAM(5), LL_PARAM(6))
{
for (Iterator<BailOutCheckerType, ThisType> iter (*this); iter.next (bailOutChecker);)
(iter.getListener()->*callbackFunction) (param1, param2, param3, param4, param5, param6);
}
//==============================================================================
/** A dummy bail-out checker that always returns false.
See the ListenerList notes for more info about bail-out checkers.
*/
class DummyBailOutChecker
{
public:
inline bool shouldBailOut() const noexcept { return false; }
};
//==============================================================================
/** Iterates the listeners in a ListenerList. */
template <class BailOutCheckerType, class ListType>
class Iterator
{
public:
//==============================================================================
Iterator (const ListType& listToIterate) noexcept
: list (listToIterate), index (listToIterate.size())
{}
~Iterator() noexcept {}
//==============================================================================
bool next() noexcept
{
if (index <= 0)
return false;
const int listSize = list.size();
if (--index < listSize)
return true;
index = listSize - 1;
return index >= 0;
}
bool next (const BailOutCheckerType& bailOutChecker) noexcept
{
return (! bailOutChecker.shouldBailOut()) && next();
}
typename ListType::ListenerType* getListener() const noexcept
{
return list.getListeners().getUnchecked (index);
}
//==============================================================================
private:
const ListType& list;
int index;
JUCE_DECLARE_NON_COPYABLE (Iterator)
};
typedef ListenerList<ListenerClass, ArrayType> ThisType;
typedef ListenerClass ListenerType;
const ArrayType& getListeners() const noexcept { return listeners; }
private:
//==============================================================================
ArrayType listeners;
JUCE_DECLARE_NON_COPYABLE (ListenerList)
#undef LL_TEMPLATE
#undef LL_PARAM
};
#endif // JUCE_LISTENERLIST_H_INCLUDED