mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-05 14:11:00 +00:00
Operation queue convenience methods
This commit is contained in:
parent
6b04eaa35c
commit
4c9c691626
4 changed files with 121 additions and 3 deletions
|
@ -36,6 +36,14 @@ extern "C" {
|
|||
|
||||
@interface NSOperationQueue (GNUstepBase)
|
||||
|
||||
/** Wraps a nil terminated list of objects in key/value pairs in a
|
||||
* dictionary and adds an operation to send a message to aTarget to
|
||||
* perform aSelector (which takes the map as its single argument).
|
||||
*/
|
||||
- (void) addOperationWithTarget: (id<NSObject>)aTarget
|
||||
performSelector: (SEL)aSelector
|
||||
withMap: (id)firstkey, ...;
|
||||
|
||||
- (void) addOperationWithTarget: (id<NSObject>)aTarget
|
||||
performSelector: (SEL)aSelector
|
||||
withObject: (id<NSObject>)object1
|
||||
|
|
|
@ -22,9 +22,12 @@
|
|||
|
||||
*/
|
||||
#import "../common.h"
|
||||
#import "Foundation/NSDictionary.h"
|
||||
#import "Foundation/NSException.h"
|
||||
#import "Foundation/NSMapTable.h"
|
||||
#import "Foundation/NSObject.h"
|
||||
#import "Foundation/NSOperation.h"
|
||||
#import "GNUstepBase/GSObjCRuntime.h"
|
||||
#import "GNUstepBase/NSOperationQueue+GNUstepBase.h"
|
||||
|
||||
|
||||
|
@ -72,6 +75,23 @@
|
|||
*/
|
||||
@implementation NSOperationQueue (GNUstepBase)
|
||||
|
||||
- (void) addOperationWithTarget: (id<NSObject>)aTarget
|
||||
performSelector: (SEL)aSelector
|
||||
withMap: (id)firstKey, ...
|
||||
{
|
||||
GSTargetOperation *top;
|
||||
NSDictionary *map;
|
||||
|
||||
map = [NSDictionary alloc];
|
||||
GS_USEIDPAIRLIST(firstKey,
|
||||
map = [map initWithObjects: __pairs forKeys: __objects count: __count/2]);
|
||||
|
||||
top = [GSTargetOperation operationWithTarget: aTarget
|
||||
performSelector: aSelector
|
||||
withObject: AUTORELEASE(map)];
|
||||
[self addOperation: top];
|
||||
}
|
||||
|
||||
- (void) addOperationWithTarget: (id<NSObject>)aTarget
|
||||
performSelector: (SEL)aSelector
|
||||
withObject: (id<NSObject>)object1
|
||||
|
|
|
@ -105,6 +105,10 @@ int main()
|
|||
NSOperationQueue *q;
|
||||
int i;
|
||||
NSMutableArray *a;
|
||||
NSTimeInterval s;
|
||||
NSTimeInterval f;
|
||||
NSUInteger ran;
|
||||
NSUInteger want;
|
||||
# if __has_feature(blocks)
|
||||
__block BOOL blockDidRun = NO;
|
||||
#endif
|
||||
|
@ -128,23 +132,32 @@ int main()
|
|||
[obj release];
|
||||
|
||||
// multiple concurrent operations
|
||||
s = [NSDate timeIntervalSinceReferenceDate];
|
||||
[q setMaxConcurrentOperationCount: 10];
|
||||
a = [NSMutableArray array];
|
||||
for (i = 0; i < 5; ++i)
|
||||
want = 200;
|
||||
ran = 0;
|
||||
for (i = 0; i < want; ++i)
|
||||
{
|
||||
obj = [[MyOperation alloc] initWithValue: i];
|
||||
[a addObject: obj];
|
||||
[q addOperation: obj];
|
||||
}
|
||||
[q waitUntilAllOperationsAreFinished];
|
||||
f = [NSDate timeIntervalSinceReferenceDate];
|
||||
PASS(([obj isFinished] == YES), "operation ran");
|
||||
PASS(([obj isExecuting] == NO), "operation is not executing");
|
||||
|
||||
for (i = 0; i < 5; ++i)
|
||||
for (i = 0; i < want; ++i)
|
||||
{
|
||||
obj = [a objectAtIndex: i];
|
||||
PASS(([obj getCalculation] == (2*i)), "operation was performed");
|
||||
if ([obj getCalculation] == (2*i))
|
||||
{
|
||||
ran++;
|
||||
}
|
||||
}
|
||||
PASS((ran == want), "many operations, all were performed")
|
||||
PASS((f - s) < 0.1, "many operations, duration was reasonably small")
|
||||
|
||||
// multiple concurrent operations
|
||||
[q setMaxConcurrentOperationCount: 5];
|
||||
|
|
77
Tests/base/NSOperation/perform.m
Normal file
77
Tests/base/NSOperation/perform.m
Normal file
|
@ -0,0 +1,77 @@
|
|||
#import <Foundation/Foundation.h>
|
||||
#import <GNUstepBase/NSOperationQueue+GNUstepBase.h>
|
||||
#import "ObjectTesting.h"
|
||||
|
||||
@interface MyClass : NSObject
|
||||
{
|
||||
unsigned counter;
|
||||
}
|
||||
- (void) count: (NSMapTable*)map;
|
||||
- (unsigned) counter;
|
||||
- (void) increment;
|
||||
- (void) reset;
|
||||
@end
|
||||
|
||||
@implementation MyClass
|
||||
- (void) count: (NSDictionary*)map
|
||||
{
|
||||
unsigned c = [map count];
|
||||
|
||||
// NSLog(@"Count %u for %@", c, map);
|
||||
counter += c;
|
||||
}
|
||||
- (unsigned) counter
|
||||
{
|
||||
return counter;
|
||||
}
|
||||
- (void) increment
|
||||
{
|
||||
counter = counter + 1;
|
||||
}
|
||||
- (void) reset
|
||||
{
|
||||
counter = 0;
|
||||
}
|
||||
@end
|
||||
|
||||
int main()
|
||||
{
|
||||
ENTER_POOL
|
||||
NSOperationQueue *q;
|
||||
NSUInteger i;
|
||||
NSUInteger ran;
|
||||
NSUInteger want;
|
||||
NSTimeInterval s;
|
||||
NSTimeInterval f;
|
||||
MyClass *o = AUTORELEASE([[MyClass alloc] init]);
|
||||
|
||||
q = AUTORELEASE([[NSOperationQueue alloc] init]);
|
||||
[q setMaxConcurrentOperationCount: 1];
|
||||
|
||||
ran = 0;
|
||||
want = 200;
|
||||
s = [NSDate timeIntervalSinceReferenceDate];
|
||||
for (i = 0; i < want; i++)
|
||||
{
|
||||
[q addOperationWithTarget: o
|
||||
performSelector: @selector(increment)];
|
||||
}
|
||||
[q waitUntilAllOperationsAreFinished];
|
||||
f = [NSDate timeIntervalSinceReferenceDate];
|
||||
PASS([o counter] == want, "expected number of operations")
|
||||
PASS((f - s) < 0.1, "duration was reasonable")
|
||||
|
||||
[o reset];
|
||||
[q addOperationWithTarget: o
|
||||
performSelector: @selector(count:)
|
||||
withMap:
|
||||
@"Key1", @"Val1",
|
||||
@"Key2", @"Val2",
|
||||
@"Key3", @"Val3",
|
||||
nil];
|
||||
[q waitUntilAllOperationsAreFinished];
|
||||
PASS([o counter] == 3, "map had three keys")
|
||||
|
||||
LEAVE_POOL
|
||||
return 0;
|
||||
}
|
Loading…
Reference in a new issue