diff --git a/modules/juce_audio_plugin_client/AU/juce_AUv3_Wrapper.mm b/modules/juce_audio_plugin_client/AU/juce_AUv3_Wrapper.mm index cdb44060bf..b5b9640958 100644 --- a/modules/juce_audio_plugin_client/AU/juce_AUv3_Wrapper.mm +++ b/modules/juce_audio_plugin_client/AU/juce_AUv3_Wrapper.mm @@ -1556,6 +1556,13 @@ public: } } + void didReceiveMemoryWarning() + { + if (processorHolder != nullptr) + if (auto* processor = processorHolder->get()) + processor->memoryWarningReceived(); + } + CGSize getPreferredContentSize() const { return CGSizeMake (static_cast (preferredSize.getWidth()), @@ -1634,11 +1641,12 @@ private: ScopedPointer cpp; } -- (instancetype) initWithNibName: (nullable NSString*) nib bundle: (nullable NSBundle*) bndl { self = [super initWithNibName: nib bundle: bndl]; cpp = new JuceAUViewController (self); return self;} -- (void) loadView { cpp->loadView(); } -- (AUAudioUnit *)createAudioUnitWithComponentDescription:(AudioComponentDescription)desc error:(NSError **)error { return cpp->createAudioUnit (desc, error); } -- (CGSize) preferredContentSize { return cpp->getPreferredContentSize(); } -- (void)viewDidLayoutSubviews { return cpp->viewDidLayoutSubviews(); } +- (instancetype) initWithNibName: (nullable NSString*) nib bundle: (nullable NSBundle*) bndl { self = [super initWithNibName: nib bundle: bndl]; cpp = new JuceAUViewController (self); return self; } +- (void) loadView { cpp->loadView(); } +- (AUAudioUnit *) createAudioUnitWithComponentDescription: (AudioComponentDescription) desc error: (NSError **) error { return cpp->createAudioUnit (desc, error); } +- (CGSize) preferredContentSize { return cpp->getPreferredContentSize(); } +- (void) viewDidLayoutSubviews { cpp->viewDidLayoutSubviews(); } +- (void) didReceiveMemoryWarning { cpp->didReceiveMemoryWarning(); } @end //============================================================================== @@ -1646,7 +1654,7 @@ private: bool JUCE_CALLTYPE juce_isInterAppAudioConnected() { return false; } void JUCE_CALLTYPE juce_switchToHostApplication() {} #if JUCE_MODULE_AVAILABLE_juce_gui_basics -Image JUCE_CALLTYPE juce_getIAAHostIcon (int) { return Image(); } +Image JUCE_CALLTYPE juce_getIAAHostIcon (int) { return {}; } #endif #endif diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessor.h b/modules/juce_audio_processors/processors/juce_AudioProcessor.h index 137d28a30b..5bb3241a8f 100644 --- a/modules/juce_audio_processors/processors/juce_AudioProcessor.h +++ b/modules/juce_audio_processors/processors/juce_AudioProcessor.h @@ -129,6 +129,16 @@ public: */ virtual void releaseResources() = 0; + /** Called by the host to indicate that you should reduce your memory footprint. + + You should override this method to free up some memory gracefully, if possible, + otherwise the host may forcibly unload your AudioProcessor. + + At the moment this method is only called when your AudioProcessor is an AUv3 + plug-in running on iOS. + */ + virtual void memoryWarningReceived() { jassertfalse; } + /** Renders the next block. When this method is called, the buffer contains a number of channels which is diff --git a/modules/juce_events/messages/juce_ApplicationBase.h b/modules/juce_events/messages/juce_ApplicationBase.h index 85fdafa080..2d5a3dbf7c 100644 --- a/modules/juce_events/messages/juce_ApplicationBase.h +++ b/modules/juce_events/messages/juce_ApplicationBase.h @@ -188,6 +188,16 @@ public: const String& sourceFilename, int lineNumber) = 0; + /** Called by the operating system to indicate that you should reduce your memory + footprint. + + You should override this method to free up some memory gracefully, if possible, + otherwise the host may forcibly kill your app. + + At the moment this method is only called on iOS. + */ + virtual void memoryWarningReceived() { jassertfalse; } + //============================================================================== /** Override this method to be informed when the back button is pressed on a device. This is currently only implemented on Android devices. diff --git a/modules/juce_events/native/juce_mac_MessageManager.mm b/modules/juce_events/native/juce_mac_MessageManager.mm index 1ea60b4802..ef6749cb81 100644 --- a/modules/juce_events/native/juce_mac_MessageManager.mm +++ b/modules/juce_events/native/juce_mac_MessageManager.mm @@ -116,7 +116,7 @@ private: addMethod (@selector (mainMenuTrackingEnded:), mainMenuTrackingEnded, "v@:@"); addMethod (@selector (dummyMethod), dummyMethod, "v@:"); - #if JUCE_PUSH_NOTIFICATIONS + #if JUCE_PUSH_NOTIFICATIONS //============================================================================== addIvar*> ("pushNotificationsDelegate"); @@ -125,7 +125,7 @@ private: addMethod (@selector (application:didRegisterForRemoteNotificationsWithDeviceToken:), registeredForRemoteNotifications, "v@:@@"); addMethod (@selector (application:didFailToRegisterForRemoteNotificationsWithError:), failedToRegisterForRemoteNotifications, "v@:@@"); addMethod (@selector (application:didReceiveRemoteNotification:), didReceiveRemoteNotification, "v@:@@"); - #endif + #endif registerClass(); } @@ -139,7 +139,7 @@ private: andEventID: kAEGetURL]; } - #if JUCE_PUSH_NOTIFICATIONS + #if JUCE_PUSH_NOTIFICATIONS static void applicationDidFinishLaunching (id self, SEL, NSNotification* notification) { if (notification.userInfo != nil) @@ -150,7 +150,7 @@ private: didReceiveRemoteNotification (self, nil, [NSApplication sharedApplication], userNotification.userInfo); } } - #endif + #endif static NSApplicationTerminateReply applicationShouldTerminate (id /*self*/, SEL, NSApplication*) { @@ -241,7 +241,7 @@ private: return s; } - #if JUCE_PUSH_NOTIFICATIONS + #if JUCE_PUSH_NOTIFICATIONS //============================================================================== static void setPushNotificationsDelegate (id self, SEL, NSObject* delegate) { @@ -306,7 +306,7 @@ private: [invocation invoke]; } } - #endif + #endif }; }; diff --git a/modules/juce_gui_basics/native/juce_ios_Windowing.mm b/modules/juce_gui_basics/native/juce_ios_Windowing.mm index 3818673887..546f40c71a 100644 --- a/modules/juce_gui_basics/native/juce_ios_Windowing.mm +++ b/modules/juce_gui_basics/native/juce_ios_Windowing.mm @@ -57,6 +57,7 @@ namespace juce - (void) applicationWillResignActive: (UIApplication*) application; - (void) application: (UIApplication*) application handleEventsForBackgroundURLSession: (NSString*) identifier completionHandler: (void (^)(void)) completionHandler; +- (void) applicationDidReceiveMemoryWarning: (UIApplication *) application; #if JUCE_PUSH_NOTIFICATIONS - (void) application: (UIApplication*) application didRegisterUserNotificationSettings: (UIUserNotificationSettings*) notificationSettings; - (void) application: (UIApplication*) application didRegisterForRemoteNotificationsWithDeviceToken: (NSData*) deviceToken; @@ -92,9 +93,9 @@ namespace juce self = [super init]; appSuspendTask = UIBackgroundTaskInvalid; - #if JUCE_PUSH_NOTIFICATIONS && defined (__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 + #if JUCE_PUSH_NOTIFICATIONS && defined (__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 [UNUserNotificationCenter currentNotificationCenter].delegate = self; - #endif + #endif return self; } @@ -104,7 +105,7 @@ namespace juce ignoreUnused (application); initialiseJuce_GUI(); - if (JUCEApplicationBase* app = JUCEApplicationBase::createInstance()) + if (auto* app = JUCEApplicationBase::createInstance()) { if (! app->initialiseApp()) exit (app->shutdownApp()); @@ -174,6 +175,14 @@ namespace juce completionHandler(); } +- (void) applicationDidReceiveMemoryWarning: (UIApplication*) application +{ + ignoreUnused (application); + + if (auto* app = JUCEApplicationBase::getInstance()) + app->memoryWarningReceived(); +} + - (void) setPushNotificationsDelegateToUse: (NSObject*) delegate { _pushNotificationsDelegate = delegate;