Add completion block support to NSOperation.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@34996 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
thebeing 2012-03-26 14:47:07 +00:00
parent 45763510da
commit 849ed6b9f4
5 changed files with 84 additions and 20 deletions

View file

@ -1,3 +1,11 @@
2012-03-26 Niels Grewe <niels.grewe@halbordnung.de>
* Headers/Foundation/NSOperation.h
* Source/NSOperation.m:
Implement -setCompletionBlock: and -completionBlock.
* Headers/GNUstepBase/GSBlocks: Make blocks without arguments callable
* Tests/base/NSOperation/basic.m: Test whether completion blocks work.
2012-03-25 Richard Frith-Macdonald <rfm@gnu.org>
* Source/NSXMLPrivate.h: Change order of includes to ensure libxml2
@ -56,6 +64,14 @@
abort configuration unless specifically disabled ... we want a
consistent build with all major features.
2012-03-20 Niels Grewe <niels.grewe@halbordnung.de>
* Headers/Foundation/NSDictionary.h
* Source/NSDictionary.m:
Implement blocks related enumeration methods.
* Tests/base/NSDictionary/blocks.m:
Test cases for blocks support.
2012-03-20 Niels Grewe <niels.grewe@halbordnung.de>
* Headers/Foundation/NSObjCRuntime.h: Define NS_REQUIRES_NIL_TERMINATION
macro.

View file

@ -4,31 +4,31 @@
Written by: Gregory Casamento <greg.casamento@gmail.com>
Written by: Richard Frith-Macdonald <rfm@gnu.org>
Date: 2009,2010
This file is part of the GNUstep Base Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02111 USA.
*/
*/
#ifndef __NSOperation_h_GNUSTEP_BASE_INCLUDE
#define __NSOperation_h_GNUSTEP_BASE_INCLUDE
#import <Foundation/NSObject.h>
#import <GNUstepBase/GSBlocks.h>
#if OS_API_VERSION(100500, GS_API_LATEST)
#if defined(__cplusplus)
@ -149,6 +149,14 @@ typedef NSInteger NSOperationQueuePriority;
* The valid range is 0.0 to 1.0
*/
- (void) setThreadPriority: (double)prio;
DEFINE_BLOCK_TYPE(GSOperationCompletionBlock, void, void);
/**
* Sets the block that will be executed when the operation has finished.
*/
- (void)setCompletionBlock: (GSOperationCompletionBlock)aBlock;
#endif
/** This method is called to start execution of the receiver.<br />
@ -177,6 +185,11 @@ typedef NSInteger NSOperationQueuePriority;
* from the same thread that the receiver started in.
*/
- (void) waitUntilFinished;
/**
* Returns the block that will be executed after the operation finishes.
*/
- (GSOperationCompletionBlock)completionBlock;
#endif
@end

View file

@ -7,24 +7,24 @@
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02111 USA.
*/
*/
#ifndef __GSBlocks_h_GNUSTEP_BASE_INCLUDE
#define __GSBlocks_h_GNUSTEP_BASE_INCLUDE
/* Define the has_feature pseudo-macro for GCC. */
#ifndef __has_feature
#ifndef __has_feature
#define __has_feature(x) 0
#endif
@ -41,6 +41,10 @@ typedef retTy(^name)(argTys, ## __VA_ARGS__)
*/
#define CALL_BLOCK(block, args, ...) block(args, ## __VA_ARGS__)
/**
* Calls a block without arguments.
*/
#define CALL_BLOCK_NO_ARGS(block) block()
#else
/* Fall-back versions for when the compiler doesn't have native blocks support.
@ -57,6 +61,8 @@ typedef retTy(^name)(argTys, ## __VA_ARGS__)
#define CALL_BLOCK(block, args, ...) block->invoke(block, args, ## __VA_ARGS__)
#define CALL_BLOCK_NO_ARGS(block) block->invoke()
#else /* GCC_VERSION >= 3000 */
#define DEFINE_BLOCK_TYPE(name, retTy, argTys, args...) \

View file

@ -4,19 +4,19 @@
Written by: Gregory Casamento <greg.casamento@gmail.com>
Written by: Richard Frith-Macdonald <rfm@gnu.org>
Date: 2009,2010
This file is part of the GNUstep Base Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
@ -24,7 +24,7 @@
<title>NSOperation class reference</title>
$Date: 2008-06-08 11:38:33 +0100 (Sun, 08 Jun 2008) $ $Revision: 26606 $
*/
*/
#import "common.h"
@ -41,7 +41,8 @@
BOOL finished; \
BOOL blocked; \
BOOL ready; \
NSMutableArray *dependencies;
NSMutableArray *dependencies; \
GSOperationCompletionBlock completionBlock
#define GS_NSOperationQueue_IVARS \
NSRecursiveLock *lock; \
@ -396,6 +397,18 @@ static NSArray *empty = nil;
internal->threadPriority = pri;
}
- (void) setCompletionBlock:(GSOperationCompletionBlock)aBlock
{
ASSIGN(internal->completionBlock, aBlock);
GSPrintf(stderr, @"Setting block: %p", internal->completionBlock);
}
- (GSOperationCompletionBlock)completionBlock
{
return internal->completionBlock;
}
- (void) start
{
NSAutoreleasePool *pool = [NSAutoreleasePool new];
@ -524,6 +537,11 @@ static NSArray *empty = nil;
internal->finished = YES;
[self didChangeValueForKey: @"isFinished"];
}
if (NULL != internal->completionBlock)
{
GSPrintf(stderr, @"Calling block: %p", internal->completionBlock);
CALL_BLOCK_NO_ARGS(internal->completionBlock);
}
}
[internal->lock unlock];
[self release];
@ -554,7 +572,7 @@ sortFunc(id o1, id o2, void *ctxt)
{
NSOperationQueuePriority p1 = [o1 queuePriority];
NSOperationQueuePriority p2 = [o2 queuePriority];
if (p1 < p2) return NSOrderedDescending;
if (p1 > p2) return NSOrderedAscending;
return NSOrderedSame;

View file

@ -4,6 +4,12 @@
#import "ObjectTesting.h"
# ifndef __has_feature
# define __has_feature(x) 0
# endif
static BOOL blockDidRun = NO;
int main()
{
id obj1;
@ -11,12 +17,12 @@ int main()
NSMutableArray *testObjs = [[NSMutableArray alloc] init];
NSAutoreleasePool *arp = [NSAutoreleasePool new];
test_alloc(@"NSOperation");
test_alloc(@"NSOperation");
obj1 = [NSOperation new];
PASS((obj1 != nil), "can create an operation");
[testObjs addObject: obj1];
test_NSObject(@"NSOperation", testObjs);
PASS(([obj1 isReady] == YES), "operation is ready");
PASS(([obj1 isConcurrent] == NO), "operation is not concurrent");
PASS(([obj1 isCancelled] == NO), "operation is not cancelled");
@ -51,11 +57,16 @@ int main()
obj1 = [NSOperation new];
[testObjs replaceObjectAtIndex: 0 withObject: obj1];
[obj2 addDependency: obj1];
# if __has_feature(blocks)
[obj1 setCompletionBlock: ^(void){blockDidRun = YES;}];
# endif
[obj1 start];
[NSThread sleepForTimeInterval: 1.0];
PASS(([obj1 isFinished] == YES), "operation is finished");
PASS(([obj1 isReady] == YES), "a finished operation is ready");
# if __has_feature(blocks)
PASS(YES == blockDidRun, "completion block is executed");
# endif
PASS(([[obj2 dependencies] isEqual: testObjs]),
"finished dependency continues");
PASS(([obj2 isReady] == YES), "operation with finished dependency is ready");
@ -80,13 +91,13 @@ int main()
PASS(([obj2 waitUntilFinished], YES), "wait returns at once");
test_alloc(@"NSOperationQueue");
test_alloc(@"NSOperationQueue");
obj1 = [NSOperationQueue new];
PASS((obj1 != nil), "can create an operation queue");
[testObjs removeAllObjects];
[testObjs addObject: obj1];
test_NSObject(@"NSOperationQueue", testObjs);
PASS(([obj1 isSuspended] == NO), "not suspended by default");
[obj1 setSuspended: YES];
PASS(([obj1 isSuspended] == YES), "set suspended yes");