mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
ListenerList: Optimise empty listener list
This commit is contained in:
parent
315167a91a
commit
0dfff1454c
1 changed files with 54 additions and 7 deletions
|
|
@ -111,6 +111,8 @@ public:
|
|||
*/
|
||||
void add (ListenerClass* listenerToAdd)
|
||||
{
|
||||
initialiseIfNeeded();
|
||||
|
||||
if (listenerToAdd != nullptr)
|
||||
listeners->addIfNotAlreadyThere (listenerToAdd);
|
||||
else
|
||||
|
|
@ -127,6 +129,9 @@ public:
|
|||
{
|
||||
jassert (listenerToRemove != nullptr); // Listeners can't be null pointers!
|
||||
|
||||
if (! initialised())
|
||||
return;
|
||||
|
||||
const ScopedLockType lock (listeners->getLock());
|
||||
|
||||
if (const auto index = listeners->removeFirstMatchingValue (listenerToRemove); index >= 0)
|
||||
|
|
@ -154,10 +159,10 @@ public:
|
|||
}
|
||||
|
||||
/** Returns the number of registered listeners. */
|
||||
int size() const noexcept { return listeners->size(); }
|
||||
int size() const noexcept { return ! initialised() ? 0 : listeners->size(); }
|
||||
|
||||
/** Returns true if no listeners are registered, false otherwise. */
|
||||
bool isEmpty() const noexcept { return listeners->isEmpty(); }
|
||||
bool isEmpty() const noexcept { return ! initialised() || listeners->isEmpty(); }
|
||||
|
||||
/** Clears the list.
|
||||
|
||||
|
|
@ -166,7 +171,8 @@ public:
|
|||
*/
|
||||
void clear()
|
||||
{
|
||||
const ScopedLockType lock (listeners->getLock());
|
||||
if (! initialised())
|
||||
return;
|
||||
|
||||
listeners->clear();
|
||||
|
||||
|
|
@ -175,7 +181,11 @@ public:
|
|||
}
|
||||
|
||||
/** Returns true if the specified listener has been added to the list. */
|
||||
bool contains (ListenerClass* listener) const noexcept { return listeners->contains (listener); }
|
||||
bool contains (ListenerClass* listener) const noexcept
|
||||
{
|
||||
return initialised()
|
||||
&& listeners->contains (listener);
|
||||
}
|
||||
|
||||
/** Returns the raw array of listeners.
|
||||
|
||||
|
|
@ -186,7 +196,11 @@ public:
|
|||
|
||||
@see add, remove, clear, contains
|
||||
*/
|
||||
const ArrayType& getListeners() const noexcept { return *listeners; }
|
||||
const ArrayType& getListeners() const noexcept
|
||||
{
|
||||
const_cast<ListenerList*> (this)->initialiseIfNeeded();
|
||||
return *listeners;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/** Calls an invokable object for each listener in the list. */
|
||||
|
|
@ -234,6 +248,9 @@ public:
|
|||
const BailOutCheckerType& bailOutChecker,
|
||||
Callback&& callback)
|
||||
{
|
||||
if (! initialised())
|
||||
return;
|
||||
|
||||
const auto localListeners = listeners;
|
||||
const ScopedLockType lock { localListeners->getLock() };
|
||||
|
||||
|
|
@ -339,7 +356,7 @@ private:
|
|||
|
||||
//==============================================================================
|
||||
using SharedListeners = std::shared_ptr<ArrayType>;
|
||||
const SharedListeners listeners = std::make_shared<ArrayType>();
|
||||
SharedListeners listeners;
|
||||
|
||||
struct Iterator
|
||||
{
|
||||
|
|
@ -349,7 +366,37 @@ private:
|
|||
|
||||
using SafeIterators = std::vector<Iterator*>;
|
||||
using SharedIterators = std::shared_ptr<SafeIterators>;
|
||||
const SharedIterators iterators = std::make_shared<SafeIterators>();
|
||||
SharedIterators iterators;
|
||||
|
||||
enum class State
|
||||
{
|
||||
uninitialised,
|
||||
initialising,
|
||||
initialised
|
||||
};
|
||||
|
||||
std::atomic<State> state { State::uninitialised };
|
||||
|
||||
inline bool initialised() const noexcept { return state == State::initialised; }
|
||||
|
||||
inline void initialiseIfNeeded() noexcept
|
||||
{
|
||||
if (initialised())
|
||||
return;
|
||||
|
||||
auto expected = State::uninitialised;
|
||||
|
||||
if (state.compare_exchange_strong (expected, State::initialising))
|
||||
{
|
||||
listeners = std::make_shared<ArrayType>();
|
||||
iterators = std::make_shared<SafeIterators>();
|
||||
state = State::initialised;
|
||||
return;
|
||||
}
|
||||
|
||||
while (! initialised())
|
||||
std::this_thread::yield();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
JUCE_DECLARE_NON_COPYABLE (ListenerList)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue