8 #include <AppKit/AppKit.h>
9 #include <AppKit/NSApplication.h>
10 #include <Foundation/Foundation.h>
11 #include <objc/message.h>
13 #include "flutter/fml/logging.h"
14 #include "flutter/fml/paths.h"
17 NSMutableArray* _notificationUnsubscribers;
20 - (void)addObserverFor:(NSString*)name selector:(
SEL)selector {
21 [[NSNotificationCenter defaultCenter] addObserver:self selector:selector name:name object:nil];
22 __block NSObject* blockSelf =
self;
23 dispatch_block_t unsubscribe = ^{
24 [[NSNotificationCenter defaultCenter] removeObserver:blockSelf name:name object:nil];
26 [_notificationUnsubscribers addObject:[unsubscribe copy]];
29 - (instancetype)init {
30 if (
self = [super init]) {
31 _notificationUnsubscribers = [[NSMutableArray alloc] init];
35 #ifdef OBSERVE_NOTIFICATION
36 #error OBSERVE_NOTIFICATION ALREADY DEFINED!
38 #define OBSERVE_NOTIFICATION(SELECTOR) \
39 [self addObserverFor:NSApplication##SELECTOR##Notification selector:@selector(handle##SELECTOR:)]
56 #undef OBSERVE_NOTIFICATION
58 _delegates = [NSPointerArray weakObjectsPointerArray];
64 for (dispatch_block_t unsubscribe in _notificationUnsubscribers) {
67 [_notificationUnsubscribers removeAllObjects];
69 _notificationUnsubscribers = nil;
72 static BOOL IsPowerOfTwo(NSUInteger x) {
73 return x != 0 && (x & (x - 1)) == 0;
77 [_delegates addPointer:(__bridge void*)delegate];
78 if (IsPowerOfTwo([_delegates count])) {
84 NSUInteger index = [[_delegates allObjects] indexOfObject:delegate];
85 if (index != NSNotFound) {
86 [_delegates removePointerAtIndex:index];
93 #ifdef DISTRIBUTE_NOTIFICATION
94 #error DISTRIBUTE_NOTIFICATION ALREADY DEFINED!
96 #define DISTRIBUTE_NOTIFICATION(SELECTOR) \
97 -(void)handle##SELECTOR : (NSNotification*)notification { \
98 for (NSObject<FlutterAppLifecycleDelegate> * delegate in _delegates) { \
99 if ([delegate respondsToSelector:@selector(handle##SELECTOR:)]) { \
100 [delegate handle##SELECTOR:notification]; \
120 #undef DISTRIBUTE_NOTIFICATION