text: /*
    ==============================================================================
  
     This file is part of the JUCE library - "Jules' Utility Class Extensions"
     Copyright 2004-11 by Raw Material Software Ltd.
  
    ------------------------------------------------------------------------------
  
     JUCE can be redistributed and/or modified under the terms of the GNU General
     Public License (Version 2), as published by the Free Software Foundation.
     A copy of the license is included in the JUCE distribution, or can be found
     online 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.rawmaterialsoftware.com/juce 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();
  }
  