Fixed: OperationQueue for the CPNotificationCenter is not ignored anymore

Previously, the operationQueue given to the notificationCenter was ignored.

Tests in CPNotificationCenterTest.j
This commit is contained in:
Alexandre Wilhelm committed 2015-10-08 11:23:07 -07:00
1 parent 54e1efd794
commit 3e29732e46
2 files changed
+102 -8

No files matched your search

+51 -8
View File
@@ -25,6 +25,8 @@
@import "CPException.j"
@import "CPNotification.j"
@import "CPNull.j"
@import "CPOperationQueue.j"
@import "CPOperation.j"
@import "CPSet.j"
@class _CPNotificationRegistry
@@ -94,13 +96,13 @@ var CPNotificationDefaultCenter = nil;
Adds an entry to the receiver’s dispatch table with a block, and optional criteria: notification name and sender.
@param aNotificationName the name of the notification the observer wants to watch
@param anObject the object in the notification the observer wants to watch
@param queue is ignored for the moment
@param The operation queue to which block should be added. If you pass nil, the block is run synchronously on the posting thread.
@param block the block to be executed when the notification is received.
*/
- (id <CPObject>)addObserverForName:(CPString)aNotificationName object:(id)anObject queue:(id)queue usingBlock:(Function)block
- (id <CPObject>)addObserverForName:(CPString)aNotificationName object:(id)anObject queue:(CPOperationQueue)queue usingBlock:(Function)block
{
var registry = [self _registryForNotificationName:aNotificationName],
observer = [[_CPNotificationObserver alloc] initWithBlock:block];
observer = [[_CPNotificationObserver alloc] initWithBlock:block queue:queue];
[registry addObserver:observer object:anObject];
@@ -344,9 +346,10 @@ var _CPNotificationCenterPostNotification = function(/* CPNotificationCenter */
/* @ignore */
@implementation _CPNotificationObserver : CPObject
{
id _observer;
Function _block;
SEL _selector;
CPOperationQueue _operationQueue;
id _observer;
Function _block;
SEL _selector;
}
- (id)initWithObserver:(id)anObserver selector:(SEL)aSelector
@@ -360,11 +363,12 @@ var _CPNotificationCenterPostNotification = function(/* CPNotificationCenter */
return self;
}
- (id)initWithBlock:(Function)aBlock
- (id)initWithBlock:(Function)aBlock queue:(CPOperationQueue)aQueue
{
if (self)
{
_block = aBlock;
_operationQueue = aQueue;
}
return self;
@@ -384,7 +388,11 @@ var _CPNotificationCenterPostNotification = function(/* CPNotificationCenter */
{
if (_block)
{
_block(aNotification);
if (!_operationQueue)
_block(aNotification);
else
[_operationQueue addOperation:[[_CPNotificationObserverOperation alloc] initWithBlock:_block notification:aNotification]];
return;
}
@@ -392,3 +400,38 @@ var _CPNotificationCenterPostNotification = function(/* CPNotificationCenter */
}
@end
/* @ignore */
@implementation _CPNotificationObserverOperation : CPOperation
{
CPNotification _notification;
Function _block;
}
/* @ignore */
- (id)initWithBlock:(Function)aBlock notification:(CPNotification)aNotification
{
self = [super init];
if (self)
{
_block = aBlock;
_notification = aNotification;
}
return self;
}
/* @ignore */
- (void)main
{
_block(_notification);
}
/* @ignore */
- (BOOL)isReady
{
return YES;
}
@end
@@ -97,6 +97,57 @@ var TestNotification = @"TestNotification";
[self assert:7 equals:notificationCount message:@"observer should not be notified"];
}
- (void)testNotifyWithBlocksAndOperationQueue
{
var center = [CPNotificationCenter defaultCenter],
queue = [[CPOperationQueue alloc] init];
notificationCount = 0;
var notificationBlock = function(notification){
notificationCount += 1;
};
var observer2 = [center addObserverForName:TestNotification object:2 queue:queue usingBlock:notificationBlock],
observer25 = [center addObserverForName:TestNotification object:25 queue:queue usingBlock:notificationBlock];
[center postNotificationName:TestNotification object:self];
[center postNotificationName:TestNotification object:2];
[queue waitUntilAllOperationsAreFinished];
[self assert:1 equals:notificationCount message:@"observer should be notified for object '2'"];
var observerNil = [center addObserverForName:TestNotification object:nil queue:queue usingBlock:notificationBlock];
[center postNotificationName:TestNotification object:2];
[queue waitUntilAllOperationsAreFinished];
[self assert:3 equals:notificationCount message:@"observer should be notified for object '2' and for any object"];
[center removeObserver:observer2 name:TestNotification object:2];
[center postNotificationName:TestNotification object:2];
[queue waitUntilAllOperationsAreFinished];
[self assert:4 equals:notificationCount message:@"observer should be notified only for any object"];
// At this point we have TestNofication:nil observer and a TestNotification:25 observer.
observer2 = [center addObserverForName:nil object:2 queue:queue usingBlock:notificationBlock];
[center postNotificationName:TestNotification object:2];
[queue waitUntilAllOperationsAreFinished];
[self assert:6 equals:notificationCount message:@"observer should be notified for TestNofication and for object '2' (TestNotification)"];
[center postNotificationName:@"RandomNotification" object:2];
[queue waitUntilAllOperationsAreFinished];
[self assert:7 equals:notificationCount message:@"observer should be notified for object '2' (RandomNotification)"];
[center removeObserver:observer2];
[center removeObserver:observer25];
[center removeObserver:observerNil];
[center postNotificationName:TestNotification object:nil];
[center postNotificationName:TestNotification object:2];
[center postNotificationName:TestNotification object:25];
[queue waitUntilAllOperationsAreFinished];
[self assert:7 equals:notificationCount message:@"observer should not be notified"];
}
- (void)testAddObserversDuringNotification
{
var center = [CPNotificationCenter defaultCenter];