SameBoy | Accurate GB/GBC emulator |
| download: https://git.y1.nz/archives/sameboy.tar.gz | |
| README | Files | Log | Refs | LICENSE |
Cocoa/NSObject+DefaultsObserver.m
1 #import "NSObject+DefaultsObserver.h"
2 #import <AppKit/AppKit.h>
3 #import <objc/runtime.h>
4
5 @interface GBUserDefaultsObserverHelper : NSObject
6 @end
7
8 @implementation GBUserDefaultsObserverHelper
9 + (void)observeValueForKeyPath:(NSString *)keyPath
10 ofObject:(id)object
11 change:(NSDictionary<NSKeyValueChangeKey,id> *)change
12 context:(void *)context
13 {
14 [[NSNotificationCenter defaultCenter] postNotificationName:[keyPath stringByAppendingString:@"Changed$DefaultsObserver"]
15 object:nil
16 userInfo:@{
17 @"value": change[NSKeyValueChangeNewKey]
18 }];
19 }
20
21 + (void)startObservingKey:(NSString *)key
22 {
23 if (!NSThread.isMainThread) {
24 dispatch_sync(dispatch_get_main_queue(), ^{
25 [self startObservingKey:key];
26 });
27 return;
28 }
29 static NSMutableSet *set = nil;
30 if (!set) {
31 set = [NSMutableSet set];
32 }
33 if ([set containsObject:key]) return;
34 [set addObject:key];
35 [[NSUserDefaults standardUserDefaults] addObserver:(id)self
36 forKeyPath:key
37 options:NSKeyValueObservingOptionNew
38 context:nil];
39 }
40 @end
41
42 @implementation NSObject (DefaultsObserver)
43 - (void)observeStandardDefaultsKey:(NSString *)key selector:(SEL)selector
44 {
45 __weak id weakSelf = self;
46 [self observeStandardDefaultsKey:key
47 withBlock:^(id newValue) {
48 #pragma clang diagnostic push
49 #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
50 [weakSelf performSelector:selector withObject:newValue];
51 #pragma clang diagnostic pop
52 }];
53 }
54
55 - (void)observeStandardDefaultsKey:(NSString *)key withBlock:(void(^)(id newValue))block
56 {
57 NSString *notificationName = [key stringByAppendingString:@"Changed$DefaultsObserver"];
58 objc_setAssociatedObject(self, sel_registerName(notificationName.UTF8String), block, OBJC_ASSOCIATION_RETAIN);
59 [[NSNotificationCenter defaultCenter] addObserver:self
60 selector:@selector(standardDefaultsKeyChanged:)
61 name:notificationName
62 object:nil];
63 [GBUserDefaultsObserverHelper startObservingKey:key];
64 block([[NSUserDefaults standardUserDefaults] objectForKey:key]);
65 }
66
67 - (void)standardDefaultsKeyChanged:(NSNotification *)notification
68 {
69 SEL selector = sel_registerName(notification.name.UTF8String);
70 ((void(^)(id))objc_getAssociatedObject(self, selector))(notification.userInfo[@"value"]);
71 }
72 @end
This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.