The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
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.

187 lines
5.8KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library - "Jules' Utility Class Extensions"
  4. Copyright 2004-11 by Raw Material Software Ltd.
  5. ------------------------------------------------------------------------------
  6. JUCE can be redistributed and/or modified under the terms of the GNU General
  7. Public License (Version 2), as published by the Free Software Foundation.
  8. A copy of the license is included in the JUCE distribution, or can be found
  9. online at www.gnu.org/licenses.
  10. JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
  11. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  12. A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  13. ------------------------------------------------------------------------------
  14. To release a closed-source product which uses JUCE, commercial licenses are
  15. available: visit www.rawmaterialsoftware.com/juce for more information.
  16. ==============================================================================
  17. */
  18. // (This file gets included by juce_mac_NativeCode.mm, rather than being
  19. // compiled on its own).
  20. #if JUCE_INCLUDED_FILE
  21. struct CallbackMessagePayload
  22. {
  23. MessageCallbackFunction* function;
  24. void* parameter;
  25. void* volatile result;
  26. bool volatile hasBeenExecuted;
  27. };
  28. END_JUCE_NAMESPACE
  29. //==============================================================================
  30. @interface JuceCustomMessageHandler : NSObject
  31. {
  32. }
  33. - (void) performCallback: (id) info;
  34. @end
  35. //==============================================================================
  36. @implementation JuceCustomMessageHandler
  37. - (void) performCallback: (id) info
  38. {
  39. if ([info isKindOfClass: [NSData class]])
  40. {
  41. JUCE_NAMESPACE::CallbackMessagePayload* pl = (JUCE_NAMESPACE::CallbackMessagePayload*) [((NSData*) info) bytes];
  42. if (pl != nullptr)
  43. {
  44. pl->result = (*pl->function) (pl->parameter);
  45. pl->hasBeenExecuted = true;
  46. }
  47. }
  48. else
  49. {
  50. jassertfalse; // should never get here!
  51. }
  52. }
  53. @end
  54. BEGIN_JUCE_NAMESPACE
  55. //==============================================================================
  56. void MessageManager::runDispatchLoop()
  57. {
  58. jassert (isThisTheMessageThread()); // must only be called by the message thread
  59. runDispatchLoopUntil (-1);
  60. }
  61. void MessageManager::stopDispatchLoop()
  62. {
  63. [[[UIApplication sharedApplication] delegate] applicationWillTerminate: [UIApplication sharedApplication]];
  64. exit (0); // iPhone apps get no mercy..
  65. }
  66. bool MessageManager::runDispatchLoopUntil (int millisecondsToRunFor)
  67. {
  68. JUCE_AUTORELEASEPOOL
  69. jassert (isThisTheMessageThread()); // must only be called by the message thread
  70. uint32 endTime = Time::getMillisecondCounter() + millisecondsToRunFor;
  71. NSDate* endDate = [NSDate dateWithTimeIntervalSinceNow: millisecondsToRunFor * 0.001];
  72. while (! quitMessagePosted)
  73. {
  74. JUCE_AUTORELEASEPOOL
  75. [[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode
  76. beforeDate: endDate];
  77. if (millisecondsToRunFor >= 0 && Time::getMillisecondCounter() >= endTime)
  78. break;
  79. }
  80. return ! quitMessagePosted;
  81. }
  82. //==============================================================================
  83. struct MessageDispatchSystem
  84. {
  85. MessageDispatchSystem()
  86. : juceCustomMessageHandler (nil)
  87. {
  88. juceCustomMessageHandler = [[JuceCustomMessageHandler alloc] init];
  89. }
  90. ~MessageDispatchSystem()
  91. {
  92. [[NSRunLoop currentRunLoop] cancelPerformSelectorsWithTarget: juceCustomMessageHandler];
  93. [juceCustomMessageHandler release];
  94. }
  95. JuceCustomMessageHandler* juceCustomMessageHandler;
  96. MessageQueue messageQueue;
  97. };
  98. static ScopedPointer<MessageDispatchSystem> dispatcher;
  99. void MessageManager::doPlatformSpecificInitialisation()
  100. {
  101. if (dispatcher == nullptr)
  102. dispatcher = new MessageDispatchSystem();
  103. }
  104. void MessageManager::doPlatformSpecificShutdown()
  105. {
  106. dispatcher = nullptr;
  107. }
  108. bool MessageManager::postMessageToSystemQueue (Message* message)
  109. {
  110. if (dispatcher != nullptr)
  111. dispatcher->messageQueue.post (message);
  112. return true;
  113. }
  114. void MessageManager::broadcastMessage (const String& value)
  115. {
  116. }
  117. void* MessageManager::callFunctionOnMessageThread (MessageCallbackFunction* callback, void* data)
  118. {
  119. if (isThisTheMessageThread())
  120. {
  121. return (*callback) (data);
  122. }
  123. else
  124. {
  125. jassert (dispatcher != nullptr); // trying to call this when the juce system isn't initialised..
  126. // If a thread has a MessageManagerLock and then tries to call this method, it'll
  127. // deadlock because the message manager is blocked from running, so can never
  128. // call your function..
  129. jassert (! MessageManager::getInstance()->currentThreadHasLockedMessageManager());
  130. JUCE_AUTORELEASEPOOL
  131. CallbackMessagePayload cmp;
  132. cmp.function = callback;
  133. cmp.parameter = data;
  134. cmp.result = 0;
  135. cmp.hasBeenExecuted = false;
  136. [dispatcher->juceCustomMessageHandler performSelectorOnMainThread: @selector (performCallback:)
  137. withObject: [NSData dataWithBytesNoCopy: &cmp
  138. length: sizeof (cmp)
  139. freeWhenDone: NO]
  140. waitUntilDone: YES];
  141. return cmp.result;
  142. }
  143. }
  144. #endif