Skip to content

Instantly share code, notes, and snippets.

@rnapier
Created August 13, 2012 18:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rnapier/3343133 to your computer and use it in GitHub Desktop.
Save rnapier/3343133 to your computer and use it in GitHub Desktop.
Demonstration of NSOperationQueue w/ and w/o maxCurrentOperations
#import <Foundation/Foundation.h>
#import <complex.h>
@interface JuliaOperation : NSOperation
@property (nonatomic, readwrite, assign) NSUInteger width;
@property (nonatomic, readwrite, assign) NSUInteger height;
@property (nonatomic, readwrite, assign) complex long double c;
@property (nonatomic, readwrite, assign) complex long double blowup;
@property (nonatomic, readwrite, assign) CGFloat contentScaleFactor;
@property (nonatomic, readwrite, assign) NSUInteger rScale;
@property (nonatomic, readwrite, assign) NSUInteger gScale;
@property (nonatomic, readwrite, assign) NSUInteger bScale;
@property (nonatomic, readonly, strong) UIImage *image;
@end
#import "JuliaOperation.h"
@interface JuliaOperation ()
@property (nonatomic, readwrite, strong) UIImage *image;
@end
@implementation JuliaOperation
complex long double f(const complex long double z,
const complex long double c) {
return z*z + c;
}
- (NSString *)description {
return [NSString stringWithFormat:@"(%.3f, %.3f)@%.2f",
creal(self.c), cimag(self.c), self.contentScaleFactor];
}
- (void)main {
printf("Start: %s\n", self.description.UTF8String);
NSUInteger height = self.height;
NSUInteger width = self.width;
NSUInteger components = 4;
NSMutableData *
data = [NSMutableData dataWithLength:
width * height * components * sizeof(uint8_t)];
uint8_t *bits = [data mutableBytes];
complex long double c = self.c;
long double blowup = self.blowup;
const double kScale = 1.5;
for (NSUInteger y = 0; y < height; ++y) {
for (NSUInteger x = 0; x < width; ++x) {
if (self.isCancelled) {
return;
}
NSUInteger iteration = 0;
complex long double z = (2.0 * kScale * x)/width - kScale
+ I*((2.0 * kScale * y)/width - kScale);
while (cabsl(z) < blowup && iteration < 256) {
z = f(z, c);
++iteration;
}
NSUInteger offset = (y*width*components) + (x*components);
bits[offset+0] = (iteration * self.rScale);
bits[offset+1] = (iteration * self.bScale);
bits[offset+2] = (iteration * self.gScale);
}
}
CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(bits,
width,
height,
8,
width * components,
colorspace,
kCGImageAlphaNoneSkipLast);
CGColorSpaceRelease(colorspace);
CGImageRef cgImage = CGBitmapContextCreateImage(context);
self.image = [UIImage imageWithCGImage:cgImage
scale:self.contentScaleFactor
orientation:UIImageOrientationUp];
CGImageRelease(cgImage);
CGContextRelease(context);
printf("Finish: %s\n", self.description.UTF8String);
}
@end
#import <UIKit/UIKit.h>
#import "JuliaOperation.h"
int main(int argc, char *argv[])
{
@autoreleasepool {
printf("Running\n");
CFAbsoluteTime start = CFAbsoluteTimeGetCurrent();
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
// With this, we get 2 concurrent ops; without we get 6 on iPad 3.
// queue.maxConcurrentOperationCount = 2;
CGRect bounds = CGRectMake(0, 0, 100, 100);
CGFloat scale = 2.0;
for (NSUInteger i = 0; i < 100; ++i) {
JuliaOperation *op = [[JuliaOperation alloc] init];
op.contentScaleFactor = scale;
op.width = (unsigned)(CGRectGetWidth(bounds) * scale);
op.height = (unsigned)(CGRectGetHeight(bounds) * scale);
op.c = (long double)random()/LONG_MAX + I*(long double)random()/LONG_MAX;
op.blowup = random();
op.rScale = random() % 20;
op.gScale = random() % 20;
op.bScale = random() % 20;
[queue addOperation:op];
}
[queue waitUntilAllOperationsAreFinished];
printf("time: %f\n", CFAbsoluteTimeGetCurrent() - start);
exit(0);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment