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.

181 lines
5.6KB

  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. struct CallbackMessagePayload
  19. {
  20. MessageCallbackFunction* function;
  21. void* parameter;
  22. void* volatile result;
  23. bool volatile hasBeenExecuted;
  24. };
  25. END_JUCE_NAMESPACE
  26. //==============================================================================
  27. @interface JuceCustomMessageHandler : NSObject
  28. {
  29. }
  30. - (void) performCallback: (id) info;
  31. @end
  32. //==============================================================================
  33. @implementation JuceCustomMessageHandler
  34. - (void) performCallback: (id) info
  35. {
  36. if ([info isKindOfClass: [NSData class]])
  37. {
  38. juce::CallbackMessagePayload* pl = (juce::CallbackMessagePayload*) [((NSData*) info) bytes];
  39. if (pl != nullptr)
  40. {
  41. pl->result = (*pl->function) (pl->parameter);
  42. pl->hasBeenExecuted = true;
  43. }
  44. }
  45. else
  46. {
  47. jassertfalse; // should never get here!
  48. }
  49. }
  50. @end
  51. BEGIN_JUCE_NAMESPACE
  52. //==============================================================================
  53. void MessageManager::runDispatchLoop()
  54. {
  55. jassert (isThisTheMessageThread()); // must only be called by the message thread
  56. runDispatchLoopUntil (-1);
  57. }
  58. void MessageManager::stopDispatchLoop()
  59. {
  60. [[[UIApplication sharedApplication] delegate] applicationWillTerminate: [UIApplication sharedApplication]];
  61. exit (0); // iPhone apps get no mercy..
  62. }
  63. bool MessageManager::runDispatchLoopUntil (int millisecondsToRunFor)
  64. {
  65. JUCE_AUTORELEASEPOOL
  66. jassert (isThisTheMessageThread()); // must only be called by the message thread
  67. uint32 endTime = Time::getMillisecondCounter() + millisecondsToRunFor;
  68. NSDate* endDate = [NSDate dateWithTimeIntervalSinceNow: millisecondsToRunFor * 0.001];
  69. while (! quitMessagePosted)
  70. {
  71. JUCE_AUTORELEASEPOOL
  72. [[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode
  73. beforeDate: endDate];
  74. if (millisecondsToRunFor >= 0 && Time::getMillisecondCounter() >= endTime)
  75. break;
  76. }
  77. return ! quitMessagePosted;
  78. }
  79. //==============================================================================
  80. struct MessageDispatchSystem
  81. {
  82. MessageDispatchSystem()
  83. : juceCustomMessageHandler (nil)
  84. {
  85. juceCustomMessageHandler = [[JuceCustomMessageHandler alloc] init];
  86. }
  87. ~MessageDispatchSystem()
  88. {
  89. [[NSRunLoop currentRunLoop] cancelPerformSelectorsWithTarget: juceCustomMessageHandler];
  90. [juceCustomMessageHandler release];
  91. }
  92. JuceCustomMessageHandler* juceCustomMessageHandler;
  93. MessageQueue messageQueue;
  94. };
  95. static ScopedPointer<MessageDispatchSystem> dispatcher;
  96. void MessageManager::doPlatformSpecificInitialisation()
  97. {
  98. if (dispatcher == nullptr)
  99. dispatcher = new MessageDispatchSystem();
  100. }
  101. void MessageManager::doPlatformSpecificShutdown()
  102. {
  103. dispatcher = nullptr;
  104. }
  105. bool MessageManager::postMessageToSystemQueue (Message* message)
  106. {
  107. if (dispatcher != nullptr)
  108. dispatcher->messageQueue.post (message);
  109. return true;
  110. }
  111. void MessageManager::broadcastMessage (const String& value)
  112. {
  113. }
  114. void* MessageManager::callFunctionOnMessageThread (MessageCallbackFunction* callback, void* data)
  115. {
  116. if (isThisTheMessageThread())
  117. {
  118. return (*callback) (data);
  119. }
  120. else
  121. {
  122. jassert (dispatcher != nullptr); // trying to call this when the juce system isn't initialised..
  123. // If a thread has a MessageManagerLock and then tries to call this method, it'll
  124. // deadlock because the message manager is blocked from running, so can never
  125. // call your function..
  126. jassert (! MessageManager::getInstance()->currentThreadHasLockedMessageManager());
  127. JUCE_AUTORELEASEPOOL
  128. CallbackMessagePayload cmp;
  129. cmp.function = callback;
  130. cmp.parameter = data;
  131. cmp.result = 0;
  132. cmp.hasBeenExecuted = false;
  133. [dispatcher->juceCustomMessageHandler performSelectorOnMainThread: @selector (performCallback:)
  134. withObject: [NSData dataWithBytesNoCopy: &cmp
  135. length: sizeof (cmp)
  136. freeWhenDone: NO]
  137. waitUntilDone: YES];
  138. return cmp.result;
  139. }
  140. }