mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-22 16:33:29 +00:00
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:
parent
45763510da
commit
849ed6b9f4
5 changed files with 84 additions and 20 deletions
16
ChangeLog
16
ChangeLog
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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...) \
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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");
|
||||
|
|
Loading…
Reference in a new issue