Permalink
Browse files

initial commit

  • Loading branch information...
0 parents commit 7e5ff6a549394b32bed3e96ff37d07fc946dcb3a @mikeash committed Jul 6, 2011
Showing with 119 additions and 0 deletions.
  1. +1 −0 .gitignore
  2. +15 −0 MANotificationCenter.h
  3. +74 −0 MANotificationCenter.m
  4. +29 −0 main.m
@@ -0,0 +1 @@
+a.out
@@ -0,0 +1,15 @@
+
+#import <Foundation/Foundation.h>
+
+
+@interface MANotificationCenter : NSObject
+{
+ CFMutableDictionaryRef _objectsDict;
+}
+
+- (id)addObserverForName: (NSString *)name object: (id)object block: (void (^)(NSNotification *note))block;
+- (void)removeObserver: (id)observer;
+
+- (void)postNotification: (NSNotification *)note;
+
+@end
@@ -0,0 +1,74 @@
+
+#import "MANotificationCenter.h"
+
+
+@implementation MANotificationCenter
+
+- (id)init
+{
+ if((self = [super init]))
+ {
+ _objectsDict = CFDictionaryCreateMutable(NULL, 0, NULL, &kCFTypeDictionaryValueCallBacks);
+ }
+ return self;
+}
+
+- (void)dealloc
+{
+ CFRelease(_objectsDict);
+ [super dealloc];
+}
+
+- (id)addObserverForName: (NSString *)name object: (id)object block: (void (^)(NSNotification *note))block
+{
+ NSMutableDictionary *innerDict = (id)CFDictionaryGetValue(_objectsDict, object);
+ if(!innerDict)
+ {
+ innerDict = [NSMutableDictionary dictionary];
+ CFDictionarySetValue(_objectsDict, object, innerDict);
+ }
+
+ NSMutableSet *observerBlocks = [innerDict objectForKey: name];
+ if(!observerBlocks)
+ {
+ observerBlocks = [NSMutableSet set];
+ [innerDict setObject: observerBlocks forKey: name];
+ }
+
+ void (^copiedBlock)(NSNotification *note);
+ copiedBlock = [block copy];
+
+ [observerBlocks addObject: copiedBlock];
+
+ [copiedBlock release];
+
+ __block id weakObject = object;
+ void (^removalBlock)(void) = ^{
+ NSMutableDictionary *innerDict = (id)CFDictionaryGetValue(_objectsDict, weakObject);
+ NSMutableSet *observerBlocks = [innerDict objectForKey: name];
+ [observerBlocks removeObject: copiedBlock];
+ if([observerBlocks count] == 0)
+ [innerDict removeObjectForKey: name];
+ if([innerDict count] == 0)
+ CFDictionaryRemoveValue(_objectsDict, weakObject);
+ };
+
+ return [[removalBlock copy] autorelease];
+}
+
+- (void)removeObserver: (id)observer
+{
+ void (^removalBlock)(void) = observer;
+ removalBlock();
+}
+
+- (void)postNotification: (NSNotification *)note
+{
+ NSDictionary *innerDict = (id)CFDictionaryGetValue(_objectsDict, [note object]);
+ NSSet *observerBlocks = [innerDict objectForKey: [note name]];
+ for(void (^block)(NSNotification *) in observerBlocks)
+ block(note);
+}
+
+@end
+
29 main.m
@@ -0,0 +1,29 @@
+// gcc -framework Foundation main.m MANotificationCenter.m
+
+#import "MANotificationCenter.h"
+
+
+int main(int argc, char **argv)
+{
+ [NSAutoreleasePool new];
+
+ MANotificationCenter *center = [[MANotificationCenter alloc] init];
+
+ id obj = [[NSObject alloc] init];
+ id otherObj = [[NSObject alloc] init];
+ [center addObserverForName: @"name" object: obj block: ^(NSNotification *note) {
+ NSLog(@"First block got notification %@", note);
+ }];
+ [center addObserverForName: @"name" object: obj block: ^(NSNotification *note) {
+ NSLog(@"Second block got notification %@", note);
+ }];
+ [center addObserverForName: @"othername" object: obj block: ^(NSNotification *note) {
+ NSLog(@"Third block got notification %@", note);
+ }];
+ [center addObserverForName: @"name" object: otherObj block: ^(NSNotification *note) {
+ NSLog(@"Fourth block got notification %@", note);
+ }];
+
+ [center postNotification: [NSNotification notificationWithName: @"name" object: obj]];
+}
+

0 comments on commit 7e5ff6a

Please sign in to comment.