Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

CarlaJuceEvents.cpp 4.4KB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. /*
  2. * Fake juce event thread needed for juce_audio_processors
  3. * Copyright (C) 2014 Filipe Coelho <falktx@falktx.com>
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License as
  7. * published by the Free Software Foundation; either version 2 of
  8. * the License, or any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * For a full copy of the GNU General Public License see the doc/GPL.txt file.
  16. */
  17. #include "CarlaJuceUtils.hpp"
  18. // -------------------------------------------------------------------------------------------------------------------
  19. #if ! (defined(CARLA_OS_MAC) || defined(CARLA_OS_WIN))
  20. #undef KeyPress
  21. #include "juce_audio_processors.h"
  22. #include "juce_events.h"
  23. namespace juce {
  24. #include "juce_events/broadcasters/juce_ActionBroadcaster.cpp"
  25. #include "juce_events/broadcasters/juce_AsyncUpdater.cpp"
  26. #include "juce_events/messages/juce_DeletedAtShutdown.cpp"
  27. #include "juce_events/messages/juce_MessageManager.cpp"
  28. #include "juce_audio_processors/processors/juce_AudioProcessor.cpp"
  29. #include "juce_audio_processors/processors/juce_AudioProcessorGraph.cpp"
  30. class JuceEventsThread : public Thread
  31. {
  32. public:
  33. JuceEventsThread()
  34. : Thread("JuceEventsThread"),
  35. fInitializing(false),
  36. fLock(),
  37. fQueue() {}
  38. ~JuceEventsThread()
  39. {
  40. signalThreadShouldExit();
  41. stopThread(2000);
  42. const ScopedLock sl(fLock);
  43. fQueue.clear();
  44. }
  45. bool postMessage(MessageManager::MessageBase* const msg)
  46. {
  47. const ScopedLock sl(fLock);
  48. fQueue.add(msg);
  49. return true;
  50. }
  51. bool isInitializing() const noexcept
  52. {
  53. return fInitializing;
  54. }
  55. protected:
  56. void run() override
  57. {
  58. /*
  59. * We need to know when we're initializing because MessageManager::setCurrentThreadAsMessageThread()
  60. * calls doPlatformSpecificInitialisation/Shutdown, in which we started this thread previously.
  61. * To avoid a deadlock we do not call start/stopThread if still initializing.
  62. */
  63. fInitializing = true;
  64. if (MessageManager* const msgMgr = MessageManager::getInstance())
  65. msgMgr->setCurrentThreadAsMessageThread();
  66. fInitializing = false;
  67. for (; ! threadShouldExit();)
  68. {
  69. // dispatch messages until no more present, then sleep
  70. for (; dispatchNextInternalMessage();) {}
  71. sleep(25);
  72. }
  73. }
  74. private:
  75. volatile bool fInitializing;
  76. CriticalSection fLock;
  77. ReferenceCountedArray<MessageManager::MessageBase> fQueue;
  78. MessageManager::MessageBase::Ptr popNextMessage()
  79. {
  80. const ScopedLock sl(fLock);
  81. return fQueue.removeAndReturn(0);
  82. }
  83. bool dispatchNextInternalMessage()
  84. {
  85. if (const MessageManager::MessageBase::Ptr msg = popNextMessage())
  86. {
  87. JUCE_TRY
  88. {
  89. msg->messageCallback();
  90. return true;
  91. }
  92. JUCE_CATCH_EXCEPTION
  93. }
  94. return false;
  95. }
  96. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(JuceEventsThread)
  97. };
  98. static JuceEventsThread& getJuceEventsThreadInstance()
  99. {
  100. static JuceEventsThread sJuceEventsThread;
  101. return sJuceEventsThread;
  102. }
  103. JUCEApplicationBase::CreateInstanceFunction JUCEApplicationBase::createInstance = nullptr;
  104. void MessageManager::doPlatformSpecificInitialisation()
  105. {
  106. JuceEventsThread& juceEventsThread(getJuceEventsThreadInstance());
  107. if (! juceEventsThread.isInitializing())
  108. juceEventsThread.startThread();
  109. }
  110. void MessageManager::doPlatformSpecificShutdown()
  111. {
  112. JuceEventsThread& juceEventsThread(getJuceEventsThreadInstance());
  113. if (! juceEventsThread.isInitializing())
  114. juceEventsThread.stopThread(-1);
  115. }
  116. bool MessageManager::postMessageToSystemQueue(MessageManager::MessageBase* const message)
  117. {
  118. JuceEventsThread& juceEventsThread(getJuceEventsThreadInstance());
  119. return juceEventsThread.postMessage(message);
  120. }
  121. bool MessageManager::dispatchNextMessageOnSystemQueue(bool)
  122. {
  123. carla_stderr2("MessageManager::dispatchNextMessageOnSystemQueue() unsupported");
  124. return false;
  125. }
  126. } // namespace juce
  127. #endif // ! CARLA_OS_MAC || CARLA_OS_WIN