From 9a7ee9fdbb6bd6b1bee31f016da26d4899d451f6 Mon Sep 17 00:00:00 2001 From: hogliux Date: Thu, 17 Nov 2016 13:50:49 +0000 Subject: [PATCH] Added support for iOS custom delegates - use at your own risk --- .../messages/juce_ApplicationBase.cpp | 8 +-- .../messages/juce_ApplicationBase.h | 2 +- .../messages/juce_Initialisation.h | 52 ++++++++++++++++++- .../native/juce_ios_Windowing.mm | 8 +-- 4 files changed, 62 insertions(+), 8 deletions(-) diff --git a/modules/juce_events/messages/juce_ApplicationBase.cpp b/modules/juce_events/messages/juce_ApplicationBase.cpp index 5a2e3c3742..387768a1d9 100644 --- a/modules/juce_events/messages/juce_ApplicationBase.cpp +++ b/modules/juce_events/messages/juce_ApplicationBase.cpp @@ -164,7 +164,7 @@ StringArray JUCE_CALLTYPE JUCEApplicationBase::getCommandLineParameterArray() #else #if JUCE_IOS - extern int juce_iOSMain (int argc, const char* argv[]); + extern int juce_iOSMain (int argc, const char* argv[], void* classPtr); #endif #if JUCE_MAC @@ -201,7 +201,7 @@ StringArray JUCEApplicationBase::getCommandLineParameterArray() return StringArray (juce_argv + 1, juce_argc - 1); } -int JUCEApplicationBase::main (int argc, const char* argv[]) +int JUCEApplicationBase::main (int argc, const char* argv[], void* customDelegate) { JUCE_AUTORELEASEPOOL { @@ -213,8 +213,10 @@ int JUCEApplicationBase::main (int argc, const char* argv[]) #endif #if JUCE_IOS - return juce_iOSMain (argc, argv); + return juce_iOSMain (argc, argv, customDelegate); #else + ignoreUnused (customDelegate); + return JUCEApplicationBase::main(); #endif } diff --git a/modules/juce_events/messages/juce_ApplicationBase.h b/modules/juce_events/messages/juce_ApplicationBase.h index 35bc65ff71..3f668d50ef 100644 --- a/modules/juce_events/messages/juce_ApplicationBase.h +++ b/modules/juce_events/messages/juce_ApplicationBase.h @@ -252,7 +252,7 @@ public: #ifndef DOXYGEN // The following methods are for internal use only... static int main(); - static int main (int argc, const char* argv[]); + static int main (int argc, const char* argv[], void*); static void appWillTerminateByForce(); typedef JUCEApplicationBase* (*CreateInstanceFunction)(); diff --git a/modules/juce_events/messages/juce_Initialisation.h b/modules/juce_events/messages/juce_Initialisation.h index d358d0d8b9..7972227162 100644 --- a/modules/juce_events/messages/juce_Initialisation.h +++ b/modules/juce_events/messages/juce_Initialisation.h @@ -97,7 +97,7 @@ public: #define JUCE_MAIN_FUNCTION_ARGS #else #define JUCE_MAIN_FUNCTION int main (int argc, char* argv[]) - #define JUCE_MAIN_FUNCTION_ARGS argc, (const char**) argv + #define JUCE_MAIN_FUNCTION_ARGS argc, (const char**) argv, nullptr #endif #define START_JUCE_APPLICATION(AppClass) \ @@ -107,6 +107,56 @@ public: juce::JUCEApplicationBase::createInstance = &juce_CreateApplication; \ return juce::JUCEApplicationBase::main (JUCE_MAIN_FUNCTION_ARGS); \ } + + #if JUCE_IOS + /** + You can instruct JUCE to use a custom iOS app delegate class instaed of JUCE's default + app delegate. For JUCE to work you must pass all messages to JUCE's internal app delegate. + Below is an example of minimal forwarding custom delegate. Note that you are at your own + risk if you decide to use your own delegate an subtle, hard to debug bugs may occur. + + @interface MyCustomDelegate : NSObject { NSObject* juceDelegate; } @end + @implementation MyCustomDelegate + -(id) init + { + self = [super init]; + juceDelegate = reinterpret_cast*> ([[NSClassFromString (@"JuceAppStartupDelegate") alloc] init]); + + return self; + } + + -(void)dealloc + { + [juceDelegate release]; + [super dealloc]; + } + + - (void)forwardInvocation:(NSInvocation *)anInvocation + { + if (juceDelegate != nullptr && [juceDelegate respondsToSelector:[anInvocation selector]]) + [anInvocation invokeWithTarget:juceDelegate]; + else + [super forwardInvocation:anInvocation]; + } + + -(BOOL)respondsToSelector:(SEL)aSelector + { + if (juceDelegate != nullptr && [juceDelegate respondsToSelector:aSelector]) + return YES; + + return [super respondsToSelector:aSelector]; + } + @end + */ + #define START_JUCE_APPLICATION_WITH_CUSTOM_DELEGATE(AppClass, DelegateClass) \ + static juce::JUCEApplicationBase* juce_CreateApplication() { return new AppClass(); } \ + extern "C" JUCE_MAIN_FUNCTION \ + { \ + juce::JUCEApplicationBase::createInstance = &juce_CreateApplication; \ + return juce::JUCEApplicationBase::main (argc, (const char**) argv, [DelegateClass class]); \ + } + #endif + #endif #endif // JUCE_INITIALISATION_H_INCLUDED diff --git a/modules/juce_gui_basics/native/juce_ios_Windowing.mm b/modules/juce_gui_basics/native/juce_ios_Windowing.mm index 466c4ecf41..bbf26381e6 100644 --- a/modules/juce_gui_basics/native/juce_ios_Windowing.mm +++ b/modules/juce_gui_basics/native/juce_ios_Windowing.mm @@ -109,10 +109,12 @@ Array appBecomingInactiveCallbacks; namespace juce { -int juce_iOSMain (int argc, const char* argv[]); -int juce_iOSMain (int argc, const char* argv[]) +int juce_iOSMain (int argc, const char* argv[], void* customDelgatePtr); +int juce_iOSMain (int argc, const char* argv[], void* customDelagetPtr) { - return UIApplicationMain (argc, const_cast (argv), nil, @"JuceAppStartupDelegate"); + Class delegateClass = (customDelagetPtr != nullptr ? reinterpret_cast (customDelagetPtr) : [JuceAppStartupDelegate class]); + + return UIApplicationMain (argc, const_cast (argv), nil, NSStringFromClass (delegateClass)); } //==============================================================================