| 
							- /*
 -  * Fake juce event thread needed for juce_audio_processors
 -  * Copyright (C) 2014 Filipe Coelho <falktx@falktx.com>
 -  *
 -  * This program is free software; you can redistribute it and/or
 -  * modify it under the terms of the GNU General Public License as
 -  * published by the Free Software Foundation; either version 2 of
 -  * the License, or any later version.
 -  *
 -  * This program 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.
 -  *
 -  * For a full copy of the GNU General Public License see the doc/GPL.txt file.
 -  */
 - 
 - #include "CarlaJuceUtils.hpp"
 - 
 - // -------------------------------------------------------------------------------------------------------------------
 - 
 - #if ! (defined(CARLA_OS_MAC) || defined(CARLA_OS_WIN))
 - 
 - #undef KeyPress
 - #include "juce_audio_processors.h"
 - #include "juce_events.h"
 - 
 - namespace juce {
 - 
 - #include "juce_events/broadcasters/juce_ActionBroadcaster.cpp"
 - #include "juce_events/broadcasters/juce_AsyncUpdater.cpp"
 - #include "juce_events/messages/juce_DeletedAtShutdown.cpp"
 - #include "juce_events/messages/juce_MessageManager.cpp"
 - #include "juce_audio_processors/processors/juce_AudioProcessor.cpp"
 - #include "juce_audio_processors/processors/juce_AudioProcessorGraph.cpp"
 - 
 - class JuceEventsThread : public Thread
 - {
 - public:
 -     JuceEventsThread()
 -         : Thread("JuceEventsThread"),
 -           fInitializing(false),
 -           fLock(),
 -           fQueue() {}
 - 
 -     ~JuceEventsThread()
 -     {
 -         signalThreadShouldExit();
 -         stopThread(2000);
 - 
 -         const ScopedLock sl(fLock);
 -         fQueue.clear();
 -     }
 - 
 -     bool postMessage(MessageManager::MessageBase* const msg)
 -     {
 -         const ScopedLock sl(fLock);
 -         fQueue.add(msg);
 -         return true;
 -     }
 - 
 -     bool isInitializing() const noexcept
 -     {
 -         return fInitializing;
 -     }
 - 
 - protected:
 -     void run() override
 -     {
 -         /*
 -          * We need to know when we're initializing because MessageManager::setCurrentThreadAsMessageThread()
 -          * calls doPlatformSpecificInitialisation/Shutdown, in which we started this thread previously.
 -          * To avoid a deadlock we do not call start/stopThread if still initializing.
 -          */
 -         fInitializing = true;
 - 
 -         if (MessageManager* const msgMgr = MessageManager::getInstance())
 -             msgMgr->setCurrentThreadAsMessageThread();
 - 
 -         fInitializing = false;
 - 
 -         for (; ! threadShouldExit();)
 -         {
 -             // dispatch messages until no more present, then sleep
 -             for (; dispatchNextInternalMessage();) {}
 - 
 -             sleep(25);
 -         }
 -     }
 - 
 - private:
 -     volatile bool fInitializing;
 -     CriticalSection fLock;
 -     ReferenceCountedArray<MessageManager::MessageBase> fQueue;
 - 
 -     MessageManager::MessageBase::Ptr popNextMessage()
 -     {
 -         const ScopedLock sl(fLock);
 -         return fQueue.removeAndReturn(0);
 -     }
 - 
 -     bool dispatchNextInternalMessage()
 -     {
 -         if (const MessageManager::MessageBase::Ptr msg = popNextMessage())
 -         {
 -             JUCE_TRY
 -             {
 -                 msg->messageCallback();
 -                 return true;
 -             }
 -             JUCE_CATCH_EXCEPTION
 -         }
 - 
 -         return false;
 -     }
 - 
 -     CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(JuceEventsThread)
 - };
 - 
 - static JuceEventsThread& getJuceEventsThreadInstance()
 - {
 -     static JuceEventsThread sJuceEventsThread;
 -     return sJuceEventsThread;
 - }
 - 
 - JUCEApplicationBase::CreateInstanceFunction JUCEApplicationBase::createInstance = nullptr;
 - 
 - void MessageManager::doPlatformSpecificInitialisation()
 - {
 -     JuceEventsThread& juceEventsThread(getJuceEventsThreadInstance());
 - 
 -     if (! juceEventsThread.isInitializing())
 -         juceEventsThread.startThread();
 - }
 - 
 - void MessageManager::doPlatformSpecificShutdown()
 - {
 -     JuceEventsThread& juceEventsThread(getJuceEventsThreadInstance());
 - 
 -     if (! juceEventsThread.isInitializing())
 -         juceEventsThread.stopThread(-1);
 - }
 - 
 - bool MessageManager::postMessageToSystemQueue(MessageManager::MessageBase* const message)
 - {
 -     JuceEventsThread& juceEventsThread(getJuceEventsThreadInstance());
 -     return juceEventsThread.postMessage(message);
 - }
 - 
 - bool MessageManager::dispatchNextMessageOnSystemQueue(bool)
 - {
 -     carla_stderr2("MessageManager::dispatchNextMessageOnSystemQueue() unsupported");
 -     return false;
 - }
 - 
 - } // namespace juce
 - 
 - #endif // ! CARLA_OS_MAC || CARLA_OS_WIN
 
 
  |