Permalink
Browse files

Added Concurrency

  • Loading branch information...
1 parent 77d1eaf commit baffaa48369958eee6c4089637bc4423346d30ac @cneuwirt committed Feb 9, 2014
Showing with 4,518 additions and 8 deletions.
  1. +172 −0 Miruken.xcodeproj/project.pbxproj
  2. +10 −0 Miruken.xcworkspace/xcuserdata/cneuwirt.xcuserdatad/WorkspaceSettings.xcsettings
  3. +18 −0 Miruken/Concurrency/Concurrency.h
  4. +21 −0 Miruken/Concurrency/MKAction.h
  5. +25 −0 Miruken/Concurrency/MKAction.m
  6. +26 −0 Miruken/Concurrency/MKAsyncDelegate.h
  7. +28 −0 Miruken/Concurrency/MKAsyncDelegate.m
  8. +32 −0 Miruken/Concurrency/MKAsyncObject.h
  9. +94 −0 Miruken/Concurrency/MKAsyncObject.m
  10. +23 −0 Miruken/Concurrency/MKAsyncProxyResult.h
  11. +102 −0 Miruken/Concurrency/MKAsyncProxyResult.m
  12. +39 −0 Miruken/Concurrency/MKAsyncResult.h
  13. +142 −0 Miruken/Concurrency/MKAsyncResult.m
  14. +44 −0 Miruken/Concurrency/MKBufferedPromise.h
  15. +269 −0 Miruken/Concurrency/MKBufferedPromise.m
  16. +54 −0 Miruken/Concurrency/MKConcurrency.h
  17. +55 −0 Miruken/Concurrency/MKDeferred.h
  18. +989 −0 Miruken/Concurrency/MKDeferred.m
  19. +21 −0 Miruken/Concurrency/MKDelayedDelegate.h
  20. +56 −0 Miruken/Concurrency/MKDelayedDelegate.m
  21. +27 −0 Miruken/Concurrency/MKGrandCentralDispatchDelegate.h
  22. +57 −0 Miruken/Concurrency/MKGrandCentralDispatchDelegate.m
  23. +22 −0 Miruken/Concurrency/MKMainThreadDelegate.h
  24. +53 −0 Miruken/Concurrency/MKMainThreadDelegate.m
  25. +19 −0 Miruken/Concurrency/MKNewThreadDelegate.h
  26. +33 −0 Miruken/Concurrency/MKNewThreadDelegate.m
  27. +21 −0 Miruken/Concurrency/MKOperationProxyResult.h
  28. +34 −0 Miruken/Concurrency/MKOperationProxyResult.m
  29. +24 −0 Miruken/Concurrency/MKOperationQueueDelegate.h
  30. +58 −0 Miruken/Concurrency/MKOperationQueueDelegate.m
  31. +23 −0 Miruken/Concurrency/MKOperationResult.h
  32. +34 −0 Miruken/Concurrency/MKOperationResult.m
  33. +87 −0 Miruken/Concurrency/MKPromise.h
  34. +24 −0 Miruken/Concurrency/MKScheduledPromise.h
  35. +275 −0 Miruken/Concurrency/MKScheduledPromise.m
  36. +20 −0 Miruken/Concurrency/MKSynchronousResult.h
  37. +68 −0 Miruken/Concurrency/MKSynchronousResult.m
  38. +19 −0 Miruken/Concurrency/MKThreadDelegate.h
  39. +39 −0 Miruken/Concurrency/MKThreadDelegate.m
  40. +49 −0 Miruken/Concurrency/NSObject+Concurrency.h
  41. +232 −0 Miruken/Concurrency/NSObject+Concurrency.m
  42. +16 −0 Miruken/Concurrency/NSObject+Promise.h
  43. +21 −0 Miruken/Concurrency/NSObject+Promise.m
  44. +19 −0 Miruken/Core/NSInvocation+Objects.h
  45. +32 −0 Miruken/Core/NSInvocation+Objects.m
  46. +1 −1 Miruken/Miruken.h
  47. +268 −0 MirukenTests/Concurrency/MKBufferedPromiseTests.m
  48. +723 −0 MirukenTests/Concurrency/MKDeferredTests.m
  49. +0 −7 MirukenTests/MirukenTests.m

Large diffs are not rendered by default.

Oops, something went wrong.
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>HasAskedToTakeAutomaticSnapshotBeforeSignificantChanges</key>
+ <true/>
+ <key>SnapshotAutomaticallyBeforeSignificantChanges</key>
+ <false/>
+</dict>
+</plist>
@@ -0,0 +1,18 @@
+//
+// Concurrency.h
+// Miruken
+//
+// Created by Craig Neuwirt on 2/9/14.
+// Copyright (c) 2014 Craig Neuwirt. All rights reserved.
+//
+
+#import "MKAction.h"
+#import "MKAsyncDelegate.h"
+#import "MKAsyncObject.h"
+#import "MKAsyncResult.h"
+#import "MKBufferedPromise.h"
+#import "MKConcurrency.h"
+#import "MKDeferred.h"
+#import "MKPromise.h"
+#import "NSObject+Concurrency.h"
+#import "NSObject+Promise.h"
@@ -0,0 +1,21 @@
+//
+// MKAction.h
+// Miruken
+//
+// Created by Craig Neuwirt on 2/7/14.
+// Copyright (c) 2014 Craig Neuwirt. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+/**
+ An Action executes an objective-C block so it can leverage concurrency.
+ */
+
+@interface MKAction : NSObject
+
++ (void)do:(dispatch_block_t)action;
+
+- (void)do:(dispatch_block_t)action;
+
+@end
@@ -0,0 +1,25 @@
+//
+// MKAction.m
+// Miruken
+//
+// Created by Craig Neuwirt on 2/7/14.
+// Copyright (c) 2014 Craig Neuwirt. All rights reserved.
+//
+
+#import "MKAction.h"
+
+@implementation MKAction
+
++ (void)do:(dispatch_block_t)action
+{
+ if (action)
+ action();
+}
+
+- (void)do:(dispatch_block_t)action
+{
+ if (action)
+ action();
+}
+
+@end
@@ -0,0 +1,26 @@
+//
+// MKAsyncDelegate.h
+// Miruken
+//
+// Created by Craig Neuwirt on 10/24/12.
+// Copyright (c) 2014 Craig Neuwirt. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import "MKAsyncResult.h"
+
+/**
+ This protocol encapsulates the concurrency strategy for invocation execution.
+ */
+
+@protocol MKAsyncDelegate <NSObject>
+
+- (id<MKAsyncResult>)asyncResultForInvocation:(NSInvocation *)invocation;
+
+- (void)completeResult:(id<MKAsyncResult>)asyncResult;
+
+@end
+
+@interface MKAsyncDelegate : NSObject <MKAsyncDelegate>
+
+@end
@@ -0,0 +1,28 @@
+//
+// MKAsyncDelegate.m
+// Miruken
+//
+// Created by Craig Neuwirt on 10/24/12.
+// Copyright (c) 2014 Craig Neuwirt. All rights reserved.
+//
+
+#import "MKAsyncDelegate.h"
+#import "MKAsyncResult.h"
+#import "MKAsyncProxyResult.h"
+#import "NSInvocation+Objects.h"
+
+@implementation MKAsyncDelegate
+
+- (id<MKAsyncResult>)asyncResultForInvocation:(NSInvocation *)invocation
+{
+ return [invocation returnsObject]
+ ? (id)[[MKAsyncProxyResult alloc] initWithInvocation:invocation]
+ : (id)[[MKAsyncResult alloc] initWithInvocation:invocation];
+}
+
+- (void)completeResult:(id<MKAsyncResult>)asyncResult
+{
+ [asyncResult complete];
+}
+
+@end
@@ -0,0 +1,32 @@
+//
+// MKAsyncObject.h
+// Miruken
+//
+// Created by Craig Neuwirt on 10/23/12.
+// Copyright (c) 2014 Craig Neuwirt. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import "MKAsyncDelegate.h"
+#import "MKAsyncResult.h"
+
+/**
+ This class is a proxy that adds concurrency behaviors to an object.
+ The concurrency details are determined by the AsyncDelegate.
+ */
+
+@protocol MKAsyncObject
+
+- (id)outAsyncResult:(id<MKAsyncResult> __autoreleasing *)outAsyncResult;
+
+- (id)weak;
+
+@end
+
+@interface MKAsyncObject : NSProxy <MKAsyncObject>
+
+- (id)initWithClass:(Class)aClass delegate:(id<MKAsyncDelegate>)delegate;
+
+- (id)initWithObject:(id)anObject delegate:(id<MKAsyncDelegate>)delegate;
+
+@end
@@ -0,0 +1,94 @@
+//
+// MKAsyncObject.m
+// Miruken
+//
+// Created by Craig Neuwirt on 10/23/12.
+// Copyright (c) 2014 Craig Neuwirt. All rights reserved.
+//
+
+#import "MKAsyncObject.h"
+#import "MKAsyncResult.h"
+
+@implementation MKAsyncObject
+{
+ id _target;
+ __weak id _weakTarget;
+ id<MKAsyncDelegate> _delegate;
+ id<MKAsyncResult> _asyncResult;
+ __autoreleasing id<MKAsyncResult> *_outAsyncResult;
+}
+
+- (id)initWithClass:(Class)aClass delegate:(id<MKAsyncDelegate>)delegate
+{
+ return [self initWithObject:[[aClass alloc] init] delegate:delegate];
+}
+
+- (id)initWithObject:(id)anObject delegate:(id<MKAsyncDelegate>)delegate
+{
+ _target = anObject;
+ _delegate = delegate;
+ _outAsyncResult = nil;
+ return self;
+}
+
+- (id)outAsyncResult:(id<MKAsyncResult> __autoreleasing *)outAsyncResult
+{
+ _outAsyncResult = outAsyncResult;
+ return self;
+}
+
+- (id)weak
+{
+ _weakTarget = _target;
+ _target = nil;
+ return self;
+}
+
+- (id<MKAsyncResult>)asyncResult
+{
+ return _asyncResult;
+}
+
+- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector
+{
+ return _target
+ ? [_target methodSignatureForSelector:selector]
+ : [_weakTarget methodSignatureForSelector:selector];
+}
+
+- (void)forwardInvocation:(NSInvocation *)invocation
+{
+ id<MKAsyncResult> asyncResult = [_delegate asyncResultForInvocation:invocation];
+
+ if (_outAsyncResult)
+ {
+ *_outAsyncResult = asyncResult;
+ _outAsyncResult = nil;
+ }
+
+ if ([asyncResult isProxyResult])
+ {
+ _asyncResult = asyncResult;
+ SEL selector = [invocation selector];
+ [invocation setSelector:@selector(asyncResult)];
+ [invocation invokeWithTarget:self];
+ [invocation setSelector:selector];
+ _asyncResult = nil;
+ }
+
+ [invocation setTarget:_target ? _target : _weakTarget];
+
+ if (invocation.argumentsRetained == NO)
+ [invocation retainArguments];
+
+ [_delegate completeResult:asyncResult];
+}
+
+- (void)dealloc
+{
+ _delegate = nil;
+ _asyncResult = nil;
+ _outAsyncResult = nil;
+}
+
+@end
@@ -0,0 +1,23 @@
+//
+// MKAsyncProxyResult.h
+// Miruken
+//
+// Created by Craig Neuwirt on 10/23/12.
+// Copyright (c) 2014 Craig Neuwirt. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import "MKAsyncResult.h"
+
+/**
+ Extends to the AsyncResult protocol to present the asynchronous
+ result as a proxy when the result is an object (id).
+ Accessing any members of this proxy will block until the actual result
+ is available.
+ */
+
+@interface MKAsyncProxyResult : NSProxy <MKAsyncResult>
+
+- (id)initWithInvocation:(NSInvocation *)invocation;
+
+@end
@@ -0,0 +1,102 @@
+//
+// MKAsyncProxyResultm
+// Miruken
+//
+// Created by Craig Neuwirt on 10/23/12.
+// Copyright (c) 2014 Craig Neuwirt. All rights reserved.
+//
+
+#import "MKAsyncProxyResult.h"
+#import "MKDeferred.h"
+#import "NSInvocation+Objects.h"
+
+@implementation MKAsyncProxyResult
+{
+ id _result;
+ NSException *_exception;
+ NSInvocation *_invocation;
+ MKDeferred *_deferred;
+ NSArray *_blockArguments;
+}
+
+- (id)initWithInvocation:(NSInvocation *)invocation
+{
+ _invocation = invocation;
+ _deferred = [MKDeferred new];
+ _blockArguments = [MKAsyncResult copyBlockArguments:invocation];
+ return self;
+}
+
+- (BOOL)isComplete
+{
+ return _deferred.state != DeferredStatePending;
+}
+
+- (BOOL)isProxyResult
+{
+ return YES;
+}
+
+- (void)complete
+{
+ if (_deferred.state != DeferredStatePending)
+ return;
+
+ @try
+ {
+ [_invocation invoke];
+ _result = [_invocation objectReturnValue];
+ [_deferred resolve:_result];
+ }
+ @catch (NSException *exception)
+ {
+ _exception = exception;
+ [_deferred reject:_exception];
+ }
+ @finally
+ {
+ _invocation = nil;
+ }
+}
+
+- (id)result
+{
+ [_deferred wait];
+
+ if (_exception)
+ {
+ [_exception raise];
+ return nil;
+ }
+
+ return _result;
+}
+
+- (id<MKPromise>)promise
+{
+ return [_deferred promise];
+}
+
+- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
+{
+ if (_deferred.state == DeferredStatePending)
+ [self result];
+ return _result
+ ? [_result methodSignatureForSelector:aSelector]
+ : [NSMethodSignature signatureWithObjCTypes:"v@"];
+}
+
+- (void)forwardInvocation:(NSInvocation *)anInvocation
+{
+ if (_deferred.state == DeferredStatePending)
+ [self result];
+ if (_result)
+ [anInvocation invokeWithTarget:_result];
+}
+
+- (void)dealloc
+{
+ [MKAsyncResult releaseBlockArguments:_blockArguments];
+}
+
+@end
Oops, something went wrong.

0 comments on commit baffaa4

Please sign in to comment.